buffering_logger 2.0.4 → 3.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2ec7a39f0dd57757106b2407dc76ee3a51f2efc4
4
- data.tar.gz: a416626987ce0e312e1c4cd10280f280fbdc10e1
2
+ SHA256:
3
+ metadata.gz: e76718294cf2d45e7d614aa99fc05574bcc21d7b1484ee8cdbcfcb9a1ee8be63
4
+ data.tar.gz: 936e56c62d2d5d666ec336cb5037ee96735257a16d05d35ae181e21c3141f8c5
5
5
  SHA512:
6
- metadata.gz: c6c31d2d11a5144ab790dd7eb4a5b71d61a8deb8e785e6e6729fbaa636bce52e1d6f6469096e840790294f05c6a563c9aa39d1dc1197b487624cadf15eaaa4dd
7
- data.tar.gz: 5783ab6b1107dd7f92f9335a314eb835a49becf524d558b2fe90a146bb140f77ca946d9d48314d0a9391f579e4d00a4c3b8ba963a36920ad0f1511c7df0f291e
6
+ metadata.gz: b247ee48fe4c6885ac64a8d24bccb73acda910782cbebcb5256528b35ad39f3a83c62db20dd84a76374136d9c84c861e18945f46cf6f515e107116fb18c25994
7
+ data.tar.gz: 3de0d002b76ea6bf7c6e48c5717364d76854a3f074932dcc76971548348a1f149468faf594de73c22813f9bfdd282030b113ba4e5816b75f42f5227daf4fff5f
@@ -1,6 +1,6 @@
1
+ module BufferingLogger
2
+ end
3
+
1
4
  require 'buffering_logger/logger'
2
5
  require 'buffering_logger/buffer'
3
6
  require 'buffering_logger/rack_buffer'
4
-
5
- module BufferingLogger
6
- end
@@ -1,66 +1,77 @@
1
1
  # Buffer is used to wrap the logger's logdev to accomplish buffering.
2
2
  # For the purposes of the Logger class a LogDevice only needs to implement
3
3
  # #write and #close. We add #buffered as well.
4
- module BufferingLogger
5
- class Buffer
6
- def initialize(logdev)
7
- @logdev = logdev
8
- @mutex = Mutex.new
9
- end
4
+ class BufferingLogger::Buffer
10
5
 
11
- # buffers during the block and then flushes.
12
- # returns the value of the block.
13
- def buffered(transform: nil)
14
- @buffering = true
15
- yield
16
- ensure
17
- @buffering = false
18
- flush(transform: transform)
19
- end
6
+ def initialize(logdev)
7
+ @logdev = logdev
8
+ @mutex = Mutex.new
9
+ end
20
10
 
21
- def write(msg)
22
- if @buffering
23
- (buffer || create_buffer).write(msg)
24
- else
25
- @logdev.write(msg)
26
- end
27
- end
11
+ # buffers during the block and then flushes.
12
+ # returns the value of the block.
13
+ def buffered(transform: nil)
14
+ self.buffering = true
15
+ yield
16
+ ensure
17
+ self.buffering = false
18
+ flush(transform: transform)
19
+ end
28
20
 
29
- def close
30
- @mutex.synchronize do
31
- @logdev.close
32
- end
21
+ def write(msg)
22
+ if buffering
23
+ buffer.write(msg)
24
+ else
25
+ logdev_write(msg)
33
26
  end
27
+ end
34
28
 
35
- private
29
+ def close
30
+ logdev_close
31
+ end
36
32
 
37
- def flush(transform: nil)
38
- if buffer && buffer.length > 0
39
- @mutex.synchronize do
40
- msg = buffer.string
41
- msg = transform.call(msg) if transform
42
- @logdev.write(msg)
43
- end
44
- end
45
- ensure
46
- unset_buffer if buffer
47
- end
33
+ private
48
34
 
49
- def buffer
50
- Thread.current[buffer_id]
35
+ def flush(transform: nil)
36
+ if buffer && buffer.length > 0
37
+ msg = buffer.string
38
+ msg = transform.call(msg) if transform
39
+ logdev_write(msg)
51
40
  end
