lumberjack 1.0.13 → 1.1.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 (49) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +74 -0
  3. data/README.md +92 -20
  4. data/VERSION +1 -1
  5. data/lib/lumberjack.rb +51 -16
  6. data/lib/lumberjack/context.rb +35 -0
  7. data/lib/lumberjack/device.rb +20 -6
  8. data/lib/lumberjack/device/date_rolling_log_file.rb +2 -2
  9. data/lib/lumberjack/device/log_file.rb +12 -1
  10. data/lib/lumberjack/device/multi.rb +46 -0
  11. data/lib/lumberjack/device/null.rb +0 -2
  12. data/lib/lumberjack/device/rolling_log_file.rb +2 -2
  13. data/lib/lumberjack/device/size_rolling_log_file.rb +1 -1
  14. data/lib/lumberjack/device/writer.rb +86 -55
  15. data/lib/lumberjack/formatter.rb +54 -18
  16. data/lib/lumberjack/formatter/date_time_formatter.rb +26 -0
  17. data/lib/lumberjack/formatter/id_formatter.rb +23 -0
  18. data/lib/lumberjack/formatter/object_formatter.rb +12 -0
  19. data/lib/lumberjack/formatter/structured_formatter.rb +31 -0
  20. data/lib/lumberjack/log_entry.rb +41 -16
  21. data/lib/lumberjack/logger.rb +168 -63
  22. data/lib/lumberjack/rack.rb +3 -2
  23. data/lib/lumberjack/rack/context.rb +18 -0
  24. data/lib/lumberjack/rack/request_id.rb +4 -4
  25. data/lib/lumberjack/severity.rb +11 -9
  26. data/lib/lumberjack/tags.rb +24 -0
  27. data/lib/lumberjack/template.rb +74 -32
  28. data/lumberjack.gemspec +35 -0
  29. metadata +48 -37
  30. data/Rakefile +0 -40
  31. data/spec/device/date_rolling_log_file_spec.rb +0 -73
  32. data/spec/device/log_file_spec.rb +0 -48
  33. data/spec/device/null_spec.rb +0 -12
  34. data/spec/device/rolling_log_file_spec.rb +0 -151
  35. data/spec/device/size_rolling_log_file_spec.rb +0 -58
  36. data/spec/device/writer_spec.rb +0 -118
  37. data/spec/formatter/exception_formatter_spec.rb +0 -20
  38. data/spec/formatter/inspect_formatter_spec.rb +0 -13
  39. data/spec/formatter/pretty_print_formatter_spec.rb +0 -14
  40. data/spec/formatter/string_formatter_spec.rb +0 -12
  41. data/spec/formatter_spec.rb +0 -45
  42. data/spec/log_entry_spec.rb +0 -69
  43. data/spec/logger_spec.rb +0 -411
  44. data/spec/lumberjack_spec.rb +0 -29
  45. data/spec/rack/request_id_spec.rb +0 -48
  46. data/spec/rack/unit_of_work_spec.rb +0 -26
  47. data/spec/severity_spec.rb +0 -23
  48. data/spec/spec_helper.rb +0 -32
  49. data/spec/template_spec.rb +0 -34
