lumberjack 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.
Files changed (60) hide show
  1. data/MIT_LICENSE +20 -0
  2. data/README.rdoc +86 -0
  3. data/Rakefile +56 -0
  4. data/VERSION +1 -0
  5. data/lib/lumberjack.rb +39 -0
  6. data/lib/lumberjack/device.rb +26 -0
  7. data/lib/lumberjack/device/date_rolling_log_file.rb +58 -0
  8. data/lib/lumberjack/device/log_file.rb +18 -0
  9. data/lib/lumberjack/device/null.rb +15 -0
  10. data/lib/lumberjack/device/rolling_log_file.rb +109 -0
  11. data/lib/lumberjack/device/size_rolling_log_file.rb +58 -0
  12. data/lib/lumberjack/device/writer.rb +119 -0
  13. data/lib/lumberjack/formatter.rb +76 -0
  14. data/lib/lumberjack/formatter/exception_formatter.rb +12 -0
  15. data/lib/lumberjack/formatter/inspect_formatter.rb +10 -0
  16. data/lib/lumberjack/formatter/pretty_print_formatter.rb +23 -0
  17. data/lib/lumberjack/formatter/string_formatter.rb +10 -0
  18. data/lib/lumberjack/log_entry.rb +36 -0
  19. data/lib/lumberjack/logger.rb +302 -0
  20. data/lib/lumberjack/rack.rb +5 -0
  21. data/lib/lumberjack/rack/unit_of_work.rb +15 -0
  22. data/lib/lumberjack/severity.rb +23 -0
  23. data/lib/lumberjack/template.rb +71 -0
  24. data/spec/device/date_rolling_log_file_spec.rb +66 -0
  25. data/spec/device/date_rolling_log_file_spec.rbc +2118 -0
  26. data/spec/device/log_file_spec.rb +26 -0
  27. data/spec/device/log_file_spec.rbc +727 -0
  28. data/spec/device/null_spec.rb +12 -0
  29. data/spec/device/null_spec.rbc +362 -0
  30. data/spec/device/rolling_log_file_spec.rb +117 -0
  31. data/spec/device/rolling_log_file_spec.rbc +2894 -0
  32. data/spec/device/size_rolling_log_file_spec.rb +54 -0
  33. data/spec/device/size_rolling_log_file_spec.rbc +1961 -0
  34. data/spec/device/stream_spec.rbc +3310 -0
  35. data/spec/device/writer_spec.rb +118 -0
  36. data/spec/entry_spec.rbc +2333 -0
  37. data/spec/formatter/exception_formatter_spec.rb +20 -0
  38. data/spec/formatter/exception_formatter_spec.rbc +620 -0
  39. data/spec/formatter/inspect_formatter_spec.rb +13 -0
  40. data/spec/formatter/inspect_formatter_spec.rbc +360 -0
  41. data/spec/formatter/pretty_print_formatter_spec.rb +14 -0
  42. data/spec/formatter/pretty_print_formatter_spec.rbc +380 -0
  43. data/spec/formatter/string_formatter_spec.rb +12 -0
  44. data/spec/formatter/string_formatter_spec.rbc +314 -0
  45. data/spec/formatter_spec.rb +45 -0
  46. data/spec/formatter_spec.rbc +1431 -0
  47. data/spec/log_entry_spec.rb +69 -0
  48. data/spec/logger_spec.rb +390 -0
  49. data/spec/logger_spec.rbc +10043 -0
  50. data/spec/lumberjack_spec.rb +22 -0
  51. data/spec/lumberjack_spec.rbc +523 -0
  52. data/spec/rack/unit_of_work_spec.rb +26 -0
  53. data/spec/rack/unit_of_work_spec.rbc +697 -0
  54. data/spec/severity_spec.rb +23 -0
  55. data/spec/spec_helper.rb +16 -0
  56. data/spec/spec_helper.rbc +391 -0
  57. data/spec/template_spec.rb +34 -0
  58. data/spec/template_spec.rbc +1563 -0
  59. data/spec/unique_identifier_spec.rbc +329 -0
  60. metadata +128 -0
@@ -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")
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")
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")
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