41
+ ensure
42
+ buffer.reopen('')
43
+ end
52
44
 
53
- def create_buffer
54
- Thread.current[buffer_id] = StringIO.new
45
+ def logdev_write(msg)
46
+ @mutex.synchronize do
47
+ @logdev.write(msg)
55
48
  end
49
+ end
56
50
 
57
- def unset_buffer
58
- Thread.current[buffer_id] = nil
51
+ def logdev_close
52
+ @mutex.synchronize do
53
+ @logdev.close
59
54
  end
55
+ end
60
56
 
61
- def buffer_id
62
- "buffering_logger_#{object_id}_buffer"
63
- end
57
+ def buffer
58
+ Thread.current[buffer_id] ||= StringIO.new
59
+ end
60
+
61
+ def buffer_id
62
+ "buffering_logger_#{object_id}_buffer"
63
+ end
64
64
 
65
+ def buffering
66
+ Thread.current[buffering_id]
65
67
  end
68
+
69
+ def buffering=(val)
70
+ Thread.current[buffering_id] = val
71
+ end
72
+
73
+ def buffering_id
74
+ "buffering_logger_#{object_id}_is_buffering"
75
+ end
76
+
66
77
  end
@@ -4,35 +4,40 @@ require 'logger'
4
4
  # logger.buffered { logger.info 'hi'; logger.info 'goodbye' }
5
5
  # Buffering is implemented by wrapping the logger @logdev object with a Buffer.
6
6
 
7
- module BufferingLogger
8
- class Logger < ::Logger
7
+ class BufferingLogger::Logger < ::Logger
8
+ include ActiveSupport::LoggerSilence if defined?(ActiveSupport::LoggerSilence)
9
9
 
10
- attr_reader :raw_log_device
10
+ attr_accessor :default_transform
11
+ attr_reader :raw_log_device
11
12
 
12
- def initialize(logdev, shift_age: 0, shift_size: 1048576)
13
- @shift_age, @shift_size = shift_age, shift_size
14
- @opened_logdev = false
15
- super(nil, shift_age, shift_size)
16
- self.logdev = logdev
17
- end
13
+ def initialize(logdev, shift_age: 0, shift_size: 1048576)
14
+ @shift_age, @shift_size = shift_age, shift_size
15
+ @opened_logdev = false
16
+ super(nil, shift_age, shift_size)
17
+ self.logdev = logdev
18
+ end
18
19
 
19
- # allow changing the log destination. e.g.: in Unicorn during after_fork to
20
- # set a separate log path for each worker.
21
- def logdev=(logdev)
22
- @logdev.close if @logdev && @opened_logdev
20
+ # allow changing the log destination. e.g.: in Unicorn during after_fork to
21
+ # set a separate log path for each worker.
22
+ def logdev=(logdev)
23
+ @logdev.close if @logdev && @opened_logdev
23
24
 
24
- @raw_log_device = LogDevice.new(logdev, shift_age: @shift_age, shift_size: @shift_size)
25
+ @raw_log_device = LogDevice.new(
26
+ logdev,
27
+ shift_age: @shift_age,
28
+ shift_size: @shift_size,
29
+ )
25
30
 
26
- # if we opened the logdev then we should close it when we're done
27
- @opened_logdev = @raw_log_device.dev != logdev
31
+ # if we opened the logdev then we should close it when we're done
32
+ @opened_logdev = @raw_log_device.dev != logdev
28
33
 
29
- @logdev = Buffer.new(@raw_log_device)
30
- end
34
+ @logdev = BufferingLogger::Buffer.new(@raw_log_device)
35
+ end
31
36
 
32
- def buffered(transform: nil)
33
- @logdev.buffered(transform: transform) do
34
- yield
35
- end
37
+ def buffered(transform: default_transform)
38
+ @logdev.buffered(transform: transform) do
39
+ yield
36
40
  end
37
41
  end
42
+
38
43
  end
