buffering_logger 2.0.5 → 2.0.6
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 +5 -5
- data/lib/buffering_logger.rb +3 -3
- data/lib/buffering_logger/buffer.rb +46 -47
- data/lib/buffering_logger/logger.rb +26 -23
- data/lib/buffering_logger/rack_buffer.rb +8 -8
- data/lib/buffering_logger/railtie.rb +28 -25
- data/lib/buffering_logger/single_line_transform.rb +24 -24
- metadata +2 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5564a270f8f8b903262a250478cfca69a7854b7943aed6e4353b7589c5bf4a3a
|
4
|
+
data.tar.gz: 74b1b8ac3d1d3a321c8064427966b47253c98968ba69f12fdd6e2b741989e924
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29ed01af72ea3b3bc85446c3de71a48f2a48eed7716ff1a23c183fb8d5ba9ac9903fe969a04d8c337877562a9a0070ed1c245c27993228d05d9ae95cd876bea5
|
7
|
+
data.tar.gz: ef3dae1d2d911160ba538a34b03afff8a1101dbdfde68f02530547a09d4290742caa60b7b9bac874ad3c0163c830d21df1cf595ed8a0c4ee1e44c8636d4b1c16
|
data/lib/buffering_logger.rb
CHANGED
@@ -1,66 +1,65 @@
|
|
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
|
-
|
5
|
-
class Buffer
|
6
|
-
def initialize(logdev)
|
7
|
-
@logdev = logdev
|
8
|
-
@mutex = Mutex.new
|
9
|
-
end
|
4
|
+
class BufferingLogger::Buffer
|
10
5
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
28
20
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
29
|
+
def close
|
30
|
+
logdev_close
|
31
|
+
end
|
36
32
|
|
37
|
-
|
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
|
-
|
50
|
-
|
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
|
-
|
54
|
-
|
45
|
+
def logdev_write(msg)
|
46
|
+
@mutex.synchronize do
|
47
|
+
@logdev.write(msg)
|
55
48
|
end
|
49
|
+
end
|
56
50
|
|
57
|
-
|
58
|
-
|
51
|
+
def logdev_close
|
52
|
+
@mutex.synchronize do
|
53
|
+
@logdev.close
|
59
54
|
end
|
55
|
+
end
|
60
56
|
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
def buffer
|
58
|
+
Thread.current[buffer_id] ||= StringIO.new
|
59
|
+
end
|
64
60
|
|
61
|
+
def buffer_id
|
62
|
+
"buffering_logger_#{object_id}_buffer"
|
65
63
|
end
|
64
|
+
|
66
65
|
end
|
@@ -4,36 +4,39 @@ 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
|
-
|
8
|
-
class Logger < ::Logger
|
7
|
+
class BufferingLogger::Logger < ::Logger
|
9
8
|
|
10
|
-
|
11
|
-
|
9
|
+
attr_accessor :default_transform
|
10
|
+
attr_reader :raw_log_device
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
24
23
|
|
25
|
-
|
24
|
+
@raw_log_device = LogDevice.new(
|
25
|
+
logdev,
|
26
|
+
shift_age: @shift_age,
|
27
|
+
shift_size: @shift_size,
|
28
|
+
)
|
26
29
|
|
27
|
-
|
28
|
-
|
30
|
+
# if we opened the logdev then we should close it when we're done
|
31
|
+
@opened_logdev = @raw_log_device.dev != logdev
|
29
32
|
|
30
|
-
|
31
|
-
|
33
|
+
@logdev = BufferingLogger::Buffer.new(@raw_log_device)
|
34
|
+
end
|
32
35
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
36
|
+
def buffered(transform: default_transform)
|
37
|
+
@logdev.buffered(transform: transform) do
|
38
|
+
yield
|
37
39
|
end
|
38
40
|
end
|
41
|
+
|
39
42
|
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
|
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
|
-
|
8
|
-
|
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
|
@@ -2,36 +2,39 @@ require 'buffering_logger'
|
|
2
2
|
require 'buffering_logger/rack_buffer'
|
3
3
|
require 'rails/railtie'
|
4
4
|
|
5
|
-
|
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
|
11
|
-
|
12
|
-
path = app.paths["log"].first
|
13
|
-
|
14
|
-
unless File.exist? File.dirname path
|
15
|
-
FileUtils.mkdir_p File.dirname path
|
16
|
-
end
|
17
|
-
|
18
|
-
file = File.open(path, 'a')
|
19
|
-
file.binmode
|
20
|
-
file
|
21
|
-
end
|
5
|
+
class BufferingLogger::Railtie < Rails::Railtie
|
22
6
|
|
23
|
-
|
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
|
24
11
|
|
25
|
-
|
26
|
-
logger.formatter = app.config.log_formatter
|
27
|
-
logger = ActiveSupport::TaggedLogging.new(logger)
|
12
|
+
path = app.paths["log"].first
|
28
13
|
|
29
|
-
|
14
|
+
unless File.exist? File.dirname path
|
15
|
+
FileUtils.mkdir_p File.dirname path
|
16
|
+
end
|
30
17
|
|
31
|
-
|
32
|
-
|
33
|
-
|
18
|
+
file = File.open(path, 'a')
|
19
|
+
file.binmode
|
20
|
+
file
|
34
21
|
end
|
22
|
+
|
23
|
+
device.sync = true if sync && device.respond_to?(:sync=)
|
24
|
+
|
25
|
+
logger = BufferingLogger::Logger.new(device)
|
26
|
+
logger.formatter = app.config.log_formatter
|
27
|
+
logger = ActiveSupport::TaggedLogging.new(logger)
|
28
|
+
|
29
|
+
app.config.logger = logger
|
30
|
+
|
31
|
+
# Inserts at the very beginning so that all logs, even from other
|
32
|
+
# middleware, get buffered together.
|
33
|
+
app.config.middleware.insert(
|
34
|
+
0,
|
35
|
+
BufferingLogger::RackBuffer, logger, transform: transform,
|
36
|
+
)
|
35
37
|
end
|
36
38
|
end
|
39
|
+
|
37
40
|
end
|
@@ -1,28 +1,28 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
18
|
-
|
19
|
-
end
|
14
|
+
REPLACEMENT = ' '.freeze
|
15
|
+
NEWLINE = /\r?\n/.freeze
|
20
16
|
|
21
|
-
|
22
|
-
|
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
|
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
|
+
version: 2.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Brough
|
@@ -43,8 +43,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
43
43
|
- !ruby/object:Gem::Version
|
44
44
|
version: '0'
|
45
45
|
requirements: []
|
46
|
-
|
47
|
-
rubygems_version: 2.4.5.1
|
46
|
+
rubygems_version: 3.0.3
|
48
47
|
signing_key:
|
49
48
|
specification_version: 4
|
50
49
|
summary: BufferingLogger is a logger that buffers log entries and then writes them
|