filterfish-logging 0.9.8

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 (55) hide show
  1. data/History.txt +176 -0
  2. data/Manifest.txt +54 -0
  3. data/README.txt +93 -0
  4. data/Rakefile +28 -0
  5. data/data/logging.yaml +63 -0
  6. data/lib/logging.rb +288 -0
  7. data/lib/logging/appender.rb +257 -0
  8. data/lib/logging/appenders/console.rb +43 -0
  9. data/lib/logging/appenders/email.rb +131 -0
  10. data/lib/logging/appenders/file.rb +55 -0
  11. data/lib/logging/appenders/growl.rb +182 -0
  12. data/lib/logging/appenders/io.rb +81 -0
  13. data/lib/logging/appenders/rolling_file.rb +293 -0
  14. data/lib/logging/appenders/syslog.rb +202 -0
  15. data/lib/logging/config/yaml_configurator.rb +197 -0
  16. data/lib/logging/layout.rb +103 -0
  17. data/lib/logging/layouts/basic.rb +35 -0
  18. data/lib/logging/layouts/pattern.rb +292 -0
  19. data/lib/logging/log_event.rb +50 -0
  20. data/lib/logging/logger.rb +388 -0
  21. data/lib/logging/repository.rb +151 -0
  22. data/lib/logging/root_logger.rb +60 -0
  23. data/lib/logging/utils.rb +44 -0
  24. data/tasks/ann.rake +78 -0
  25. data/tasks/bones.rake +21 -0
  26. data/tasks/gem.rake +106 -0
  27. data/tasks/manifest.rake +49 -0
  28. data/tasks/notes.rake +22 -0
  29. data/tasks/post_load.rake +37 -0
  30. data/tasks/rdoc.rake +49 -0
  31. data/tasks/rubyforge.rake +57 -0
  32. data/tasks/setup.rb +253 -0
  33. data/tasks/svn.rake +45 -0
  34. data/tasks/test.rake +38 -0
  35. data/test/appenders/test_console.rb +40 -0
  36. data/test/appenders/test_email.rb +167 -0
  37. data/test/appenders/test_file.rb +94 -0
  38. data/test/appenders/test_growl.rb +115 -0
  39. data/test/appenders/test_io.rb +113 -0
  40. data/test/appenders/test_rolling_file.rb +187 -0
  41. data/test/appenders/test_syslog.rb +192 -0
  42. data/test/benchmark.rb +88 -0
  43. data/test/config/test_yaml_configurator.rb +41 -0
  44. data/test/layouts/test_basic.rb +44 -0
  45. data/test/layouts/test_pattern.rb +173 -0
  46. data/test/setup.rb +66 -0
  47. data/test/test_appender.rb +162 -0
  48. data/test/test_layout.rb +85 -0
  49. data/test/test_log_event.rb +81 -0
  50. data/test/test_logger.rb +589 -0
  51. data/test/test_logging.rb +250 -0
  52. data/test/test_repository.rb +123 -0
  53. data/test/test_root_logger.rb +82 -0
  54. data/test/test_utils.rb +48 -0
  55. metadata +126 -0
