sgeorgi-logging 1.4.2

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 (72) hide show
  1. data/History.txt +262 -0
  2. data/README.rdoc +115 -0
  3. data/Rakefile +32 -0
  4. data/data/bad_logging_1.rb +13 -0
  5. data/data/bad_logging_2.rb +21 -0
  6. data/data/logging.rb +42 -0
  7. data/data/logging.yaml +63 -0
  8. data/data/simple_logging.rb +13 -0
  9. data/examples/appenders.rb +47 -0
  10. data/examples/classes.rb +41 -0
  11. data/examples/consolidation.rb +83 -0
  12. data/examples/fork.rb +37 -0
  13. data/examples/formatting.rb +51 -0
  14. data/examples/hierarchies.rb +73 -0
  15. data/examples/layouts.rb +48 -0
  16. data/examples/loggers.rb +29 -0
  17. data/examples/names.rb +43 -0
  18. data/examples/simple.rb +17 -0
  19. data/lib/logging.rb +528 -0
  20. data/lib/logging/appender.rb +260 -0
  21. data/lib/logging/appenders.rb +137 -0
  22. data/lib/logging/appenders/buffering.rb +178 -0
  23. data/lib/logging/appenders/console.rb +60 -0
  24. data/lib/logging/appenders/email.rb +75 -0
  25. data/lib/logging/appenders/file.rb +75 -0
  26. data/lib/logging/appenders/growl.rb +197 -0
  27. data/lib/logging/appenders/io.rb +69 -0
  28. data/lib/logging/appenders/rolling_file.rb +327 -0
  29. data/lib/logging/appenders/string_io.rb +68 -0
  30. data/lib/logging/appenders/syslog.rb +210 -0
  31. data/lib/logging/config/configurator.rb +188 -0
  32. data/lib/logging/config/yaml_configurator.rb +191 -0
  33. data/lib/logging/layout.rb +117 -0
  34. data/lib/logging/layouts.rb +47 -0
  35. data/lib/logging/layouts/basic.rb +32 -0
  36. data/lib/logging/layouts/parseable.rb +211 -0
  37. data/lib/logging/layouts/pattern.rb +311 -0
  38. data/lib/logging/log_event.rb +45 -0
  39. data/lib/logging/logger.rb +504 -0
  40. data/lib/logging/repository.rb +232 -0
  41. data/lib/logging/root_logger.rb +61 -0
  42. data/lib/logging/stats.rb +278 -0
  43. data/lib/logging/utils.rb +201 -0
  44. data/lib/spec/logging_helper.rb +34 -0
  45. data/test/appenders/test_buffered_io.rb +176 -0
  46. data/test/appenders/test_console.rb +66 -0
  47. data/test/appenders/test_email.rb +170 -0
  48. data/test/appenders/test_file.rb +95 -0
  49. data/test/appenders/test_growl.rb +127 -0
  50. data/test/appenders/test_io.rb +129 -0
  51. data/test/appenders/test_rolling_file.rb +209 -0
  52. data/test/appenders/test_syslog.rb +194 -0
  53. data/test/benchmark.rb +86 -0
  54. data/test/config/test_configurator.rb +70 -0
  55. data/test/config/test_yaml_configurator.rb +40 -0
  56. data/test/layouts/test_basic.rb +42 -0
  57. data/test/layouts/test_json.rb +112 -0
  58. data/test/layouts/test_pattern.rb +198 -0
  59. data/test/layouts/test_yaml.rb +121 -0
  60. data/test/setup.rb +43 -0
  61. data/test/test_appender.rb +152 -0
  62. data/test/test_consolidate.rb +46 -0
  63. data/test/test_layout.rb +110 -0
  64. data/test/test_log_event.rb +80 -0
  65. data/test/test_logger.rb +699 -0
  66. data/test/test_logging.rb +267 -0
  67. data/test/test_repository.rb +158 -0
  68. data/test/test_root_logger.rb +81 -0
  69. data/test/test_stats.rb +274 -0
  70. data/test/test_utils.rb +116 -0
  71. data/version.txt +1 -0
  72. metadata +227 -0
