sweet-logger 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1f49f890b86cb4eca6168ff1e456b4d6f275f99e
4
+ data.tar.gz: 60687cabceb51fb3ec2bf0b94f57689c7959e3b4
5
+ SHA512:
6
+ metadata.gz: 6cc427f8f38c31b7d7e7912ee3ffa1468681f922a57011e76705041ee8262d5b32ebcda418e2fa3415bd3d17a068c476ed434ba8950f8ffa15dd6ee365c2e212
7
+ data.tar.gz: a2d6d082f475fb5acc6e9a0d469b1f92a043a4cf5af7922ed17799cc785a62ecc4edc41d6f7278cd8f6302ddd3bb7b7096104b2e4d8c27e253dcffcb4daaaf63
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sweet-logger.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Nikolay Nemshilov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,55 @@
1
+ # SweetLogger
2
+
3
+ This little gem solves two issues with rails `ActiveSuppot::Logger` when it's
4
+ running in a multi-threaded environment.
5
+
6
+ 1. It doesn't let log entries for concurrent requests overlap
7
+ 2. Adds a log silencer (for `/assets/`) that works correctly with multiple threads
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'sweet-logger'
15
+ ```
16
+
17
+ Enjoy!
18
+
19
+ ## Rack::Lock
20
+
21
+ By default in the `development` environment, Rails adds the `Rack::Lock` middleware
22
+ so that the rack server will process only one request at a time.
23
+
24
+ If you need to enable the real multi-threaded processing in the development
25
+ environment, add this to your `config/application.rb`
26
+
27
+ ```ruby
28
+ config.middleware.delete Rack::Lock
29
+ ```
30
+
31
+
32
+ ## Silencer
33
+
34
+ Our sweet logger comes with a silencer in case you need to remove some of the
35
+ entries from leaking into the logs. By default it silences the `/assets/` entries.
36
+ But if you need to silence anything else, add this to one of your rails initializers
37
+
38
+ ```ruby
39
+ SweetLogger.silence %w[
40
+ favicon.io
41
+ livereload.js
42
+ /something/else
43
+ ]
44
+ ```
45
+
46
+ __NOTE__: logger will check if the route _included_ in the current request's path.
47
+
48
+
49
+ ## Contributing
50
+
51
+ 1. Fork it ( https://github.com/MadRabbit/sweet-logger/fork )
52
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
53
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
54
+ 4. Push to the branch (`git push origin my-new-feature`)
55
+ 5. Create a new Pull Request
@@ -0,0 +1,4 @@
1
+ #
2
+ # Just a gem hook
3
+ #
4
+ require_relative "./sweet_logger"
@@ -0,0 +1,13 @@
1
+ module SweetLogger
2
+ extend self
3
+
4
+ def silence(routes)
5
+ Logstash.silence(routes)
6
+ end
7
+ end
8
+
9
+ require_relative "./sweet_logger/version"
10
+ require_relative "./sweet_logger/middleware"
11
+ require_relative "./sweet_logger/logstash"
12
+ require_relative "./sweet_logger/hackhack"
13
+ require_relative "./sweet_logger/railtie"
@@ -0,0 +1,19 @@
1
+ #
2
+ # Hack hack hack
3
+ #
4
+ # This makes the logger to write into a current thread
5
+ # stash while it's blocked by other threads.
6
+ #
7
+ ActiveSupport::Logger.class_eval do
8
+
9
+ alias :add_before_sweet_logger :add
10
+
11
+ def add(*args, &block)
12
+ if Thread.current[:sweet_logger_stash]
13
+ Thread.current[:sweet_logger_stash].push [self, args, block]
14
+ else
15
+ add_before_sweet_logger *args, &block
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,65 @@
1
+ #
2
+ # A little queue to stash logs while the STDOUT it blocked
3
+ # by another threads
4
+ #
5
+ require "thread"
6
+
7
+ module SweetLogger
8
+ class Logstash
9
+ MUTEX = Mutex.new
10
+
11
+ def self.silence(routes)
12
+ @silencer_re = /#{ routes.map { |e| Regexp.escape(e) }.join("|") }/
13
+ end
14
+
15
+ def self.silencer_re
16
+ @silencer_re
17
+ end
18
+
19
+ def wrap(path, &block)
20
+ silenced = shall_be_silenced?(path)
21
+ we_started_this = ! Thread.main[:sweet_logger_stash]
22
+
23
+ MUTEX.synchronize do
24
+ if we_started_this && ! silenced
25
+ Thread.main[:sweet_logger_stash] = []
26
+ else
27
+ Thread.current[:sweet_logger_stash] = []
28
+ end
29
+ end
30
+
31
+ yield
32
+
33
+ ensure
34
+ MUTEX.synchronize do
35
+ if silenced || ! Thread.current[:sweet_logger_stash]
36
+ Thread.current[:sweet_logger_stash] = []
37
+ end
38
+
39
+ if Thread.main[:sweet_logger_stash]
40
+ if we_started_this
41
+ flush Thread.main[:sweet_logger_stash]
42
+ Thread.main[:sweet_logger_stash] = nil
43
+ else
44
+ Thread.main[:sweet_logger_stash] += Thread.current[:sweet_logger_stash]
45
+ end
46
+
47
+ elsif
48
+ flush Thread.current[:sweet_logger_stash]
49
+ end
50
+
51
+ Thread.current[:sweet_logger_stash] = nil
52
+ end
53
+ end
54
+
55
+ def flush(entries)
56
+ entries.each do |logger, args, block|
57
+ logger.add_before_sweet_logger *args, &block
58
+ end
59
+ end
60
+
61
+ def shall_be_silenced?(path)
62
+ path =~ self.class.silencer_re
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,20 @@
1
+ #
2
+ # The rack middleware patch for `Rails::Rack::Logger`
3
+ #
4
+ module SweetLogger
5
+ class Middleware < Rails::Rack::Logger
6
+
7
+ def initialize(*args, &block)
8
+ super
9
+
10
+ @logstash = SweetLogger::Logstash.new
11
+ end
12
+
13
+ def call(env)
14
+ @logstash.wrap env['PATH_INFO'] do
15
+ super env
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module SweetLogger
2
+ class Railtie < Rails::Railtie
3
+ railtie_name :sweet_logger
4
+
5
+ config.before_initialize do |app|
6
+ Rails.configuration.middleware.swap(
7
+ Rails::Rack::Logger, SweetLogger::Middleware
8
+ )
9
+
10
+ SweetLogger.silence %w{ /assets/ }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module SweetLogger
2
+
3
+ VERSION = "1.0.0"
4
+
5
+ end
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+ require_relative './lib/sweet_logger/version'
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "sweet-logger"
6
+ spec.version = SweetLogger::VERSION
7
+ spec.authors = ["Nikolay Nemshilov"]
8
+ spec.email = ["nemshilov@gmail.com"]
9
+ spec.summary = %q{Betterer Rails logger that handles multi-threading}
10
+ spec.description = %q{Betterer Rails logger that handles multi-threading well}
11
+ spec.homepage = "https://github.com/MadRabbit/sweet-logger"
12
+ spec.license = "MIT"
13
+
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sweet-logger
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Nikolay Nemshilov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-31 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Betterer Rails logger that handles multi-threading well
14
+ email:
15
+ - nemshilov@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - Gemfile
22
+ - LICENSE.txt
23
+ - README.md
24
+ - lib/sweet-logger.rb
25
+ - lib/sweet_logger.rb
26
+ - lib/sweet_logger/hackhack.rb
27
+ - lib/sweet_logger/logstash.rb
28
+ - lib/sweet_logger/middleware.rb
29
+ - lib/sweet_logger/railtie.rb
30
+ - lib/sweet_logger/version.rb
31
+ - sweet-logger.gemspec
32
+ homepage: https://github.com/MadRabbit/sweet-logger
33
+ licenses:
34
+ - MIT
35
+ metadata: {}
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubyforge_project:
52
+ rubygems_version: 2.2.2
53
+ signing_key:
54
+ specification_version: 4
55
+ summary: Betterer Rails logger that handles multi-threading
56
+ test_files: []