@@ -0,0 +1,113 @@
1
+ # $Id$
2
+
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
4
+
5
+ module TestLogging
6
+ module TestAppenders
7
+
8
+ class TestIO < Test::Unit::TestCase
9
+ include LoggingTestCase
10
+
11
+ def setup
12
+ super
13
+ ::Logging.init
14
+ @levels = ::Logging::LEVELS
15
+
16
+ @sio = StringIO.new
17
+ @appender = ::Logging::Appenders::IO.new 'test_appender', @sio
18
+ begin readline rescue EOFError end
19
+ end
20
+
21
+ def test_append
22
+ event = ::Logging::LogEvent.new('TestLogger', @levels['warn'],
23
+ [1, 2, 3, 4], false)
24
+ @appender.append event
25
+ assert_equal " WARN TestLogger : <Array> #{[1, 2, 3, 4]}\n", readline
26
+ assert_raise(EOFError) {readline}
27
+
28
+ event.level = @levels['debug']
29
+ event.data = 'the big log message'
30
+ @appender.append event
31
+ assert_equal "DEBUG TestLogger : the big log message\n", readline
32
+ assert_raise(EOFError) {readline}
33
+
34
+ @appender.close
35
+ assert_raise(RuntimeError) {@appender.append event}
36
+ end
37
+
38
+ def test_append_error
39
+ @sio.close
40
+ event = ::Logging::LogEvent.new('TestLogger', @levels['warn'],
41
+ [1, 2, 3, 4], false)
42
+ assert_raise(IOError) {@appender.append event}
43
+ assert_equal false, @appender.closed?
44
+ assert_equal 5, @appender.level
45
+ end
46
+
47
+ def test_close
48
+ assert_equal false, @sio.closed?
49
+ assert_equal false, @appender.closed?
50
+
51
+ @appender.close
52
+ assert_equal true, @sio.closed?
53
+ assert_equal true, @appender.closed?
54
+
55
+ [STDIN, STDERR, STDOUT].each do |io|
56
+ @appender = ::Logging::Appenders::IO.new 'test', io
57
+ @appender.close
58
+ assert_equal false, io.closed?
59
+ assert_equal true, @appender.closed?
60
+ end
61
+ end
62
+
63
+ def test_concat
64
+ @appender << "this is a test message\n"
65
+ assert_equal "this is a test message\n", readline
66
+ assert_raise(EOFError) {readline}
67
+
68
+ @appender << "this is another message\n"
69
+ @appender << "some other line\n"
70
+ assert_equal "this is another message\n", readline
71
+ assert_equal "some other line\n", readline
72
+ assert_raise(EOFError) {readline}
73
+
74
+ @appender.close
75
+ assert_raise(RuntimeError) {@appender << 'message'}
76
+ end
77
+
78
+ def test_concat_error
79
+ @sio.close
80
+ assert_raise(IOError) {@appender << 'oopsy'}
81
+ assert_equal false, @appender.closed?
82
+ assert_equal 5, @appender.level
83
+ end
84
+
85
+ def test_flush
86
+ ary = []
87
+ @sio.instance_variable_set :@ary, ary
88
+ def @sio.flush() @ary << :flush end
89
+
90
+ @appender.flush
91
+ assert_equal :flush, ary.pop
92
+ end
93
+
94
+ def test_initialize
95
+ assert_raise(EOFError) {@sio.readline}
96
+ assert_raise(TypeError) {::Logging::Appenders::IO.new 'test', []}
97
+ end
98
+
99
+ private
100
+ def readline
101
+ @pos ||= 0
102
+ @sio.seek @pos
103
+ line = @sio.readline
104
+ @pos = @sio.tell
105
+ line
106
+ end
107
+
108
+ end # class TestIO
109
+
110
+ end # module TestAppenders
111
+ end # module TestLogging
112
+
113
+ # EOF
@@ -0,0 +1,187 @@
1
+ # $Id$
2
+
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
4
+
5
+ module TestLogging
6
+ module TestAppenders
7
+
8
+ class TestRollingFile < Test::Unit::TestCase
9
+ include LoggingTestCase
10
+
11
+ NAME = 'roller'
12
+
13
+ def setup
14
+ super
15
+ ::Logging.init
16
+
17
+ @fn = File.join(TMP, 'test.log')
18
+ @fn_fmt = File.join(TMP, 'test.%d.log')
19
+ @glob = File.join(TMP, '*.log')
20
+ end
21
+
22
+ def test_initialize
23
+ assert_equal [], Dir.glob(@glob)
24
+
25
+ # create a new appender
26
+ ap = ::Logging::Appenders::RollingFile.new(NAME, :filename => @fn)
27
+ assert File.exist?(@fn)
28
+ assert_equal 0, File.size(@fn)
29
+
30
+ ap << "Just a line of text\n" # 20 bytes
31
+ ap.flush
32
+ assert_equal 20, File.size(@fn)
33
+ cleanup
34
+
35
+ # make sure we append to the current file (not truncate)
36
+ ap = ::Logging::Appenders::RollingFile.new(NAME, :filename => @fn)
37
+ assert_equal [@fn], Dir.glob(@glob)
38
+ assert_equal 20, File.size(@fn)
39
+
40
+ ap << "Just another line of text\n" # 26 bytes
41
+ ap.flush
42
+ assert_equal 46, File.size(@fn)
43
+ cleanup
44
+
45
+ # setting the truncate option to true should roll the current log file
46
+ # and create a new one
47
+ ap = ::Logging::Appenders::RollingFile.new(NAME,
48
+ :filename => @fn, :truncate => true)
49
+
50
+ log1 = sprintf(@fn_fmt, 1)
51
+ assert_equal [log1, @fn], Dir.glob(@glob).sort
52
+ assert_equal 0, File.size(@fn)
53
+ assert_equal 46, File.size(log1)
54
+
55
+ ap << "Some more text in the new file\n" # 31 bytes
56
+ ap.flush
57
+ assert_equal 31, File.size(@fn)
58
+ cleanup
59
+ end
60
+
61
+ def test_keep
62
+ assert_equal [], Dir.glob(@glob)
63
+
64
+ (1..12).each do |cnt|
65
+ name = sprintf(@fn_fmt, cnt)
66
+ File.open(name,'w') {|fd| fd.write 'X'*cnt}
67
+ end
68
+ FileUtils.touch(@fn)
69
+
70
+ # keep only five files
71
+ ap = ::Logging::Appenders::RollingFile.new(NAME,
72
+ :filename => @fn, :keep => 5)
73
+
74
+ # we still have 13 files because we did not truncate the log file,
75
+ # and hence, we did not roll all the log files
76
+ assert_equal 13, Dir.glob(@glob).length
77
+
78
+ # force the appender to roll the files
79
+ ap.send :roll
80
+ assert_equal 6, Dir.glob(@glob).length
81
+
82
+ (1..5).each do |cnt|
83
+ name = sprintf(@fn_fmt, cnt)
84
+ assert_equal cnt-1, File.size(name)
85
+ end
86
+ cleanup
87
+ end
88
+
89
+ def test_age
90
+ assert_equal [], Dir.glob(@glob)
91
+
92
+ assert_raise(ArgumentError) do
93
+ ::Logging::Appenders::RollingFile.new(
94
+ NAME, :filename => @fn, :age => 'bob')
95
+ end
96
+
97
+ ap = ::Logging::Appenders::RollingFile.new(NAME,
98
+ :filename => @fn, :age => 1)
99
+ ap << "random message\n"
100
+ assert_equal 1, Dir.glob(@glob).length
101
+
102
+ sleep 1.250
103
+ ap << "another random message\n"
104
+ assert_equal 2, Dir.glob(@glob).length
105
+
106
+ cleanup
107
+ ap = ::Logging::Appenders::RollingFile.new(NAME,
108
+ :filename => @fn, 'age' => 'daily')
109
+ ap << "random message\n"
110
+ assert_equal 2, Dir.glob(@glob).length
111
+
112
+ age_fn = @fn + '.age'
113
+ now = ::File.mtime(age_fn)
114
+ start = now - 3600 * 24
115
+ ::File.utime(start, start, age_fn)
116
+
117
+ sleep 0.250
118
+ ap << "yet another random message\n"
119
+ assert_equal 3, Dir.glob(@glob).length
120
+
121
+ cleanup
122
+ ap = ::Logging::Appenders::RollingFile.new(NAME,
123
+ :filename => @fn, :age => 'weekly')
124
+ ap << "random message\n"
125
+ assert_equal 3, Dir.glob(@glob).length
126
+
127
+ start = now - 3600 * 24 * 7
128
+ ::File.utime(start, start, age_fn)
129
+
130
+ sleep 0.250
131
+ ap << "yet another random message\n"
132
+ assert_equal 4, Dir.glob(@glob).length
133
+
134
+ cleanup
135
+ ap = ::Logging::Appenders::RollingFile.new(NAME,
136
+ :filename => @fn, :age => 'monthly')
137
+ ap << "random message\n"
138
+ assert_equal 4, Dir.glob(@glob).length
139
+
140
+ start = now - 3600 * 24 * 31
141
+ ::File.utime(start, start, age_fn)
142
+
143
+ sleep 0.250
144
+ ap << "yet another random message\n"
145
+ assert_equal 5, Dir.glob(@glob).length
146
+ end
147
+
148
+ def test_size
149
+ assert_equal [], Dir.glob(@glob)
150
+
151
+ ap = ::Logging::Appenders::RollingFile.new(NAME,
152
+ :filename => @fn, :size => 100)
153
+
154
+ ap << 'X' * 100; ap.flush
155
+ assert_equal 1, Dir.glob(@glob).length
156
+ assert_equal 100, File.size(@fn)
157
+
158
+ # this character is appended to the log file (bringing its size to 101)
159
+ # and THEN the file is rolled resulting in a new, empty log file
160
+ ap << 'X'
161
+ assert_equal 2, Dir.glob(@glob).length
162
+ assert_equal 0, File.size(@fn)
163
+
164
+ ap << 'X' * 100; ap.flush
165
+ assert_equal 2, Dir.glob(@glob).length
166
+ assert_equal 100, File.size(@fn)
167
+
168
+ ap << 'X'
169
+ assert_equal 3, Dir.glob(@glob).length
170
+ assert_equal 0, File.size(@fn)
171
+
172
+ cleanup
173
+ end
174
+
175
+ private
176
+ def cleanup
177
+ unless ::Logging::Appender[NAME].nil?
178
+ ::Logging::Appender[NAME].close false
179
+ ::Logging::Appender[NAME] = nil
180
+ end
181
+ end
182
+
183
+ end # class TestRollingFile
184
+ end # module TestAppenders
185
+ end # module TestLogging
186
+
187
+ # EOF
@@ -0,0 +1,192 @@
1
+ # $Id$
2
+
3
+ require File.join(File.dirname(__FILE__), %w[.. setup])
4
+
5
+ if HAVE_SYSLOG
6
+
7
+ module TestLogging
8
+ module TestAppenders
9
+
10
+ class TestSyslog < Test::Unit::TestCase
11
+ include LoggingTestCase
12
+ include ::Syslog::Constants
13
+
14
+ def setup
15
+ super
16
+ ::Logging.init
17
+ @levels = ::Logging::LEVELS
18
+ end
19
+
20
+ def test_append
21
+ return if RUBY_PLATFORM =~ %r/cygwin/
22
+
23
+ stderr = IO::pipe
24
+
25
+ pid = fork do
26
+ stderr[0].close
27
+ STDERR.reopen(stderr[1])
28
+ stderr[1].close
29
+
30
+ appender = create_syslog
31
+ event = ::Logging::LogEvent.new('TestLogger', @levels['info'],
32
+ [1, 2, 3, 4], false)
33
+ appender.append event
34
+ event.level = @levels['debug']
35
+ event.data = 'the big log message'
36
+ appender.append event
37
+
38
+ appender.level = :warn
39
+ event.level = @levels['info']
40
+ event.data = 'this message should not get logged'
41
+ appender.append event
42
+ event.level = @levels['warn']
43
+ event.data = 'this is your last warning'
44
+ appender.append event
45
+
46
+ exit!
47
+ end
48
+
49
+ stderr[1].close
50
+ Process.waitpid(pid)
51
+
52
+ assert_equal("syslog_test: INFO TestLogger : <Array> #{[1,2,3,4]}\n",
53
+ stderr[0].gets)
54
+ assert_equal("syslog_test: DEBUG TestLogger : the big log message\n",
55
+ stderr[0].gets)
56
+ assert_equal("syslog_test: WARN TestLogger : this is your last warning\n",
57
+ stderr[0].gets)
58
+ end
59
+
60
+ def test_append_error
61
+ appender = create_syslog
62
+ appender.close false
63
+
64
+ event = ::Logging::LogEvent.new('TestLogger', @levels['warn'],
65
+ [1, 2, 3, 4], false)
66
+ assert_raise(RuntimeError) {appender.append event}
67
+ assert_equal true, appender.closed?
68
+ end
69
+
70
+ def test_close
71
+ appender = create_syslog
72
+ assert_equal false, appender.closed?
73
+
74
+ appender.close false
75
+ assert_equal true, appender.closed?
76
+ end
77
+
78
+ def test_concat
79
+ return if RUBY_PLATFORM =~ %r/cygwin/
80
+
81
+ stderr = IO::pipe
82
+
83
+ pid = fork do
84
+ stderr[0].close
85
+ STDERR.reopen(stderr[1])
86
+ stderr[1].close
87
+
88
+ appender = create_syslog
89
+ appender << 'this is a test message'
90
+ appender << 'this is another message'
91
+ appender << 'some other line'
92
+
93
+ exit!
94
+ end
95
+
96
+ stderr[1].close
97
+ Process.waitpid(pid)
98
+
99
+ assert_equal("syslog_test: this is a test message\n", stderr[0].gets)
100
+ assert_equal("syslog_test: this is another message\n", stderr[0].gets)
101
+ assert_equal("syslog_test: some other line\n", stderr[0].gets)
102
+ end
103
+
104
+ def test_concat_error
105
+ appender = create_syslog
106
+ appender.close false
107
+
108
+ assert_raise(RuntimeError) {appender << 'oopsy'}
109
+ assert_equal true, appender.closed?
110
+ end
111
+
112
+ def test_map_eq
113
+ appender = create_syslog
114
+
115
+ assert_equal(
116
+ [LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_CRIT],
117
+ get_map_from(appender)
118
+ )
119
+
120
+ appender.map = {
121
+ :debug => LOG_DEBUG,
122
+ :info => 'LOG_NOTICE',
123
+ :warn => :LOG_WARNING,
124
+ :error => 'log_err',
125
+ :fatal => :log_alert
126
+ }
127
+
128
+ assert_equal(
129
+ [LOG_DEBUG, LOG_NOTICE, LOG_WARNING, LOG_ERR, LOG_ALERT],
130
+ get_map_from(appender)
131
+ )
132
+ end
133
+
134
+ def test_map_eq_error
135
+ appender = create_syslog
136
+
137
+ # Object is not a valid syslog level
138
+ assert_raise(ArgumentError) do
139
+ appender.map = {:debug => Object}
140
+ end
141
+
142
+ # there is no syslog level named "info"
143
+ # it should be "log_info"
144
+ assert_raise(NameError) do
145
+ appender.map = {:info => 'lg_info'}
146
+ end
147
+ end
148
+
149
+ def test_initialize_map
150
+ appender = ::Logging::Appenders::Syslog.new(
151
+ 'syslog_test',
152
+ :logopt => ::Syslog::LOG_PERROR | ::Syslog::LOG_NDELAY,
153
+ :map => {
154
+ :debug => :log_debug,
155
+ :info => :log_info,
156
+ :warn => :log_warning,
157
+ :error => :log_err,
158
+ :fatal => :log_alert
159
+ }
160
+ )
161
+
162
+ assert_equal(
163
+ [LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_ALERT],
164
+ get_map_from(appender)
165
+ )
166
+ end
167
+
168
+
169
+ private
170
+
171
+ def create_syslog
172
+ layout = ::Logging::Layouts::Pattern.new(:pattern => '%5l %c : %m')
173
+ ::Logging::Appenders::Syslog.new(
174
+ 'syslog_test',
175
+ :logopt => ::Syslog::LOG_PERROR | ::Syslog::LOG_NDELAY,
176
+ :facility => ::Syslog::LOG_USER,
177
+ :layout => layout
178
+ )
179
+ end
180
+
181
+ def get_map_from( syslog )
182
+ syslog.instance_variable_get :@map
183
+ end
184
+
185
+ end # class TestIO
186
+
187
+ end # module TestAppenders
188
+ end # module TestLogging
189
+
190
+ end # HAVE_SYSLOG
191
+
192
+ # EOF