@@ -0,0 +1,170 @@
1
+
2
+ require File.join(File.dirname(__FILE__), %w[.. setup])
3
+ require 'flexmock'
4
+
5
+ module TestLogging
6
+ module TestAppenders
7
+
8
+ class TestEmail < Test::Unit::TestCase
9
+ include FlexMock::TestCase
10
+ include LoggingTestCase
11
+
12
+ def setup
13
+ super
14
+
15
+ flexmock(Net::SMTP).new_instances do |m|
16
+ m.should_receive(:start).at_least.once.with(
17
+ 'test.logging', 'test', 'test', :cram_md5, Proc).and_yield(m)
18
+ m.should_receive(:sendmail).at_least.once.with(String, 'me', ['you'])
19
+ end
20
+
21
+ @appender = Logging.appenders.email('email',
22
+ 'from' => 'me', 'to' => 'you',
23
+ :buffer_size => '3', :immediate_at => 'error, fatal',
24
+ :domain => 'test.logging', :acct => 'test', :passwd => 'test'
25
+ )
26
+ @levels = Logging::LEVELS
27
+ end
28
+
29
+ def test_initialize
30
+ assert_raise(ArgumentError, 'Must specify from address') {
31
+ Logging.appenders.email('email')
32
+ }
33
+ assert_raise(ArgumentError, 'Must specify to address') {
34
+ Logging.appenders.email('email', :from => 'me')
35
+ }
36
+ assert_nothing_raised {
37
+ Logging.appenders.email('email', :from => 'me', :to => 'you')
38
+ }
39
+
40
+ appender = Logging.appenders.email('email',
41
+ 'from' => 'me', 'to' => 'you'
42
+ )
43
+
44
+ assert_equal(100, appender.auto_flushing)
45
+ assert_equal([], appender.instance_variable_get(:@immediate))
46
+ assert_equal('localhost', appender.server)
47
+ assert_equal(25, appender.port)
48
+
49
+ domain = ENV['HOSTNAME'] || 'localhost.localdomain'
50
+ assert_equal(domain, appender.domain)
51
+ assert_equal(nil, appender.acct)
52
+ assert_equal(:cram_md5, appender.authtype)
53
+ assert_equal("Message of #{$0}", appender.subject)
54
+
55
+ appender = Logging.appenders.email('email',
56
+ 'from' => 'lbrinn@gmail.com', 'to' => 'everyone',
57
+ :buffsize => '1000', :immediate_at => 'error, fatal',
58
+ :server => 'smtp.google.com', :port => '443',
59
+ :domain => 'google.com', :acct => 'lbrinn',
60
+ :passwd => '1234', :authtype => 'tls',
61
+ :subject => "I'm rich and you're not"
62
+ )
63
+
64
+ assert_equal('lbrinn@gmail.com', appender.instance_variable_get(:@from))
65
+ assert_equal(['everyone'], appender.instance_variable_get(:@to))
66
+ assert_equal(1000, appender.auto_flushing)
67
+ assert_equal('1234', appender.instance_variable_get(:@passwd))
68
+ assert_equal([nil, nil, nil, true, true],
69
+ appender.instance_variable_get(:@immediate))
70
+ assert_equal('smtp.google.com', appender.server)
71
+ assert_equal(443, appender.port)
72
+ assert_equal('google.com', appender.domain)
73
+ assert_equal('lbrinn', appender.acct)
74
+ assert_equal(:tls, appender.authtype)
75
+ assert_equal("I'm rich and you're not", appender.subject)
76
+
77
+ appender = Logging.appenders.email('email',
78
+ 'from' => 'me', 'to' => 'you', :auto_flushing => 42
79
+ )
80
+ assert_equal(42, appender.auto_flushing)
81
+ end
82
+
83
+ def test_append
84
+ # with auto_flushing enabled, mail will be sent each time a log event
85
+ # occurs
86
+ @appender.auto_flushing = true
87
+ event = Logging::LogEvent.new('TestLogger', @levels['warn'],
88
+ [1, 2, 3, 4], false)
89
+ @appender.append event
90
+ assert_not_equal(@levels.length, @appender.level)
91
+ assert_equal(0, @appender.buffer.length)
92
+
93
+ # increase the buffer size and log a few events
94
+ @appender.auto_flushing = 3
95
+ @appender.append event
96
+ @appender.append event
97
+ assert_equal(2, @appender.buffer.length)
98
+
99
+ @appender.append event
100
+ assert_not_equal(@levels.length, @appender.level)
101
+ assert_equal(0, @appender.buffer.length)
102
+
103
+ # error and fatal messages should be send immediately (no buffering)
104
+ error = Logging::LogEvent.new('ErrLogger', @levels['error'],
105
+ 'error message', false)
106
+ fatal = Logging::LogEvent.new('FatalLogger', @levels['fatal'],
107
+ 'fatal message', false)
108
+
109
+ @appender.append event
110
+ @appender.append fatal
111
+ assert_not_equal(@levels.length, @appender.level)
112
+ assert_equal(0, @appender.buffer.length)
113
+
114
+ @appender.append error
115
+ assert_not_equal(@levels.length, @appender.level)
116
+ assert_equal(0, @appender.buffer.length)
117
+
118
+ @appender.append event
119
+ assert_equal(1, @appender.buffer.length)
120
+ end
121
+
122
+ def test_concat
123
+ # with auto_flushing enabled, mail will be sent each time a log event
124
+ # occurs
125
+ @appender.auto_flushing = true
126
+ @appender << 'test message'
127
+ assert_not_equal(@levels.length, @appender.level)
128
+ assert_equal(0, @appender.buffer.length)
129
+
130
+ # increase the buffer size and log a few events
131
+ @appender.auto_flushing = 3
132
+ @appender << 'another test message'
133
+ @appender << 'a second test message'
134
+ assert_equal(2, @appender.buffer.length)
135
+
136
+ @appender << 'a third test message'
137
+ assert_not_equal(@levels.length, @appender.level)
138
+ assert_equal(0, @appender.buffer.length)
139
+ end
140
+
141
+ def test_flush
142
+ event = Logging::LogEvent.new('TestLogger', @levels['info'],
143
+ [1, 2, 3, 4], false)
144
+ @appender.append event
145
+ @appender << 'test message'
146
+ assert_equal(2, @appender.buffer.length)
147
+
148
+ @appender.flush
149
+ assert_not_equal(@levels.length, @appender.level)
150
+ assert_equal(0, @appender.buffer.length)
151
+ end
152
+
153
+ def test_close
154
+ event = Logging::LogEvent.new('TestLogger', @levels['info'],
155
+ [1, 2, 3, 4], false)
156
+ @appender.append event
157
+ @appender << 'test message'
158
+ assert_equal(2, @appender.buffer.length)
159
+
160
+ @appender.close
161
+ assert_not_equal(@levels.length, @appender.level)
162
+ assert_equal(0, @appender.buffer.length)
163
+ assert(@appender.closed?)
164
+ end
165
+
166
+ end # class TestEmail
167
+ end # module TestLogging
168
+ end # module TestAppenders
169
+
170
+ # EOF
@@ -0,0 +1,95 @@
1
+
2
+ require File.join(File.dirname(__FILE__), %w[.. setup])
3
+
4
+ module TestLogging
5
+ module TestAppenders
6
+
7
+ class TestFile < Test::Unit::TestCase
8
+ include LoggingTestCase
9
+
10
+ NAME = 'logfile'
11
+
12
+ def setup
13
+ super
14
+ Logging.init
15
+
16
+ FileUtils.mkdir [File.join(TMP, 'dir'), File.join(TMP, 'uw_dir')]
17
+ FileUtils.chmod 0555, File.join(TMP, 'uw_dir')
18
+ FileUtils.touch File.join(TMP, 'uw_file')
19
+ FileUtils.chmod 0444, File.join(TMP, 'uw_file')
20
+ end
21
+
22
+ def test_class_assert_valid_logfile
23
+ log = File.join(TMP, 'uw_dir', 'file.log')
24
+ assert_raise(ArgumentError) do
25
+ Logging.appenders.file.assert_valid_logfile(log)
26
+ end
27
+
28
+ log = File.join(TMP, 'dir')
29
+ assert_raise(ArgumentError) do
30
+ Logging.appenders.file.assert_valid_logfile(log)
31
+ end
32
+
33
+ log = File.join(TMP, 'uw_file')
34
+ assert_raise(ArgumentError) do
35
+ Logging.appenders.file.assert_valid_logfile(log)
36
+ end
37
+
38
+ log = File.join(TMP, 'file.log')
39
+ assert Logging.appenders.file.assert_valid_logfile(log)
40
+ end
41
+
42
+ def test_initialize
43
+ log = File.join(TMP, 'file.log')
44
+ appender = Logging.appenders.file(NAME, 'filename' => log)
45
+ assert_equal 'logfile', appender.name
46
+ assert_equal log, appender.filename
47
+ appender << "This will be the first line\n"
48
+ appender << "This will be the second line\n"
49
+ appender.flush
50
+ File.open(log, 'r') do |file|
51
+ assert_equal "This will be the first line\n", file.readline
52
+ assert_equal "This will be the second line\n", file.readline
53
+ assert_raise(EOFError) {file.readline}
54
+ end
55
+ cleanup
56
+
57
+ appender = Logging.appenders.file(NAME, :filename => log)
58
+ assert_equal 'logfile', appender.name
59
+ assert_equal log, appender.filename
60
+ appender << "This will be the third line\n"
61
+ appender.flush
62
+ File.open(log, 'r') do |file|
63
+ assert_equal "This will be the first line\n", file.readline
64
+ assert_equal "This will be the second line\n", file.readline
65
+ assert_equal "This will be the third line\n", file.readline
66
+ assert_raise(EOFError) {file.readline}
67
+ end
68
+ cleanup
69
+
70
+ appender = Logging.appenders.file(NAME, :filename => log,
71
+ :truncate => true)
72
+ assert_equal 'logfile', appender.name
73
+ appender << "The file was truncated\n"
74
+ appender.flush
75
+ File.open(log, 'r') do |file|
76
+ assert_equal "The file was truncated\n", file.readline
77
+ assert_raise(EOFError) {file.readline}
78
+ end
79
+ cleanup
80
+ end
81
+
82
+ private
83
+ def cleanup
84
+ unless Logging.appenders[NAME].nil?
85
+ Logging.appenders[NAME].close false
86
+ Logging.appenders[NAME] = nil
87
+ end
88
+ end
89
+
90
+ end # class TestFile
91
+
92
+ end # module TestAppenders
93
+ end # module TestLogging
94
+
95
+ # EOF
@@ -0,0 +1,127 @@
1
+
2
+ require File.join(File.dirname(__FILE__), %w[.. setup])
3
+ require 'flexmock'
4
+
5
+ module TestLogging
6
+ module TestAppenders
7
+
8
+ class TestGrowl < Test::Unit::TestCase
9
+ include FlexMock::TestCase
10
+ include LoggingTestCase
11
+
12
+ def setup
13
+ super
14
+
15
+ @appender = Logging.appenders.growl('growl',
16
+ :coalesce => true, :separator => "\000",
17
+ :layout => Logging.layouts.pattern(:pattern => "%5l - Test\000%m")
18
+ )
19
+ @appender.level = :all
20
+ @growl = @appender.instance_variable_get(:@growl).dup
21
+ @levels = Logging::LEVELS
22
+ end
23
+
24
+ def test_initialize
25
+ assert_equal('growlnotify -w -n "growl" -t "%s" -m "%s" -p %d &', @growl)
26
+ assert_equal(true, @appender.instance_variable_get(:@coalesce))
27
+ assert_equal("\000", @appender.instance_variable_get(:@title_sep))
28
+ end
29
+
30
+ def test_append
31
+ info = Logging::LogEvent.new('TestLogger', @levels['info'],
32
+ 'info message', false)
33
+ warn = Logging::LogEvent.new('TestLogger', @levels['warn'],
34
+ 'warning message', false)
35
+
36
+ flexmock(@appender).should_receive(:system => true).once.with(
37
+ @growl % ['WARN - Test', "warning message\nwarning message\nwarning message", 0])
38
+
39
+ flexmock(@appender).should_receive(:system => true).once.with(
40
+ @growl % ['INFO - Test', "info message\ninfo message", -1])
41
+
42
+ flexmock(@appender).should_receive(:system => true).once.with(
43
+ @growl % ['WARN - Test', "warning message", 0])
44
+
45
+ @appender.append warn
46
+ @appender.append warn
47
+ @appender.append warn
48
+ @appender.append info
49
+ @appender.append info
50
+ @appender.append warn
51
+ sleep 0.7 # give the coalescing thread time to run
52
+ end
53
+
54
+ def test_append_without_coalescing
55
+ @appender.instance_variable_set(:@coalesce, false)
56
+ event = Logging::LogEvent.new('TestLogger', @levels['warn'],
57
+ 'warning message', false)
58
+
59
+ flexmock(@appender).should_receive(:system => true).twice.with(
60
+ @growl % ['WARN - Test', 'warning message', 0])
61
+
62
+ @appender.append event
63
+ @appender.append event
64
+ end
65
+
66
+ def test_concat
67
+ flexmock(@appender).should_receive(:system => true).once.with(
68
+ @growl % ['', "first message\nsecond message\nthird message", 0])
69
+
70
+ @appender << 'first message'
71
+ @appender << 'second message'
72
+ @appender << 'third message'
73
+ sleep 0.7 # give the coalescing thread time to run
74
+ end
75
+
76
+ def test_concat_without_coalescing
77
+ @appender.instance_variable_set(:@coalesce, false)
78
+
79
+ flexmock(@appender).should_receive(:system => true).twice.with(
80
+ @growl % ['', 'concat message', 0])
81
+
82
+ @appender << 'concat message'
83
+ @appender << 'concat message'
84
+ end
85
+
86
+ def test_map_eq
87
+ get_map = lambda {@appender.instance_variable_get(:@map)}
88
+ assert_equal([-2,-1,0,1,2], get_map.call)
89
+
90
+ @appender.map = {
91
+ 'fatal' => '0',
92
+ :error => -2,
93
+ :warn => '2',
94
+ 'INFO' => 1,
95
+ 'Debug' => -1
96
+ }
97
+ assert_equal([-1,1,2,-2,0], get_map.call)
98
+
99
+ assert_raise(ArgumentError) do
100
+ @appender.map = {:fatal => 'not a number', :error => 2}
101
+ end
102
+
103
+ assert_raise(ArgumentError) do
104
+ @appender.map = {:fatal => -3, :error => 3}
105
+ end
106
+ end
107
+
108
+ def test_disabling
109
+ @appender.instance_variable_set(:@coalesce, false)
110
+ event = Logging::LogEvent.new('TestLogger', @levels['warn'],
111
+ 'warning message', false)
112
+
113
+ flexmock(@appender).should_receive(:system => false).once.with(
114
+ @growl % ['WARN - Test', 'warning message', 0])
115
+
116
+ assert_equal 0, @appender.level
117
+ @appender.append event
118
+ assert_equal 5, @appender.level
119
+ @appender.append event
120
+ @appender.append event
121
+ end
122
+
123
+ end # class TestGrowl
124
+ end # module TestLogging
125
+ end # module TestAppenders
126
+
127
+ # EOF
@@ -0,0 +1,129 @@
1
+
2
+ require File.join(File.dirname(__FILE__), %w[.. setup])
3
+
4
+ module TestLogging
5
+ module TestAppenders
6
+
7
+ class TestIO < Test::Unit::TestCase
8
+ include LoggingTestCase
9
+
10
+ def setup
11
+ super
12
+
13
+ @appender = Logging.appenders.string_io('test_appender')
14
+ @sio = @appender.sio
15
+ @levels = Logging::LEVELS
16
+ end
17
+
18
+ def test_append
19
+ event = Logging::LogEvent.new('TestLogger', @levels['warn'],
20
+ [1, 2, 3, 4], false)
21
+ @appender.append event
22
+ assert_equal " WARN TestLogger : <Array> #{[1, 2, 3, 4]}\n", readline
23
+ assert_nil(readline)
24
+
25
+ event.level = @levels['debug']
26
+ event.data = 'the big log message'
27
+ @appender.append event
28
+ assert_equal "DEBUG TestLogger : the big log message\n", readline
29
+ assert_nil(readline)
30
+
31
+ @appender.close
32
+ assert_raise(RuntimeError) {@appender.append event}
33
+ end
34
+
35
+ def test_append_error
36
+ # setup an internal logger to capture error messages from the IO
37
+ # appender
38
+ log = Logging.appenders.string_io('__internal_io')
39
+ Logging.logger[Logging].add_appenders(log)
40
+ Logging.logger[Logging].level = 'all'
41
+
42
+ # close the string IO object so we get an error
43
+ @sio.close
44
+ event = Logging::LogEvent.new('TestLogger', @levels['warn'],
45
+ [1, 2, 3, 4], false)
46
+ @appender.append event
47
+
48
+ assert_equal "INFO Logging : appender \"test_appender\" has been disabled", log.readline.strip
49
+ assert_equal "ERROR Logging : <IOError> not opened for writing", log.readline.strip
50
+
51
+ assert_equal false, @appender.closed?
52
+ assert_equal 5, @appender.level
53
+ end
54
+
55
+ def test_close
56
+ assert_equal false, @sio.closed?
57
+ assert_equal false, @appender.closed?
58
+
59
+ @appender.close
60
+ assert_equal true, @sio.closed?
61
+ assert_equal true, @appender.closed?
62
+
63
+ [STDIN, STDERR, STDOUT].each do |io|
64
+ @appender = Logging.appenders.io('test', io)
65
+ @appender.close
66
+ assert_equal false, io.closed?
67
+ assert_equal true, @appender.closed?
68
+ end
69
+ end
70
+
71
+ def test_concat
72
+ @appender << "this is a test message\n"
73
+ assert_equal "this is a test message\n", readline
74
+ assert_nil(readline)
75
+
76
+ @appender << "this is another message\n"
77
+ @appender << "some other line\n"
78
+ assert_equal "this is another message\n", readline
79
+ assert_equal "some other line\n", readline
80
+ assert_nil(readline)
81
+
82
+ @appender.close
83
+ assert_raise(RuntimeError) {@appender << 'message'}
84
+ end
85
+
86
+ def test_concat_error
87
+ # setup an internal logger to capture error messages from the IO
88
+ # appender
89
+ log = Logging.appenders.string_io('__internal_io')
90
+ Logging.logger[Logging].add_appenders(log)
91
+ Logging.logger[Logging].level = 'all'
92
+
93
+ # close the string IO object so we get an error
94
+ @sio.close
95
+ @appender << 'oopsy'
96
+
97
+ assert_equal "INFO Logging : appender \"test_appender\" has been disabled", log.readline.strip
98
+ assert_equal "ERROR Logging : <IOError> not opened for writing", log.readline.strip
99
+
100
+ # and the appender does not close itself
101
+ assert_equal false, @appender.closed?
102
+ assert_equal 5, @appender.level
103
+ end
104
+
105
+ def test_flush
106
+ ary = []
107
+ @sio.instance_variable_set :@ary, ary
108
+ def @sio.flush() @ary << :flush end
109
+
110
+ @appender.flush
111
+ assert_equal :flush, ary.pop
112
+ end
113
+
114
+ def test_initialize
115
+ assert_raise(EOFError) {@sio.readline}
116
+ assert_raise(TypeError) {Logging.appenders.io('test', [])}
117
+ end
118
+
119
+ private
120
+ def readline
121
+ @appender.readline
122
+ end
123
+
124
+ end # class TestIO
125
+
126
+ end # module TestAppenders
127
+ end # module TestLogging
128
+
129
+ # EOF