@@ -1,11 +1,11 @@
1
- module BufferingLogger
2
- class RackBuffer
3
- def initialize(app, logger, transform: nil)
4
- @app, @logger, @transform = app, logger, transform
5
- end
1
+ class BufferingLogger::RackBuffer
6
2
 
7
- def call(env)
8
- @logger.buffered(transform: @transform) { @app.call(env) }
9
- end
3
+ def initialize(app, logger, transform: nil)
4
+ @app, @logger, @transform = app, logger, transform
10
5
  end
6
+
7
+ def call(env)
8
+ @logger.buffered(transform: @transform) { @app.call(env) }
9
+ end
10
+
11
11
  end
@@ -0,0 +1,20 @@
1
+ #
2
+ # With buffered logs we don't need to log the request_id on every line.
3
+ # Instead we log it once near the start of the request.
4
+ # We do this via a Rack middleware to ensure that it's logged even for things
5
+ # like a `RoutingError` or other exceptional cases.
6
+ #
7
+ class BufferingLogger::RailsRackLogRequestId
8
+
9
+ def initialize(app)
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ request = ActionDispatch::Request.new(env)
15
+ Rails.logger.info("request_id=#{request.request_id.inspect}")
16
+
17
+ @app.call(env)
18
+ end
19
+
20
+ end
@@ -1,37 +1,66 @@
1
1
  require 'buffering_logger'
2
2
  require 'buffering_logger/rack_buffer'
3
+ require 'buffering_logger/rails_rack_log_request_id'
3
4
  require 'rails/railtie'
4
5
 
5
- module BufferingLogger
6
- class Railtie < Rails::Railtie
7
- def self.install(transform: nil, device: nil, sync: true)
8
- initializer :buffering_logger, :before => :initialize_logger do |app|
9
- device ||= begin
10
- # Does mostly the same things that Rails does. See http://git.io/2v9FxQ
6
+ class BufferingLogger::Railtie < Rails::Railtie
11
7
 
12
- path = app.paths["log"].first
8
+ def self.install(
9
+ transform: nil, device: nil, sync: true, request_id: true,
10
+ warn_log_tags: true, simple_formatter: true
11
+ )
12
+ initializer :buffering_logger, :before => :initialize_logger do |app|
13
+ device ||= begin
14
+ # Does mostly the same things that Rails does. See http://git.io/2v9FxQ
13
15
 
14
- unless File.exist? File.dirname path
15
- FileUtils.mkdir_p File.dirname path
16
- end
16
+ path = app.paths["log"].first
17
17
 
18
- file = File.open(path, 'a')
19
- file.binmode
20
- file
18
+ unless File.exist? File.dirname path
19
+ FileUtils.mkdir_p File.dirname path
21
20
  end
22
21
 
23
- device.sync = true if sync && device.respond_to?(:sync=)
22
+ file = File.open(path, 'a')
23
+ file.binmode
24
+ file
25
+ end
26
+
27
+ device.sync = true if sync && device.respond_to?(:sync=)
28
+
29
+ logger = BufferingLogger::Logger.new(device)
30
+ logger.formatter = if simple_formatter
31
+ ActiveSupport::Logger::SimpleFormatter.new
32
+ else
33
+ app.config.log_formatter
34
+ end
35
+ logger = ActiveSupport::TaggedLogging.new(logger)
24
36
 
25
- logger = BufferingLogger::Logger.new(device)
26
- logger.formatter = app.config.log_formatter
27
- logger = ActiveSupport::TaggedLogging.new(logger)
37
+ app.config.logger = logger
28
38
 
29
- app.config.logger = logger
39
+ # We insert this at the very beginning so that all logs, even from other
40
+ # middleware, get buffered together.
41
+ app.config.middleware.insert(
42
+ 0,
43
+ BufferingLogger::RackBuffer,
44
+ logger,
45
+ transform: transform,
46
+ )
30
47
 
