buffering_logger 1.0.1 → 2.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.
- checksums.yaml +4 -4
- data/lib/buffering_logger/buffer.rb +42 -15
- data/lib/buffering_logger/logger.rb +2 -2
- data/lib/buffering_logger/rack_buffer.rb +3 -3
- data/lib/buffering_logger/rails.rb +9 -28
- data/lib/buffering_logger/railtie.rb +37 -0
- data/lib/buffering_logger/single_line_transform.rb +28 -0
- data/lib/buffering_logger.rb +3 -0
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 080b9c7259c8c93409f2e8a25309fd6eabbd14a1
|
|
4
|
+
data.tar.gz: 1e9ad1c09ee4f5762c8f03b4501f9625b97f2dc6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0875c11661eabb07e1d408617095bd47c68efcf929d50ef8aca051e4d3d3a13ac64b0c204e585c980d9369074aa5586443a80ed1fd12abfb508e3abe8239238e
|
|
7
|
+
data.tar.gz: 2a91b33942353957749ad3ed0ffd2a9237c500c1da360a7a8f7e3711e6f6859a1d78cdb43b438a6176e8df6b880ba498ac283938c083ff0ab1c25d335163c1b0
|
|
@@ -1,39 +1,66 @@
|
|
|
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
|
-
# #write and #close. We add #
|
|
3
|
+
# #write and #close. We add #buffered as well.
|
|
4
4
|
module BufferingLogger
|
|
5
5
|
class Buffer
|
|
6
6
|
def initialize(logdev)
|
|
7
7
|
@logdev = logdev
|
|
8
|
-
@
|
|
8
|
+
@mutex = Mutex.new
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
# buffers during the block and then flushes.
|
|
12
12
|
# returns the value of the block.
|
|
13
|
-
def buffered
|
|
14
|
-
buffering_was = @buffering # in case we're already buffering
|
|
13
|
+
def buffered(transform: nil)
|
|
15
14
|
@buffering = true
|
|
16
15
|
yield
|
|
17
16
|
ensure
|
|
18
|
-
@buffering =
|
|
19
|
-
flush
|
|
17
|
+
@buffering = false
|
|
18
|
+
flush(transform: transform)
|
|
20
19
|
end
|
|
21
20
|
|
|
22
21
|
def write(msg)
|
|
23
|
-
@
|
|
24
|
-
|
|
22
|
+
if @buffering
|
|
23
|
+
(buffer || create_buffer).write(msg)
|
|
24
|
+
else
|
|
25
|
+
@logdev.write(msg)
|
|
26
|
+
end
|
|
25
27
|
end
|
|
26
28
|
|
|
27
|
-
def
|
|
28
|
-
|
|
29
|
-
@logdev.
|
|
30
|
-
@buffer = StringIO.new
|
|
29
|
+
def close
|
|
30
|
+
@mutex.synchronize do
|
|
31
|
+
@logdev.close
|
|
31
32
|
end
|
|
32
33
|
end
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
private
|
|
36
|
+
|
|
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
|
|
48
|
+
|
|
49
|
+
def buffer
|
|
50
|
+
Thread.current[buffer_id]
|
|
37
51
|
end
|
|
52
|
+
|
|
53
|
+
def create_buffer
|
|
54
|
+
Thread.current[buffer_id] = StringIO.new
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def unset_buffer
|
|
58
|
+
Thread.current[buffer_id] = nil
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def buffer_id
|
|
62
|
+
"buffering_logger_#{object_id}_buffer"
|
|
63
|
+
end
|
|
64
|
+
|
|
38
65
|
end
|
|
39
66
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
module BufferingLogger
|
|
2
2
|
class RackBuffer
|
|
3
|
-
def initialize(app, logger)
|
|
4
|
-
@app, @logger = app, logger
|
|
3
|
+
def initialize(app, logger, transform: transform)
|
|
4
|
+
@app, @logger, @transform = app, logger, transform
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
def call(env)
|
|
8
|
-
@logger.buffered { @app.call(env) }
|
|
8
|
+
@logger.buffered(transform: @transform) { @app.call(env) }
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -1,30 +1,11 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'rails/railtie'
|
|
2
|
+
require 'active_support/deprecation'
|
|
3
|
+
require 'active_support/core_ext/string/filters'
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
ActiveSupport::Deprecation.warn(<<-WARN.squish)
|
|
6
|
+
"buffering_logger/rails" is deprecated.
|
|
7
|
+
Please use "buffering_logger/railtie" instead and call BufferingLogger::Railtie.install explicitly.
|
|
8
|
+
WARN
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
path = app.paths["log"].first
|
|
10
|
-
|
|
11
|
-
unless File.exist? File.dirname path
|
|
12
|
-
FileUtils.mkdir_p File.dirname path
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
file = File.open(path, 'a')
|
|
16
|
-
file.binmode
|
|
17
|
-
file.sync = true # always flush to disk when write happen
|
|
18
|
-
|
|
19
|
-
logger = BufferingLogger::Logger.new(file)
|
|
20
|
-
logger.formatter = app.config.log_formatter
|
|
21
|
-
logger = ActiveSupport::TaggedLogging.new(logger)
|
|
22
|
-
|
|
23
|
-
app.config.logger = logger
|
|
24
|
-
|
|
25
|
-
# Inserts at the very beginning so that all logs, even from other
|
|
26
|
-
# middleware, get buffered together.
|
|
27
|
-
app.config.middleware.insert(0, BufferingLogger::RackBuffer, logger)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
10
|
+
require 'buffering_logger/railtie'
|
|
11
|
+
BufferingLogger::Railtie.install
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'buffering_logger'
|
|
2
|
+
require 'buffering_logger/rack_buffer'
|
|
3
|
+
require 'rails/railtie'
|
|
4
|
+
|
|
5
|
+
module BufferingLogger
|
|
6
|
+
class Railtie < Rails::Railtie
|
|
7
|
+
def self.install(transform: transform, 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
|
|
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(0, BufferingLogger::RackBuffer, logger, transform: transform)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +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
|
|
16
|
+
|
|
17
|
+
def initialize(replacement: REPLACEMENT)
|
|
18
|
+
@replacement = replacement
|
|
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
|
+
end
|
|
28
|
+
end
|
data/lib/buffering_logger.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: buffering_logger
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jordan Brough
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2015-11-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Buffering makes it possible for log tools like Splunk or Logstash to
|
|
14
14
|
more reliably group multiline logs as single events.
|
|
@@ -22,6 +22,8 @@ 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/railtie.rb
|
|
26
|
+
- lib/buffering_logger/single_line_transform.rb
|
|
25
27
|
homepage: https://github.com/jordan-brough/buffering_logger
|
|
26
28
|
licenses:
|
|
27
29
|
- MIT
|
|
@@ -34,7 +36,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
34
36
|
requirements:
|
|
35
37
|
- - ">="
|
|
36
38
|
- !ruby/object:Gem::Version
|
|
37
|
-
version:
|
|
39
|
+
version: 2.1.0
|
|
38
40
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
39
41
|
requirements:
|
|
40
42
|
- - ">="
|
|
@@ -42,7 +44,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
42
44
|
version: '0'
|
|
43
45
|
requirements: []
|
|
44
46
|
rubyforge_project:
|
|
45
|
-
rubygems_version: 2.2.
|
|
47
|
+
rubygems_version: 2.2.5
|
|
46
48
|
signing_key:
|
|
47
49
|
specification_version: 4
|
|
48
50
|
summary: BufferingLogger is a logger that buffers log entries and then writes them
|