lumberjack 1.0.0

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