buffered-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.
- data/lib/buffered_logger.rb +37 -0
- data/lib/buffered_logger/errors.rb +6 -0
- data/lib/buffered_logger/log_device_proxy.rb +32 -0
- data/lib/buffered_logger/middleware.rb +11 -0
- data/lib/buffered_logger/rails.rb +21 -0
- data/lib/buffered_logger/version.rb +5 -0
- data/test/buffered_logger/log_device_proxy_test.rb +45 -0
- data/test/buffered_logger/middleware_test.rb +23 -0
- data/test/buffered_logger_test.rb +73 -0
- metadata +93 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
require "logger"
|
2
|
+
|
3
|
+
class BufferedLogger < Logger
|
4
|
+
require "buffered_logger/errors"
|
5
|
+
require "buffered_logger/log_device_proxy"
|
6
|
+
require "buffered_logger/middleware"
|
7
|
+
require "buffered_logger/version"
|
8
|
+
|
9
|
+
def initialize(*)
|
10
|
+
super
|
11
|
+
@logdev = LogDeviceProxy.new(@logdev)
|
12
|
+
end
|
13
|
+
|
14
|
+
def end
|
15
|
+
raise NotStartedError, "not started" unless started?
|
16
|
+
@logdev.end
|
17
|
+
end
|
18
|
+
|
19
|
+
def start(&block)
|
20
|
+
raise AlreadyStartedError, "already started" if started?
|
21
|
+
@logdev.start
|
22
|
+
|
23
|
+
if block_given?
|
24
|
+
begin
|
25
|
+
yield
|
26
|
+
ensure
|
27
|
+
self.end
|
28
|
+
end
|
29
|
+
else
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def started?
|
35
|
+
@logdev.started?
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class BufferedLogger
|
2
|
+
class LogDeviceProxy
|
3
|
+
def initialize(logdev)
|
4
|
+
@logdev = logdev
|
5
|
+
@buffers = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def close
|
9
|
+
@logdev.close
|
10
|
+
end
|
11
|
+
|
12
|
+
def end
|
13
|
+
@logdev.write(@buffers.delete(Thread.current).string)
|
14
|
+
end
|
15
|
+
|
16
|
+
def start
|
17
|
+
@buffers[Thread.current] = StringIO.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def started?
|
21
|
+
@buffers.key?(Thread.current)
|
22
|
+
end
|
23
|
+
|
24
|
+
def write(message)
|
25
|
+
if started?
|
26
|
+
@buffers[Thread.current].write(message)
|
27
|
+
else
|
28
|
+
@logdev.write(message)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "buffered_logger"
|
2
|
+
require "rails"
|
3
|
+
|
4
|
+
class BufferedLogger
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
initializer :buffered_logger, :before => :initialize_logger do |app|
|
7
|
+
if Rails::VERSION::STRING >= "3.1"
|
8
|
+
path = app.paths["log"].first
|
9
|
+
else
|
10
|
+
path = app.paths.log.to_a.first
|
11
|
+
end
|
12
|
+
|
13
|
+
file = File.open(path, "a")
|
14
|
+
file.binmode
|
15
|
+
file.sync = true
|
16
|
+
|
17
|
+
app.config.logger = BufferedLogger.new(file)
|
18
|
+
app.config.middleware.insert(0, BufferedLogger::Middleware, app.config.logger)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
describe BufferedLogger::LogDeviceProxy do
|
4
|
+
def setup
|
5
|
+
@logdev = mock()
|
6
|
+
@proxy = BufferedLogger::LogDeviceProxy.new(@logdev)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should call write" do
|
10
|
+
@logdev.expects(:write)
|
11
|
+
@proxy.write("message")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should call close on the logdev when close is called" do
|
15
|
+
@logdev.expects(:close)
|
16
|
+
@proxy.close
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should not call write on the logdev once started" do
|
20
|
+
@logdev.expects(:write).never
|
21
|
+
@proxy.start
|
22
|
+
@proxy.write("message")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should be started? once started" do
|
26
|
+
@proxy.start
|
27
|
+
assert @proxy.started?
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should call write once started and ended" do
|
31
|
+
@logdev.expects(:write)
|
32
|
+
@proxy.start
|
33
|
+
@proxy.write("message")
|
34
|
+
@proxy.end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should buffer all writes and write them once" do
|
38
|
+
@logdev.expects(:write).with("123")
|
39
|
+
@proxy.start
|
40
|
+
@proxy.write("1")
|
41
|
+
@proxy.write("2")
|
42
|
+
@proxy.write("3")
|
43
|
+
@proxy.end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
describe BufferedLogger::Middleware do
|
4
|
+
def setup
|
5
|
+
@app = mock()
|
6
|
+
@app.stubs(:call).returns([200, {}, []])
|
7
|
+
@logger = mock()
|
8
|
+
def @logger.start; yield; end
|
9
|
+
@middleware = BufferedLogger::Middleware.new(@app, @logger)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should call start" do
|
13
|
+
@logger.expects(:start).yields()
|
14
|
+
@middleware.call(nil)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "behaves as a proper rack middleware" do
|
18
|
+
result = [200, {}, []]
|
19
|
+
env = mock()
|
20
|
+
@app.expects(:call).with(env).returns(result)
|
21
|
+
@middleware.call(env).must_equal(result)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class MockLogDeviceProxy
|
4
|
+
def initialize
|
5
|
+
@started = false
|
6
|
+
end
|
7
|
+
|
8
|
+
def end
|
9
|
+
@started = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def start
|
13
|
+
@started = true
|
14
|
+
|
15
|
+
if block_given?
|
16
|
+
begin
|
17
|
+
yield
|
18
|
+
ensure
|
19
|
+
@started = false
|
20
|
+
end
|
21
|
+
else
|
22
|
+
true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def started?
|
27
|
+
@started
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe BufferedLogger do
|
32
|
+
describe "with MockLogDeviceProxy" do
|
33
|
+
def setup
|
34
|
+
@logdev = MockLogDeviceProxy.new
|
35
|
+
@logger = BufferedLogger.allocate
|
36
|
+
@logger.instance_variable_set(:@logdev, @logdev)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should raise an error if end is called while not started" do
|
40
|
+
-> { @logger.end }.must_raise(BufferedLogger::NotStartedError)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should raise an error if start is called while already started" do
|
44
|
+
@logger.start
|
45
|
+
-> { @logger.start }.must_raise(BufferedLogger::AlreadyStartedError)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "with mock" do
|
50
|
+
def setup
|
51
|
+
@logdev = mock()
|
52
|
+
@logger = BufferedLogger.allocate
|
53
|
+
@logger.instance_variable_set(:@logdev, @logdev)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should call end on logdev" do
|
57
|
+
@logdev.expects(:end)
|
58
|
+
@logdev.stubs(:started?).returns(true)
|
59
|
+
@logger.end
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should call start on logdev" do
|
63
|
+
@logdev.expects(:start)
|
64
|
+
@logdev.stubs(:started?).returns(false)
|
65
|
+
@logger.start
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should call started? on logdev" do
|
69
|
+
@logdev.expects(:started?)
|
70
|
+
@logger.started?
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: buffered-logger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Samuel Kadolph
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.1.5
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.1.5
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: mocha
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.12.1
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.12.1
|
46
|
+
description: buffered-logger is designed to be used in multithreaded rack servers
|
47
|
+
and includes a middleware to automatically capture and write the buffered log statements
|
48
|
+
during each request.
|
49
|
+
email:
|
50
|
+
- samuel@kadolph.com
|
51
|
+
executables: []
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- lib/buffered_logger/errors.rb
|
56
|
+
- lib/buffered_logger/log_device_proxy.rb
|
57
|
+
- lib/buffered_logger/middleware.rb
|
58
|
+
- lib/buffered_logger/rails.rb
|
59
|
+
- lib/buffered_logger/version.rb
|
60
|
+
- lib/buffered_logger.rb
|
61
|
+
- test/buffered_logger/log_device_proxy_test.rb
|
62
|
+
- test/buffered_logger/middleware_test.rb
|
63
|
+
- test/buffered_logger_test.rb
|
64
|
+
homepage: http://samuelkadolph.github.com/buffered-logger
|
65
|
+
licenses: []
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.9.2
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.8.24
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: buffered-logger is a concurrency safe logger. It buffers each logging statement
|
88
|
+
and writes to the log file all at once.
|
89
|
+
test_files:
|
90
|
+
- test/buffered_logger/log_device_proxy_test.rb
|
91
|
+
- test/buffered_logger/middleware_test.rb
|
92
|
+
- test/buffered_logger_test.rb
|
93
|
+
has_rdoc:
|