lumberjack_aziz_light 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
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