31
- # Inserts at the very beginning so that all logs, even from other
32
- # middleware, get buffered together.
33
- app.config.middleware.insert(0, BufferingLogger::RackBuffer, logger, transform: transform)
48
+ # Log the request_id
49
+ if request_id
50
+ app.config.middleware.insert_after(
51
+ Rails::Rack::Logger,
52
+ BufferingLogger::RailsRackLogRequestId,
53
+ )
54
+ end
55
+
56
+ if warn_log_tags && app.config.log_tags.present?
57
+ puts(<<~TEXT.squish)
58
+ NOTE: You're using `Rails.application.config.log_tags` with
59
+ BufferingLogger. We recommend disabling these when using
60
+ BufferingLogger. See the README for more info.
61
+ TEXT
34
62
  end
35
63
  end
36
64
  end
65
+
37
66
  end
@@ -1,28 +1,28 @@
1
- module BufferingLogger
2
- # This transforms a multiline log into a single line log by replacing newlines
3
- # with a special string (a single space by default).
4
- #
5
- # This is useful for platforms like Heroku where multiline Rails request logs
6
- # of one process are interwoven with the request logs of other processes and
7
- # other log sources (like the Heroku router).
8
- #
9
- # If you want to convert newlines into a special string so that you can later
10
- # turn them back into newlines (e.g. in Splunk using a
11
- # [SEDCMD](http://docs.splunk.com/Documentation/Splunk/latest/admin/Propsconf))
12
- # then you can supply a `replacement` argument.
13
- class SingleLineTransform
14
- REPLACEMENT = ' '.freeze
15
- NEWLINE = /\r?\n/.freeze
1
+ # This transforms a multiline log into a single line log by replacing newlines
2
+ # with a special string (a single space by default).
3
+ #
4
+ # This is useful for platforms like Heroku where multiline Rails request logs
5
+ # of one process are interwoven with the request logs of other processes and
6
+ # other log sources (like the Heroku router).
7
+ #
8
+ # If you want to convert newlines into a special string so that you can later
9
+ # turn them back into newlines (e.g. in Splunk using a
10
+ # [SEDCMD](http://docs.splunk.com/Documentation/Splunk/latest/admin/Propsconf))
11
+ # then you can supply a `replacement` argument.
12
+ class BufferingLogger::SingleLineTransform
16
13
 
17
- def initialize(replacement: REPLACEMENT)
18
- @replacement = replacement
19
- end
14
+ REPLACEMENT = ' '.freeze
15
+ NEWLINE = /\r?\n/.freeze
20
16
 
21
- def call(msg)
22
- msg = msg.dup
23
- msg.strip!
24
- msg.gsub!(NEWLINE, @replacement)
25
- msg << "\n"
26
- end
17
+ def initialize(replacement: REPLACEMENT)
18
+ @replacement = replacement
27
19
  end
20
+
21
+ def call(msg)
22
+ msg = msg.dup
23
+ msg.strip!
24
+ msg.gsub!(NEWLINE, @replacement)
25
+ msg << "\n"
26
+ end
27
+
28
28
  end
@@ -0,0 +1,3 @@
1
+ module BufferingLogger
2
+ VERSION = '3.1.1'
3
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: buffering_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 3.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Brough
@@ -22,8 +22,10 @@ files:
22
22
  - lib/buffering_logger/logger.rb
23
23
  - lib/buffering_logger/rack_buffer.rb
24
24
  - lib/buffering_logger/rails.rb
25
+ - lib/buffering_logger/rails_rack_log_request_id.rb
25
26
  - lib/buffering_logger/railtie.rb
26
27
  - lib/buffering_logger/single_line_transform.rb
28
+ - lib/buffering_logger/version.rb
27
29
  homepage: https://github.com/jordan-brough/buffering_logger
28
30
  licenses:
29
31
  - MIT
@@ -43,8 +45,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
43
45
  - !ruby/object:Gem::Version
44
46
  version: '0'
45
47
  requirements: []
46
- rubyforge_project:
47
- rubygems_version: 2.4.5.1
48
+ rubygems_version: 3.1.2
48
49
  signing_key:
49
50
  specification_version: 4
50
51
  summary: BufferingLogger is a logger that buffers log entries and then writes them