lumberjack_aziz_light 1.0.5

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.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/MIT_LICENSE +20 -0
  3. data/README.rdoc +100 -0
  4. data/Rakefile +40 -0
  5. data/VERSION +1 -0
  6. data/lib/lumberjack/device/date_rolling_log_file.rb +58 -0
  7. data/lib/lumberjack/device/log_file.rb +18 -0
  8. data/lib/lumberjack/device/null.rb +15 -0
  9. data/lib/lumberjack/device/rolling_log_file.rb +110 -0
  10. data/lib/lumberjack/device/size_rolling_log_file.rb +60 -0
  11. data/lib/lumberjack/device/writer.rb +129 -0
  12. data/lib/lumberjack/device.rb +26 -0
  13. data/lib/lumberjack/formatter/exception_formatter.rb +12 -0
  14. data/lib/lumberjack/formatter/inspect_formatter.rb +10 -0
  15. data/lib/lumberjack/formatter/pretty_print_formatter.rb +23 -0
  16. data/lib/lumberjack/formatter/string_formatter.rb +10 -0
  17. data/lib/lumberjack/formatter.rb +76 -0
  18. data/lib/lumberjack/log_entry.rb +36 -0
  19. data/lib/lumberjack/logger.rb +302 -0
  20. data/lib/lumberjack/rack/unit_of_work.rb +15 -0
  21. data/lib/lumberjack/rack.rb +5 -0
  22. data/lib/lumberjack/severity.rb +23 -0
  23. data/lib/lumberjack/template.rb +71 -0
  24. data/lib/lumberjack.rb +42 -0
  25. data/spec/device/date_rolling_log_file_spec.rb +66 -0
  26. data/spec/device/log_file_spec.rb +26 -0
  27. data/spec/device/null_spec.rb +12 -0
  28. data/spec/device/rolling_log_file_spec.rb +129 -0
  29. data/spec/device/size_rolling_log_file_spec.rb +54 -0
  30. data/spec/device/writer_spec.rb +118 -0
  31. data/spec/formatter/exception_formatter_spec.rb +20 -0
  32. data/spec/formatter/inspect_formatter_spec.rb +13 -0
  33. data/spec/formatter/pretty_print_formatter_spec.rb +14 -0
  34. data/spec/formatter/string_formatter_spec.rb +12 -0
  35. data/spec/formatter_spec.rb +45 -0
  36. data/spec/log_entry_spec.rb +69 -0
  37. data/spec/logger_spec.rb +390 -0
  38. data/spec/lumberjack_spec.rb +29 -0
  39. data/spec/rack/unit_of_work_spec.rb +26 -0
  40. data/spec/severity_spec.rb +23 -0
  41. data/spec/spec_helper.rb +16 -0
  42. data/spec/template_spec.rb +34 -0
  43. metadata +92 -0
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lumberjack::Device::Writer do
4
+
5
+ let(:time_string){ "2011-01-15T14:23:45.123" }
6
+ let(:time){ Time.parse(time_string) }
7
+ let(:stream){ StringIO.new }
8
+ let(:entry){ Lumberjack::LogEntry.new(time, Lumberjack::Severity::INFO, "test message", "app", 12345, "ABCD") }
9
+
10
+ it "should buffer output and not write directly to the stream" do
11
+ device = Lumberjack::Device::Writer.new(stream, :template => ":message", :buffer_size => 32767)
12
+ device.write(entry)
13
+ stream.string.should == ""
14
+ device.flush
15
+ stream.string.should == "test message#{Lumberjack::LINE_SEPARATOR}"
16
+ end
17
+
18
+ it "should flush the buffer when it gets to the specified size" do
19
+ device = Lumberjack::Device::Writer.new(stream, :buffer_size => 15, :template => ":message")
20
+ device.write(entry)
21
+ stream.string.should == ""
22
+ device.write(entry)
23
+ stream.string.should == "test message#{Lumberjack::LINE_SEPARATOR}test message#{Lumberjack::LINE_SEPARATOR}"
24
+ end
25
+
26
+ it "should sync the stream and flush it when the device is flushed" do
27
+ # Create an IO like object that require flush to be called
28
+ io = Object.new
29
+ def io.init; @string = ""; @buffer = ""; @sync = false; end
30
+ def io.write(string); @buffer << string; end
31
+ def io.flush; @string << @buffer; @buffer = ""; end
32
+ def io.string; @string; end
33
+ def io.sync=(val); @sync = val; end
34
+ def io.sync; @sync; end
35
+ io.init
36
+
37
+ device = Lumberjack::Device::Writer.new(io, :template => ":message", :buffer_size => 32767)
38
+ device.write(entry)
39
+ io.string.should == ""
40
+ device.flush
41
+ io.string.should == "test message#{Lumberjack::LINE_SEPARATOR}"
42
+ io.sync.should == true
43
+ end
44
+
45
+ it "should be able to set the buffer size" do
46
+ device = Lumberjack::Device::Writer.new(stream, :buffer_size => 15)
47
+ device.buffer_size.should == 15
48
+ device.buffer_size = 100
49
+ device.buffer_size.should == 100
50
+ end
51
+
52
+ it "should have a default buffer size of 0" do
53
+ device = Lumberjack::Device::Writer.new(stream)
54
+ device.buffer_size.should == 0
55
+ end
56
+
57
+ it "should write entries out to the stream with a default template" do
58
+ device = Lumberjack::Device::Writer.new(stream)
59
+ device.write(entry)
60
+ device.flush
61
+ stream.string.should == "[2011-01-15T14:23:45.123 INFO app(12345) #ABCD] test message#{Lumberjack::LINE_SEPARATOR}"
62
+ end
63
+
64
+ it "should write entries out to the stream with a custom template" do
65
+ device = Lumberjack::Device::Writer.new(stream, :template => ":message")
66
+ device.write(entry)
67
+ device.flush
68
+ stream.string.should == "test message#{Lumberjack::LINE_SEPARATOR}"
69
+ end
70
+
71
+ it "should be able to specify the time format for the template" do
72
+ device = Lumberjack::Device::Writer.new(stream, :time_format => :microseconds)
73
+ device.write(entry)
74
+ device.flush
75
+ stream.string.should == "[2011-01-15T14:23:45.123000 INFO app(12345) #ABCD] test message#{Lumberjack::LINE_SEPARATOR}"
76
+ end
77
+
78
+ it "should be able to specify a block template for log entries" do
79
+ device = Lumberjack::Device::Writer.new(stream, :template => lambda{|e| e.message.upcase})
80
+ device.write(entry)
81
+ device.flush
82
+ stream.string.should == "TEST MESSAGE#{Lumberjack::LINE_SEPARATOR}"
83
+ end
84
+
85
+ it "should write to STDERR if an error is raised when flushing to the stream" do
86
+ stderr = $stderr
87
+ $stderr = StringIO.new
88
+ begin
89
+ device = Lumberjack::Device::Writer.new(stream, :template => ":message")
90
+ stream.should_receive(:write).and_raise(StandardError.new("Cannot write to stream"))
91
+ device.write(entry)
92
+ device.flush
93
+ $stderr.string.should include("test message#{Lumberjack::LINE_SEPARATOR}")
94
+ $stderr.string.should include("StandardError: Cannot write to stream")
95
+ ensure
96
+ $stderr = stderr
97
+ end
98
+ end
99
+
100
+ context "multi line messages" do
101
+ let(:message){ "line 1#{Lumberjack::LINE_SEPARATOR}line 2#{Lumberjack::LINE_SEPARATOR}line 3" }
102
+ let(:entry){ Lumberjack::LogEntry.new(time, Lumberjack::Severity::INFO, message, "app", 12345, "ABCD") }
103
+
104
+ it "should have a default template for multiline messages" do
105
+ device = Lumberjack::Device::Writer.new(stream)
106
+ device.write(entry)
107
+ device.flush
108
+ stream.string.split(Lumberjack::LINE_SEPARATOR).should == ["[2011-01-15T14:23:45.123 INFO app(12345) #ABCD] line 1", "> [#ABCD] line 2", "> [#ABCD] line 3"]
109
+ end
110
+
111
+ it "should be able to specify a template for multiple line messages" do
112
+ device = Lumberjack::Device::Writer.new(stream, :additional_lines => " // :message")
113
+ device.write(entry)
114
+ device.flush
115
+ stream.string.should == "[2011-01-15T14:23:45.123 INFO app(12345) #ABCD] line 1 // line 2 // line 3#{Lumberjack::LINE_SEPARATOR}"
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lumberjack::Formatter::ExceptionFormatter do
4
+
5
+ it "should convert an exception without a backtrace to a string" do
6
+ e = ArgumentError.new("not expected")
7
+ formatter = Lumberjack::Formatter::ExceptionFormatter.new
8
+ formatter.call(e).should == "ArgumentError: not expected"
9
+ end
10
+
11
+ it "should convert an exception with a backtrace to a string" do
12
+ begin
13
+ raise ArgumentError.new("not expected")
14
+ rescue => e
15
+ formatter = Lumberjack::Formatter::ExceptionFormatter.new
16
+ formatter.call(e).should == "ArgumentError: not expected#{Lumberjack::LINE_SEPARATOR} #{e.backtrace.join(Lumberjack::LINE_SEPARATOR + ' ')}"
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lumberjack::Formatter::InspectFormatter do
4
+
5
+ it "should format objects as string by calling their inspect method" do
6
+ formatter = Lumberjack::Formatter::InspectFormatter.new
7
+ formatter.call("abc").should == "\"abc\""
8
+ formatter.call(:test).should == ":test"
9
+ formatter.call(1).should == "1"
10
+ formatter.call([:a, 1, "b"]).should == [:a, 1, "b"].inspect
11
+ end
12
+
13
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lumberjack::Formatter::PrettyPrintFormatter do
4
+
5
+ it "should convert an object to a string using pretty print" do
6
+ object = Object.new
7
+ def object.pretty_print(q)
8
+ q.text "woot!"
9
+ end
10
+ formatter = Lumberjack::Formatter::PrettyPrintFormatter.new
11
+ formatter.call(object).should == "woot!"
12
+ end
13
+
14
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lumberjack::Formatter::StringFormatter do
4
+
5
+ it "should format objects as string by calling their to_s method" do
6
+ formatter = Lumberjack::Formatter::StringFormatter.new
7
+ formatter.call("abc").should == "abc"
8
+ formatter.call(:test).should == "test"
9
+ formatter.call(1).should == "1"
10
+ end
11
+
12
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lumberjack::Formatter do
4
+
5
+ let(:formatter){ Lumberjack::Formatter.new }
6
+
7
+ it "should have a default set of formatters" do
8
+ formatter.format("abc").should == "abc"
9
+ formatter.format([1, 2, 3]).should == "[1, 2, 3]"
10
+ formatter.format(ArgumentError.new("boom")).should == "ArgumentError: boom"
11
+ end
12
+
13
+ it "should be able to add a formatter object for a class" do
14
+ formatter.add(Numeric, lambda{|obj| "number: #{obj}"})
15
+ formatter.format(10).should == "number: 10"
16
+ end
17
+
18
+ it "should be able to add a formatter block for a class" do
19
+ formatter.add(Numeric){|obj| "number: #{obj}"}
20
+ formatter.format(10).should == "number: 10"
21
+ end
22
+
23
+ it "should be able to remove a formatter for a class" do
24
+ formatter.remove(String)
25
+ formatter.format("abc").should == "\"abc\""
26
+ end
27
+
28
+ it "should be able to chain add and remove calls" do
29
+ formatter.remove(String).should == formatter
30
+ formatter.add(String, Lumberjack::Formatter::StringFormatter.new).should == formatter
31
+ end
32
+
33
+ it "should format an object based on the class hierarchy" do
34
+ formatter.add(Numeric){|obj| "number: #{obj}"}
35
+ formatter.add(Fixnum){|obj| "fixed number: #{obj}"}
36
+ formatter.format(10).should == "fixed number: 10"
37
+ formatter.format(10.1).should == "number: 10.1"
38
+ end
39
+
40
+ it "should have a default formatter" do
41
+ formatter.remove(Object)
42
+ formatter.format(:test).should == ":test"
43
+ end
44
+
45
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lumberjack::LogEntry do
4
+
5
+ it "should have a time" do
6
+ t = Time.now
7
+ entry = Lumberjack::LogEntry.new(t, Lumberjack::Severity::INFO, "test", "app", 1500, "ABCD")
8
+ entry.time.should == t
9
+ entry.time = t + 1
10
+ entry.time.should == t + 1
11
+ end
12
+
13
+ it "should have a severity" do
14
+ entry = Lumberjack::LogEntry.new(Time.now, Lumberjack::Severity::INFO, "test", "app", 1500, "ABCD")
15
+ entry.severity.should == Lumberjack::Severity::INFO
16
+ entry.severity = Lumberjack::Severity::WARN
17
+ entry.severity.should == Lumberjack::Severity::WARN
18
+ end
19
+
20
+ it "should convert a severity label to a numeric level" do
21
+ entry = Lumberjack::LogEntry.new(Time.now, "INFO", "test", "app", 1500, "ABCD")
22
+ entry.severity.should == Lumberjack::Severity::INFO
23
+ end
24
+
25
+ it "should get the severity as a string" do
26
+ Lumberjack::LogEntry.new(Time.now, Lumberjack::Severity::DEBUG, "test", "app", 1500, nil).severity_label.should == "DEBUG"
27
+ Lumberjack::LogEntry.new(Time.now, Lumberjack::Severity::INFO, "test", "app", 1500, nil).severity_label.should == "INFO"
28
+ Lumberjack::LogEntry.new(Time.now, Lumberjack::Severity::WARN, "test", "app", 1500, nil).severity_label.should == "WARN"
29
+ Lumberjack::LogEntry.new(Time.now, Lumberjack::Severity::ERROR, "test", "app", 1500, nil).severity_label.should == "ERROR"
30
+ Lumberjack::LogEntry.new(Time.now, Lumberjack::Severity::FATAL, "test", "app", 1500, nil).severity_label.should == "FATAL"
31
+ Lumberjack::LogEntry.new(Time.now, -1, "test", "app", 1500, nil).severity_label.should == "UNKNOWN"
32
+ Lumberjack::LogEntry.new(Time.now, 1000, "test", "app", 1500, nil).severity_label.should == "UNKNOWN"
33
+ end
34
+
35
+ it "should have a message" do
36
+ entry = Lumberjack::LogEntry.new(Time.now, Lumberjack::Severity::INFO, "test", "app", 1500, "ABCD")
37
+ entry.message.should == "test"
38
+ entry.message = "new message"
39
+ entry.message.should == "new message"
40
+ end
41
+
42
+ it "should have a progname" do
43
+ entry = Lumberjack::LogEntry.new(Time.now, Lumberjack::Severity::INFO, "test", "app", 1500, "ABCD")
44
+ entry.progname.should == "app"
45
+ entry.progname = "prog"
46
+ entry.progname.should == "prog"
47
+ end
48
+
49
+ it "should have a pid" do
50
+ entry = Lumberjack::LogEntry.new(Time.now, Lumberjack::Severity::INFO, "test", "app", 1500, "ABCD")
51
+ entry.pid.should == 1500
52
+ entry.pid = 150
53
+ entry.pid.should == 150
54
+ end
55
+
56
+ it "should have a unit_of_work_id" do
57
+ entry = Lumberjack::LogEntry.new(Time.now, Lumberjack::Severity::INFO, "test", "app", 1500, "ABCD")
58
+ entry.unit_of_work_id.should == "ABCD"
59
+ entry.unit_of_work_id = "1234"
60
+ entry.unit_of_work_id.should == "1234"
61
+ end
62
+
63
+ it "should be converted to a string" do
64
+ t = Time.parse("2011-01-29T12:15:32.001")
65
+ entry = Lumberjack::LogEntry.new(t, Lumberjack::Severity::INFO, "test", "app", 1500, "ABCD")
66
+ entry.to_s.should == "[2011-01-29T12:15:32.001 INFO app(1500) #ABCD] test"
67
+ end
68
+
69
+ end
@@ -0,0 +1,390 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lumberjack::Logger do
4
+
5
+ context "initialization" do
6
+
7
+ before :all do
8
+ create_tmp_dir
9
+ end
10
+
11
+ after :all do
12
+ delete_tmp_dir
13
+ end
14
+
15
+ it "should wrap an IO stream in a device" do
16
+ output = StringIO.new
17
+ logger = Lumberjack::Logger.new(output)
18
+ logger.device.class.should == Lumberjack::Device::Writer
19
+ end
20
+
21
+ it "should open a file path in a device" do
22
+ logger = Lumberjack::Logger.new(File.join(tmp_dir, "log_file_1.log"))
23
+ logger.device.class.should == Lumberjack::Device::LogFile
24
+ end
25
+
26
+ it "should use the null device if the stream is :null" do
27
+ logger = Lumberjack::Logger.new(:null)
28
+ logger.device.class.should == Lumberjack::Device::Null
29
+ end
30
+
31
+ it "should set the level with a numeric" do
32
+ logger = Lumberjack::Logger.new(:null, :level => Lumberjack::Severity::WARN)
33
+ logger.level.should == Lumberjack::Severity::WARN
34
+ end
35
+
36
+ it "should set the level with a level" do
37
+ logger = Lumberjack::Logger.new(:null, :level => :warn)
38
+ logger.level.should == Lumberjack::Severity::WARN
39
+ end
40
+
41
+ it "should default the level to INFO" do
42
+ logger = Lumberjack::Logger.new(:null)
43
+ logger.level.should == Lumberjack::Severity::INFO
44
+ end
45
+
46
+ it "should set the progname"do
47
+ logger = Lumberjack::Logger.new(:null, :progname => "app")
48
+ logger.progname.should == "app"
49
+ end
50
+
51
+ it "should create a thread to flush the device" do
52
+ Thread.should_receive(:new)
53
+ logger = Lumberjack::Logger.new(:null, :flush_seconds => 10)
54
+ end
55
+ end
56
+
57
+ context "attributes" do
58
+ it "should have a level" do
59
+ logger = Lumberjack::Logger.new
60
+ logger.level = Lumberjack::Severity::DEBUG
61
+ logger.level.should == Lumberjack::Severity::DEBUG
62
+ end
63
+
64
+ it "should have a progname" do
65
+ logger = Lumberjack::Logger.new
66
+ logger.progname = "app"
67
+ logger.progname.should == "app"
68
+ end
69
+
70
+ it "should be able to silence the log in a block" do
71
+ output = StringIO.new
72
+ logger = Lumberjack::Logger.new(output, :buffer_size => 0, :level => Lumberjack::Severity::INFO, :template => ":message")
73
+ logger.info("one")
74
+ logger.silence do
75
+ logger.level.should == Lumberjack::Severity::ERROR
76
+ logger.info("two")
77
+ logger.error("three")
78
+ end
79
+ logger.info("four")
80
+ output.string.split.should == ["one", "three", "four"]
81
+ end
82
+
83
+ it "should be able to customize the level of silence in a block" do
84
+ output = StringIO.new
85
+ logger = Lumberjack::Logger.new(output, :buffer_size => 0, :level => Lumberjack::Severity::INFO, :template => ":message")
86
+ logger.info("one")
87
+ logger.silence(Lumberjack::Severity::FATAL) do
88
+ logger.level.should == Lumberjack::Severity::FATAL
89
+ logger.info("two")
90
+ logger.error("three")
91
+ logger.fatal("woof")
92
+ end
93
+ logger.info("four")
94
+ output.string.split.should == ["one", "woof", "four"]
95
+ end
96
+
97
+ it "should not be able to silence the logger if silencing is disabled" do
98
+ output = StringIO.new
99
+ logger = Lumberjack::Logger.new(output, :buffer_size => 0, :level => Lumberjack::Severity::INFO, :template => ":message")
100
+ logger.silencer = false
101
+ logger.info("one")
102
+ logger.silence do
103
+ logger.level.should == Lumberjack::Severity::INFO
104
+ logger.info("two")
105
+ logger.error("three")
106
+ end
107
+ logger.info("four")
108
+ output.string.split.should == ["one", "two", "three", "four"]
109
+ end
110
+
111
+ it "should be able to set the progname in a block" do
112
+ logger = Lumberjack::Logger.new
113
+ logger.set_progname("app")
114
+ logger.progname.should == "app"
115
+ block_executed = false
116
+ logger.set_progname("xxx") do
117
+ block_executed = true
118
+ logger.progname.should == "xxx"
119
+ end
120
+ block_executed.should == true
121
+ logger.progname.should == "app"
122
+ end
123
+
124
+ it "should only affect the current thread when silencing the logger" do
125
+ output = StringIO.new
126
+ logger = Lumberjack::Logger.new(output, :buffer_size => 0, :level => Lumberjack::Severity::INFO, :template => ":message")
127
+ # status is used to make sure the two threads are executing at the same time
128
+ status = 0
129
+ begin
130
+ Thread.new do
131
+ logger.silence do
132
+ logger.info("inner")
133
+ status = 1
134
+ loop{ sleep(0.001); break if status == 2}
135
+ end
136
+ end
137
+ loop{ sleep(0.001); break if status == 1}
138
+ logger.info("outer")
139
+ status = 2
140
+ logger.close
141
+ output.string.should include("outer")
142
+ output.string.should_not include("inner")
143
+ ensure
144
+ status = 2
145
+ end
146
+ end
147
+
148
+ it "should only affect the current thread when changing the progname in a block" do
149
+ output = StringIO.new
150
+ logger = Lumberjack::Logger.new(output, :progname => "thread1", :buffer_size => 0, :level => Lumberjack::Severity::INFO, :template => ":progname :message")
151
+ # status is used to make sure the two threads are executing at the same time
152
+ status = 0
153
+ begin
154
+ Thread.new do
155
+ logger.set_progname("thread2") do
156
+ logger.info("inner")
157
+ status = 1
158
+ loop{ sleep(0.001); break if status == 2}
159
+ end
160
+ end
161
+ loop{ sleep(0.001); break if status == 1}
162
+ logger.info("outer")
163
+ status = 2
164
+ logger.close
165
+ output.string.should include("thread1")
166
+ output.string.should include("thread2")
167
+ ensure
168
+ status = 2
169
+ end
170
+ end
171
+ end
172
+
173
+ context "flushing" do
174
+ it "should autoflush the buffer if it hasn't been flushed in a specified number of seconds" do
175
+ output = StringIO.new
176
+ logger = Lumberjack::Logger.new(output, :flush_seconds => 0.1, :level => Lumberjack::Severity::INFO, :template => ":message", :buffer_size => 32767)
177
+ logger.info("message 1")
178
+ logger.info("message 2")
179
+ output.string.should == ""
180
+ sleep(0.15)
181
+ output.string.split(Lumberjack::LINE_SEPARATOR).should == ["message 1", "message 2"]
182
+ logger.info("message 3")
183
+ output.string.should_not include("message 3")
184
+ sleep(0.15)
185
+ output.string.split(Lumberjack::LINE_SEPARATOR).should == ["message 1", "message 2", "message 3"]
186
+ end
187
+
188
+ it "should write the log entries to the device on flush and update the last flushed time" do
189
+ output = StringIO.new
190
+ logger = Lumberjack::Logger.new(output, :level => Lumberjack::Severity::INFO, :template => ":message", :buffer_size => 32767)
191
+ logger.info("message 1")
192
+ output.string.should == ""
193
+ last_flushed_at = logger.last_flushed_at
194
+ logger.flush
195
+ output.string.split(Lumberjack::LINE_SEPARATOR).should == ["message 1"]
196
+ logger.last_flushed_at.should >= last_flushed_at
197
+ end
198
+
199
+ it "should flush the buffer and close the devices" do
200
+ output = StringIO.new
201
+ logger = Lumberjack::Logger.new(output, :level => Lumberjack::Severity::INFO, :template => ":message", :buffer_size => 32767)
202
+ logger.info("message 1")
203
+ output.string.should == ""
204
+ logger.close
205
+ output.string.split(Lumberjack::LINE_SEPARATOR).should == ["message 1"]
206
+ output.should be_closed
207
+ end
208
+ end
209
+
210
+ context "logging" do
211
+ let(:output){ StringIO.new }
212
+ let(:device){ Lumberjack::Device::Writer.new(output, :buffer_size => 0) }
213
+ let(:logger){ Lumberjack::Logger.new(device, :level => Lumberjack::Severity::INFO, :progname => "test") }
214
+ let(:n){ Lumberjack::LINE_SEPARATOR }
215
+
216
+ it "should add entries with a numeric severity and a message" do
217
+ time = Time.parse("2011-01-30T12:31:56.123")
218
+ Time.stub!(:now).and_return(time)
219
+ logger.add(Lumberjack::Severity::INFO, "test")
220
+ output.string.should == "[2011-01-30T12:31:56.123 INFO test(#{$$}) #] test#{n}"
221
+ end
222
+
223
+ it "should add entries with a severity label" do
224
+ time = Time.parse("2011-01-30T12:31:56.123")
225
+ Time.stub!(:now).and_return(time)
226
+ logger.add(:info, "test")
227
+ output.string.should == "[2011-01-30T12:31:56.123 INFO test(#{$$}) #] test#{n}"
228
+ end
229
+
230
+ it "should add entries with a custom progname and message" do
231
+ time = Time.parse("2011-01-30T12:31:56.123")
232
+ Time.stub!(:now).and_return(time)
233
+ logger.add(Lumberjack::Severity::INFO, "test", "app")
234
+ output.string.should == "[2011-01-30T12:31:56.123 INFO app(#{$$}) #] test#{n}"
235
+ end
236
+
237
+ it "should add entries with a local progname and message" do
238
+ time = Time.parse("2011-01-30T12:31:56.123")
239
+ Time.stub!(:now).and_return(time)
240
+ logger.set_progname("block") do
241
+ logger.add(Lumberjack::Severity::INFO, "test")
242
+ end
243
+ output.string.should == "[2011-01-30T12:31:56.123 INFO block(#{$$}) #] test#{n}"
244
+ end
245
+
246
+ it "should add entries with a block" do
247
+ time = Time.parse("2011-01-30T12:31:56.123")
248
+ Time.stub!(:now).and_return(time)
249
+ logger.add(Lumberjack::Severity::INFO){"test"}
250
+ output.string.should == "[2011-01-30T12:31:56.123 INFO test(#{$$}) #] test#{n}"
251
+ end
252
+
253
+ it "should log entries (::Logger compatibility)" do
254
+ time = Time.parse("2011-01-30T12:31:56.123")
255
+ Time.stub!(:now).and_return(time)
256
+ logger.log(Lumberjack::Severity::INFO, "test")
257
+ output.string.should == "[2011-01-30T12:31:56.123 INFO test(#{$$}) #] test#{n}"
258
+ end
259
+
260
+ it "should append messages with unknown severity to the log" do
261
+ time = Time.parse("2011-01-30T12:31:56.123")
262
+ Time.stub!(:now).and_return(time)
263
+ logger << "test"
264
+ output.string.should == "[2011-01-30T12:31:56.123 UNKNOWN test(#{$$}) #] test#{n}"
265
+ end
266
+
267
+ it "should ouput entries to STDERR if they can't be written the the device" do
268
+ stderr = $stderr
269
+ $stderr = StringIO.new
270
+ begin
271
+ time = Time.parse("2011-01-30T12:31:56.123")
272
+ Time.stub!(:now).and_return(time)
273
+ device.should_receive(:write).and_raise(StandardError.new("Cannot write to device"))
274
+ logger.add(Lumberjack::Severity::INFO, "test")
275
+ $stderr.string.should include("[2011-01-30T12:31:56.123 INFO test(#{$$})] test")
276
+ $stderr.string.should include("StandardError: Cannot write to device")
277
+ ensure
278
+ $stderr = stderr
279
+ end
280
+ end
281
+
282
+ context "log helper methods" do
283
+ let(:device){ Lumberjack::Device::Writer.new(output, :buffer_size => 0, :template => ":message") }
284
+
285
+ it "should only add messages whose severity is greater or equal to the logger level" do
286
+ logger.add(Lumberjack::Severity::DEBUG, "debug")
287
+ logger.add(Lumberjack::Severity::INFO, "info")
288
+ logger.add(Lumberjack::Severity::ERROR, "error")
289
+ output.string.should == "info#{n}error#{n}"
290
+ end
291
+
292
+ it "should only log fatal messages when the level is set to fatal" do
293
+ logger.level = Lumberjack::Severity::FATAL
294
+ logger.fatal("fatal")
295
+ logger.fatal?.should == true
296
+ logger.error("error")
297
+ logger.error?.should == false
298
+ logger.warn("warn")
299
+ logger.warn?.should == false
300
+ logger.info("info")
301
+ logger.info?.should == false
302
+ logger.debug("debug")
303
+ logger.debug?.should == false
304
+ logger.unknown("unknown")
305
+ output.string.should == "fatal#{n}unknown#{n}"
306
+ end
307
+
308
+ it "should only log error messages and higher when the level is set to error" do
309
+ logger.level = Lumberjack::Severity::ERROR
310
+ logger.fatal("fatal")
311
+ logger.fatal?.should == true
312
+ logger.error("error")
313
+ logger.error?.should == true
314
+ logger.warn("warn")
315
+ logger.warn?.should == false
316
+ logger.info("info")
317
+ logger.info?.should == false
318
+ logger.debug("debug")
319
+ logger.debug?.should == false
320
+ logger.unknown("unknown")
321
+ output.string.should == "fatal#{n}error#{n}unknown#{n}"
322
+ end
323
+
324
+ it "should only log warn messages and higher when the level is set to warn" do
325
+ logger.level = Lumberjack::Severity::WARN
326
+ logger.fatal("fatal")
327
+ logger.fatal?.should == true
328
+ logger.error("error")
329
+ logger.error?.should == true
330
+ logger.warn("warn")
331
+ logger.warn?.should == true
332
+ logger.info("info")
333
+ logger.info?.should == false
334
+ logger.debug("debug")
335
+ logger.debug?.should == false
336
+ logger.unknown("unknown")
337
+ output.string.should == "fatal#{n}error#{n}warn#{n}unknown#{n}"
338
+ end
339
+
340
+ it "should only log info messages and higher when the level is set to info" do
341
+ logger.level = Lumberjack::Severity::INFO
342
+ logger.fatal("fatal")
343
+ logger.fatal?.should == true
344
+ logger.error("error")
345
+ logger.error?.should == true
346
+ logger.warn("warn")
347
+ logger.warn?.should == true
348
+ logger.info("info")
349
+ logger.info?.should == true
350
+ logger.debug("debug")
351
+ logger.debug?.should == false
352
+ logger.unknown("unknown")
353
+ output.string.should == "fatal#{n}error#{n}warn#{n}info#{n}unknown#{n}"
354
+ end
355
+
356
+ it "should log all messages when the level is set to debug" do
357
+ logger.level = Lumberjack::Severity::DEBUG
358
+ logger.fatal("fatal")
359
+ logger.fatal?.should == true
360
+ logger.error("error")
361
+ logger.error?.should == true
362
+ logger.warn("warn")
363
+ logger.warn?.should == true
364
+ logger.info("info")
365
+ logger.info?.should == true
366
+ logger.debug("debug")
367
+ logger.debug?.should == true
368
+ logger.unknown("unknown")
369
+ output.string.should == "fatal#{n}error#{n}warn#{n}info#{n}debug#{n}unknown#{n}"
370
+ end
371
+
372
+ it "should only log unkown messages when the level is set above fatal" do
373
+ logger.level = Lumberjack::Severity::FATAL + 1
374
+ logger.fatal("fatal")
375
+ logger.fatal?.should == false
376
+ logger.error("error")
377
+ logger.error?.should == false
378
+ logger.warn("warn")
379
+ logger.warn?.should == false
380
+ logger.info("info")
381
+ logger.info?.should == false
382
+ logger.debug("debug")
383
+ logger.debug?.should == false
384
+ logger.unknown("unknown")
385
+ output.string.should == "unknown#{n}"
386
+ end
387
+ end
388
+ end
389
+
390
+ end