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.
@@ -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,6 @@
1
+ class BufferedLogger
2
+ class AlreadyStartedError < StandardError
3
+ end
4
+ class NotStartedError < StandardError
5
+ end
6
+ 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,11 @@
1
+ class BufferedLogger
2
+ class Middleware
3
+ def initialize(app, logger)
4
+ @app, @logger = app, logger
5
+ end
6
+
7
+ def call(env)
8
+ @logger.start { @app.call(env) }
9
+ end
10
+ end
11
+ 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,5 @@
1
+ require "logger"
2
+
3
+ class BufferedLogger < Logger
4
+ VERSION = "1.0.0"
5
+ 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: