sgeorgi-logging 1.4.2

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