data/Rakefile DELETED
@@ -1,40 +0,0 @@
1
- require 'rubygems'
2
- require 'rake'
3
- require 'rubygems/package_task'
4
-
5
- desc 'Default: run unit tests.'
6
- task :default => :test
7
-
8
- desc 'RVM likes to call it tests'
9
- task :tests => :test
10
-
11
- begin
12
- require 'rspec'
13
- require 'rspec/core/rake_task'
14
- desc 'Run the unit tests'
15
- RSpec::Core::RakeTask.new(:test)
16
- rescue LoadError
17
- task :test do
18
- STDERR.puts "You must have rspec 2.0 installed to run the tests"
19
- end
20
- end
21
-
22
- namespace :rbx do
23
- desc "Cleanup *.rbc files in lib directory"
24
- task :delete_rbc_files do
25
- FileList["**/*.rbc"].each do |rbc_file|
26
- File.delete(rbc_file)
27
- end
28
- nil
29
- end
30
- end
31
-
32
- spec_file = File.expand_path('../lumberjack.gemspec', __FILE__)
33
- if File.exist?(spec_file)
34
- spec = eval(File.read(spec_file))
35
-
36
- Gem::PackageTask.new(spec) do |p|
37
- p.gem_spec = spec
38
- end
39
- Rake.application["package"].prerequisites.unshift("rbx:delete_rbc_files")
40
- end
@@ -1,73 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Lumberjack::Device::DateRollingLogFile do
4
-
5
- before :all do
6
- create_tmp_dir
7
- end
8
-
9
- after :all do
10
- delete_tmp_dir
11
- end
12
-
13
- before :each do
14
- delete_tmp_files
15
- end
16
-
17
- let(:one_day){ 60 * 60 * 24 }
18
-
19
- it "should roll the file daily" do
20
- now = Time.now
21
- log_file = File.join(tmp_dir, "a#{rand(1000000000)}.log")
22
- device = Lumberjack::Device::DateRollingLogFile.new(log_file, :roll => :daily, :template => ":message", :min_roll_check => 0)
23
- logger = Lumberjack::Logger.new(device, :buffer_size => 2)
24
- Timecop.travel(now) do
25
- logger.error("test day one")
26
- logger.flush
27
- end
28
- Timecop.travel(now + one_day) do
29
- logger.error("test day two")
30
- logger.close
31
- end
32
-
33
- File.read("#{log_file}.#{now.to_date.strftime('%Y-%m-%d')}").should == "test day one#{Lumberjack::LINE_SEPARATOR}"
34
- File.read(log_file).should == "test day two#{Lumberjack::LINE_SEPARATOR}"
35
- end
36
-
37
- it "should roll the file weekly" do
38
- now = Time.now
39
- log_file = File.join(tmp_dir, "b#{rand(1000000000)}.log")
40
- device = Lumberjack::Device::DateRollingLogFile.new(log_file, :roll => :weekly, :template => ":message", :min_roll_check => 0)
41
- logger = Lumberjack::Logger.new(device, :buffer_size => 2)
42
- Timecop.freeze(now) do
43
- logger.error("test week one")
44
- logger.flush
45
- end
46
- Timecop.freeze(now + (7 * one_day)) do
47
- logger.error("test week two")
48
- logger.close
49
- end
50
-
51
- File.read("#{log_file}.#{now.to_date.strftime('week-of-%Y-%m-%d')}").should == "test week one#{Lumberjack::LINE_SEPARATOR}"
52
- File.read(log_file).should == "test week two#{Lumberjack::LINE_SEPARATOR}"
53
- end
54
-
55
- it "should roll the file monthly" do
56
- now = Time.now
57
- log_file = File.join(tmp_dir, "c#{rand(1000000000)}.log")
58
- device = Lumberjack::Device::DateRollingLogFile.new(log_file, :roll => :monthly, :template => ":message", :min_roll_check => 0)
59
- logger = Lumberjack::Logger.new(device, :buffer_size => 2)
60
- Timecop.freeze(now) do
61
- logger.error("test month one")
62
- logger.flush
63
- end
64
- Timecop.freeze(now + (31 * one_day)) do
65
- logger.error("test month two")
66
- logger.close
67
- end
68
-
69
- File.read("#{log_file}.#{now.to_date.strftime('%Y-%m')}").should == "test month one#{Lumberjack::LINE_SEPARATOR}"
70
- File.read(log_file).should == "test month two#{Lumberjack::LINE_SEPARATOR}"
71
- end
72
-
73
- end
@@ -1,48 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require 'spec_helper'
3
-
4
- describe Lumberjack::Device::LogFile do
5
-
6
- before :all do
7
- create_tmp_dir
8
- end
9
-
10
- after :all do
11
- delete_tmp_dir
12
- end
13
-
14
- before :each do
15
- delete_tmp_files
16
- end
17
-
18
- it "should append to a file" do
19
- log_file = File.join(tmp_dir, "a#{rand(1000000000)}.log")
20
- File.open(log_file, 'w') do |f|
21
- f.puts("Existing contents")
22
- end
23
-
24
- device = Lumberjack::Device::LogFile.new(log_file, :template => ":message")
25
- device.write(Lumberjack::LogEntry.new(Time.now, 1, "New log entry", nil, $$, nil))
26
- device.close
27
-
28
- File.read(log_file).should == "Existing contents\nNew log entry#{Lumberjack::LINE_SEPARATOR}"
29
- end
30
-
31
- it "properly handles messages with broken UTF-8 characters" do
32
- log_file = File.join(tmp_dir, "test_6.log")
33
- device = Lumberjack::Device::LogFile.new(log_file,
34
- :keep => 2, :buffer_size => 32767)
35
-
36
- message = [0xC4, 0x90, 0xE1, 0xBB].pack("c*").force_encoding "ASCII-8BIT"
37
- entry = Lumberjack::LogEntry.new(Time.now, 1, message, nil, $$, nil)
38
- device.write entry
39
-
40
- message = "проверка"
41
- entry = Lumberjack::LogEntry.new(Time.now, 1, message, nil, $$, nil)
42
- device.write entry
43
-
44
- expect do
45
- device.flush
46
- end.to_not raise_error
47
- end
48
- end
@@ -1,12 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Lumberjack::Device::Null do
4
-
5
- it "should not generate any output" do
6
- device = Lumberjack::Device::Null.new
7
- device.write(Lumberjack::LogEntry.new(Time.now, 1, "New log entry", nil, $$, nil))
8
- device.flush
9
- device.close
10
- end
11
-
12
- end
@@ -1,151 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Lumberjack::Device::RollingLogFile do
4
-
5
- before :all do
6
- Lumberjack::Device::SizeRollingLogFile #needed by jruby
7
- create_tmp_dir
8
- end
9
-
10
- after :all do
11
- delete_tmp_dir
12
- end
13
-
14
- before :each do
15
- delete_tmp_files
16
- end
17
-
18
- let(:entry){ Lumberjack::LogEntry.new(Time.now, 1, "New log entry", nil, $$, nil) }
19
-
20
- it "should check for rolling the log file on flush" do
21
- device = Lumberjack::Device::RollingLogFile.new(File.join(tmp_dir, "test.log"), :buffer_size => 32767, :min_roll_check => 0)
22
- device.write(entry)
23
- expect(device).to receive(:roll_file?).twice.and_return(false)
24
- device.flush
25
- device.close
26
- end
27
-
28
- it "should roll the file by archiving the existing file and opening a new stream and calling after_roll" do
29
- log_file = File.join(tmp_dir, "test_2.log")
30
- device = Lumberjack::Device::RollingLogFile.new(log_file, :template => ":message", :buffer_size => 32767, :min_roll_check => 0)
31
- expect(device).to receive(:roll_file?).and_return(false, true)
32
- expect(device).to receive(:after_roll)
33
- device.stub(:archive_file_suffix => "rolled")
34
- device.write(entry)
35
- device.flush
36
- device.write(Lumberjack::LogEntry.new(Time.now, 1, "Another log entry", nil, $$, nil))
37
- device.close
38
- File.read("#{log_file}.rolled").should == "New log entry#{Lumberjack::LINE_SEPARATOR}"
39
- File.read(log_file).should == "Another log entry#{Lumberjack::LINE_SEPARATOR}"
40
- end
41
-
42
- it "should reopen the file if the stream inode doesn't match the file path inode" do
43
- log_file = File.join(tmp_dir, "test_3.log")
44
- device = Lumberjack::Device::RollingLogFile.new(log_file, :template => ":message", :min_roll_check => 0)
45
- device.stub(:roll_file? => false)
46
- device.write(entry)
47
- device.flush
48
- File.rename(log_file, "#{log_file}.rolled")
49
- device.flush
50
- device.write(Lumberjack::LogEntry.new(Time.now, 1, "Another log entry", nil, $$, nil))
51
- device.close
52
- File.read("#{log_file}.rolled").should == "New log entry#{Lumberjack::LINE_SEPARATOR}"
53
- File.read(log_file).should == "Another log entry#{Lumberjack::LINE_SEPARATOR}"
54
- end
55
-
56
- it "should roll the file properly with multiple thread and processes using it" do
57
- log_file = File.join(tmp_dir, "test_4.log")
58
- process_count = 8
59
- thread_count = 4
60
- entry_count = 400
61
- max_size = 128
62
- severity = Lumberjack::Severity::INFO
63
- message = "This is a test message that is written to the log file to indicate what the state of the application is."
64
-
65
- logger_test = lambda do
66
- device = Lumberjack::Device::SizeRollingLogFile.new(log_file, :max_size => max_size, :template => ":message", :buffer_size => 32767, :min_roll_check => 0)
67
- threads = []
68
- thread_count.times do
69
- threads << Thread.new do
70
- entry_count.times do |i|
71
- device.write(Lumberjack::LogEntry.new(Time.now, severity, message, "test", $$, nil))
72
- device.flush if i % 10 == 0
73
- end
74
- device.flush
75
- end
76
- end
77
- threads.each{|thread| thread.value}
78
- device.close
79
- end
80
-
81
- # Process.fork is unavailable on jruby so we need to use the java threads instead.
82
- if RUBY_PLATFORM.match(/java/)
83
- outer_threads = []
84
- process_count.times do
85
- outer_threads << Thread.new(&logger_test)
86
- end
87
- outer_threads.each{|thread| thread.value}
88
- else
89
- process_count.times do
90
- Process.fork(&logger_test)
91
- end
92
- Process.waitall
93
- end
94
-
95
- line_count = 0
96
- file_count = 0
97
- Dir.glob("#{log_file}*").each do |file|
98
- file_count += 1
99
- lines = File.read(file).split(Lumberjack::LINE_SEPARATOR)
100
- line_count += lines.size
101
- lines.each do |line|
102
- line.should == message
103
- end
104
- end
105
-
106
- file_count.should > 3
107
- end
108
-
109
- it "should only keep a specified number of archived log files" do
110
- log_file = File.join(tmp_dir, "test_5.log")
111
- device = Lumberjack::Device::RollingLogFile.new(log_file, :template => ":message", :keep => 2, :buffer_size => 32767, :min_roll_check => 0)
112
- expect(device).to receive(:roll_file?).and_return(false, true, true, true)
113
- expect(device).to receive(:archive_file_suffix).and_return("delete", "another", "keep")
114
- t = Time.now
115
- expect(File).to receive(:ctime).with("#{log_file}.delete").at_least(1).times.and_return(t + 1)
116
- expect(File).to receive(:ctime).with("#{log_file}.another").at_least(1).times.and_return(t + 2)
117
- expect(File).to receive(:ctime).with("#{log_file}.keep").at_least(1).times.and_return(t + 3)
118
- device.write(entry)
119
- device.flush
120
- device.write(entry)
121
- device.flush
122
- device.write(entry)
123
- device.flush
124
- device.write(entry)
125
- device.close
126
- Dir.glob("#{log_file}*").sort.should == [log_file, "#{log_file}.another", "#{log_file}.keep"]
127
- end
128
-
129
- context "when file is rolled" do
130
- let(:log_file) { File.join(tmp_dir, "test_6.log") }
131
-
132
- let(:device) do
133
- device = Lumberjack::Device::RollingLogFile.new(log_file, :template => ":message", :keep => 2, :buffer_size => 32767, :min_roll_check => 0)
134
- device.stub(:roll_file?).and_return(true)
135
- device.stub(:archive_file_suffix => "rolled")
136
- device
137
- end
138
-
139
- before do
140
- device.write(entry)
141
- device.flush
142
- end
143
-
144
- it "reopens file with proper encoding" do
145
- encoding = device.send(:stream).external_encoding
146
- expect(encoding).to_not be_nil
147
- expect(encoding.name).to eq "ASCII-8BIT"
148
- end
149
- end
150
-
151
- end
@@ -1,58 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Lumberjack::Device::SizeRollingLogFile do
4
-
5
- before :all do
6
- create_tmp_dir
7
- end
8
-
9
- after :all do
10
- delete_tmp_dir
11
- end
12
-
13
- before :each do
14
- delete_tmp_files
15
- end
16
-
17
- it "should roll a file when it gets to a specified size" do
18
- log_file = File.join(tmp_dir, "a#{rand(1000000000)}.log")
19
- device = Lumberjack::Device::SizeRollingLogFile.new(log_file, :max_size => 40, :template => ":message", :min_roll_check => 0)
20
- logger = Lumberjack::Logger.new(device, :buffer_size => 2)
21
- 4.times do |i|
22
- logger.error("test message #{i + 1}")
23
- logger.flush
24
- end
25
- logger.close
26
-
27
- File.read("#{log_file}.1").split(Lumberjack::LINE_SEPARATOR).should == ["test message 1", "test message 2", "test message 3"]
28
- File.read(log_file).should == "test message 4#{Lumberjack::LINE_SEPARATOR}"
29
- end
30
-
31
- it "should be able to specify the max size in kilobytes" do
32
- log_file = File.join(tmp_dir, "b#{rand(1000000000)}.log")
33
- device = Lumberjack::Device::SizeRollingLogFile.new(log_file, :max_size => "32K", :min_roll_check => 0)
34
- device.max_size.should == 32768
35
- end
36
-
37
- it "should be able to specify the max size in megabytes" do
38
- log_file = File.join(tmp_dir, "c#{rand(1000000000)}.log")
39
- device = Lumberjack::Device::SizeRollingLogFile.new(log_file, :max_size => "100M", :min_roll_check => 0)
40
- device.max_size.should == 104_857_600
41
- end
42
-
43
- it "should be able to specify the max size in gigabytes" do
44
- log_file = File.join(tmp_dir, "d#{rand(1000000000)}.log")
45
- device = Lumberjack::Device::SizeRollingLogFile.new(log_file, :max_size => "1G", :min_roll_check => 0)
46
- device.max_size.should == 1_073_741_824
47
- end
48
-
49
- it "should figure out the next archive file name available" do
50
- log_file = File.join(tmp_dir, "filename.log")
51
- (3..11).each do |i|
52
- File.open("#{log_file}.#{i}", 'w'){|f| f.write(i.to_s)}
53
- end
54
- device = Lumberjack::Device::SizeRollingLogFile.new(log_file, :max_size => "100M", :min_roll_check => 0)
55
- device.archive_file_suffix.should == "12"
56
- end
57
-
58
- end
@@ -1,118 +0,0 @@
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