pjstadig-logging 1.1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/History.txt +219 -0
  2. data/README.rdoc +115 -0
  3. data/Rakefile +43 -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/formatting.rb +51 -0
  13. data/examples/hierarchies.rb +73 -0
  14. data/examples/layouts.rb +48 -0
  15. data/examples/loggers.rb +29 -0
  16. data/examples/names.rb +43 -0
  17. data/examples/simple.rb +17 -0
  18. data/lib/logging.rb +479 -0
  19. data/lib/logging/appender.rb +251 -0
  20. data/lib/logging/appenders.rb +120 -0
  21. data/lib/logging/appenders/buffering.rb +168 -0
  22. data/lib/logging/appenders/console.rb +60 -0
  23. data/lib/logging/appenders/email.rb +75 -0
  24. data/lib/logging/appenders/file.rb +58 -0
  25. data/lib/logging/appenders/growl.rb +197 -0
  26. data/lib/logging/appenders/io.rb +69 -0
  27. data/lib/logging/appenders/rolling_file.rb +293 -0
  28. data/lib/logging/appenders/string_io.rb +68 -0
  29. data/lib/logging/appenders/syslog.rb +194 -0
  30. data/lib/logging/config/configurator.rb +188 -0
  31. data/lib/logging/config/yaml_configurator.rb +191 -0
  32. data/lib/logging/layout.rb +117 -0
  33. data/lib/logging/layouts.rb +47 -0
  34. data/lib/logging/layouts/basic.rb +32 -0
  35. data/lib/logging/layouts/parseable.rb +211 -0
  36. data/lib/logging/layouts/pattern.rb +312 -0
  37. data/lib/logging/log_event.rb +51 -0
  38. data/lib/logging/logger.rb +503 -0
  39. data/lib/logging/repository.rb +210 -0
  40. data/lib/logging/root_logger.rb +61 -0
  41. data/lib/logging/stats.rb +278 -0
  42. data/lib/logging/utils.rb +207 -0
  43. data/lib/spec/logging_helper.rb +34 -0
  44. data/test/appenders/test_buffered_io.rb +176 -0
  45. data/test/appenders/test_console.rb +66 -0
  46. data/test/appenders/test_email.rb +170 -0
  47. data/test/appenders/test_file.rb +95 -0
  48. data/test/appenders/test_growl.rb +127 -0
  49. data/test/appenders/test_io.rb +129 -0
  50. data/test/appenders/test_rolling_file.rb +200 -0
  51. data/test/appenders/test_syslog.rb +194 -0
  52. data/test/benchmark.rb +86 -0
  53. data/test/config/test_configurator.rb +70 -0
  54. data/test/config/test_yaml_configurator.rb +40 -0
  55. data/test/layouts/test_basic.rb +42 -0
  56. data/test/layouts/test_json.rb +112 -0
  57. data/test/layouts/test_pattern.rb +198 -0
  58. data/test/layouts/test_yaml.rb +121 -0
  59. data/test/setup.rb +73 -0
  60. data/test/test_appender.rb +152 -0
  61. data/test/test_consolidate.rb +46 -0
  62. data/test/test_layout.rb +110 -0
  63. data/test/test_log_event.rb +80 -0
  64. data/test/test_logger.rb +699 -0
  65. data/test/test_logging.rb +267 -0
  66. data/test/test_repository.rb +158 -0
  67. data/test/test_root_logger.rb +81 -0
  68. data/test/test_stats.rb +274 -0
  69. data/test/test_utils.rb +116 -0
  70. metadata +175 -0
@@ -0,0 +1,200 @@
1
+
2
+ require File.join(File.dirname(__FILE__), %w[.. setup])
3
+
4
+ module TestLogging
5
+ module TestAppenders
6
+
7
+ class TestRollingFile < Test::Unit::TestCase
8
+ include LoggingTestCase
9
+
10
+ NAME = 'roller'
11
+
12
+ def setup
13
+ super
14
+ Logging.init
15
+
16
+ @fn = File.join(TMP, 'test.log')
17
+ @fn_fmt = File.join(TMP, 'test.%d.log')
18
+ @glob = File.join(TMP, '*.log')
19
+ end
20
+
21
+ def test_initialize
22
+ assert_equal [], Dir.glob(@glob)
23
+
24
+ # create a new appender
25
+ ap = Logging.appenders.rolling_file(NAME, :filename => @fn)
26
+ assert_equal @fn, ap.filename
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.rolling_file(NAME, :filename => @fn)
37
+ assert_equal @fn, ap.filename
38
+ assert_equal [@fn], Dir.glob(@glob)
39
+ assert_equal 20, File.size(@fn)
40
+
41
+ ap << "Just another line of text\n" # 26 bytes
42
+ ap.flush
43
+ assert_equal 46, File.size(@fn)
44
+ cleanup
45
+
46
+ # setting the truncate option to true should roll the current log file
47
+ # and create a new one
48
+ ap = Logging.appenders.rolling_file(NAME, :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.rolling_file(NAME, :filename => @fn, :keep => 5)
72
+
73
+ # we still have 13 files because we did not truncate the log file,
74
+ # and hence, we did not roll all the log files
75
+ assert_equal 13, Dir.glob(@glob).length
76
+
77
+ # force the appender to roll the files
78
+ ap.send :roll
79
+ assert_equal 6, Dir.glob(@glob).length
80
+
81
+ (1..5).each do |cnt|
82
+ name = sprintf(@fn_fmt, cnt)
83
+ assert_equal cnt-1, File.size(name)
84
+ end
85
+ cleanup
86
+ end
87
+
88
+ def test_age
89
+ assert_equal [], Dir.glob(@glob)
90
+
91
+ assert_raise(ArgumentError) do
92
+ Logging.appenders.rolling_file(NAME, :filename => @fn, :age => 'bob')
93
+ end
94
+
95
+ ap = Logging.appenders.rolling_file(NAME, :filename => @fn, :age => 1)
96
+ ap << "random message\n"
97
+ assert_equal 1, Dir.glob(@glob).length
98
+
99
+ sleep 1.250
100
+ ap << "another random message\n"
101
+ assert_equal 2, Dir.glob(@glob).length
102
+
103
+ cleanup
104
+ ap = Logging.appenders.rolling_file(NAME, :filename => @fn, 'age' => 'daily')
105
+ ap << "random message\n"
106
+ assert_equal 2, Dir.glob(@glob).length
107
+
108
+ age_fn = @fn + '.age'
109
+ now = ::File.mtime(age_fn)
110
+ start = now - 3600 * 24
111
+ ::File.utime(start, start, age_fn)
112
+
113
+ sleep 0.250
114
+ ap << "yet another random message\n"
115
+ assert_equal 3, Dir.glob(@glob).length
116
+
117
+ cleanup
118
+ ap = Logging.appenders.rolling_file(NAME, :filename => @fn, :age => 'weekly')
119
+ ap << "random message\n"
120
+ assert_equal 3, Dir.glob(@glob).length
121
+
122
+ start = now - 3600 * 24 * 7
123
+ ::File.utime(start, start, age_fn)
124
+
125
+ sleep 0.250
126
+ ap << "yet another random message\n"
127
+ assert_equal 4, Dir.glob(@glob).length
128
+
129
+ cleanup
130
+ ap = Logging.appenders.rolling_file(NAME, :filename => @fn, :age => 'monthly')
131
+ ap << "random message\n"
132
+ assert_equal 4, Dir.glob(@glob).length
133
+
134
+ start = now - 3600 * 24 * 31
135
+ ::File.utime(start, start, age_fn)
136
+
137
+ sleep 0.250
138
+ ap << "yet another random message\n"
139
+ assert_equal 5, Dir.glob(@glob).length
140
+ end
141
+
142
+ def test_size
143
+ assert_equal [], Dir.glob(@glob)
144
+
145
+ ap = Logging.appenders.rolling_file(NAME, :filename => @fn, :size => 100)
146
+
147
+ ap << 'X' * 100; ap.flush
148
+ assert_equal 1, Dir.glob(@glob).length
149
+ assert_equal 100, File.size(@fn)
150
+
151
+ # this character is appended to the log file (bringing its size to 101)
152
+ # and THEN the file is rolled resulting in a new, empty log file
153
+ ap << 'X'
154
+ assert_equal 2, Dir.glob(@glob).length
155
+ assert_equal 0, File.size(@fn)
156
+
157
+ ap << 'X' * 100; ap.flush
158
+ assert_equal 2, Dir.glob(@glob).length
159
+ assert_equal 100, File.size(@fn)
160
+
161
+ ap << 'X'
162
+ assert_equal 3, Dir.glob(@glob).length
163
+ assert_equal 0, File.size(@fn)
164
+
165
+ cleanup
166
+ end
167
+
168
+ def test_file_removed
169
+ assert_equal [], Dir.glob(@glob)
170
+
171
+ ap = Logging.appenders.rolling_file(NAME, :filename => @fn, :size => 100)
172
+
173
+ ap << 'X' * 100; ap.flush
174
+ assert_equal 1, Dir.glob(@glob).length
175
+ assert_equal 100, File.size(@fn)
176
+
177
+ # Now remove @fn and make sure that the log file is written to
178
+ # again
179
+ File.unlink(@fn)
180
+ assert_equal 0, Dir.glob(@glob).length
181
+
182
+ ap << 'X' * 50; ap.flush
183
+ assert_equal 1, Dir.glob(@glob).length
184
+ assert_equal 50, File.size(@fn)
185
+
186
+ end
187
+
188
+ private
189
+ def cleanup
190
+ unless Logging.appenders[NAME].nil?
191
+ Logging.appenders[NAME].close false
192
+ Logging.appenders[NAME] = nil
193
+ end
194
+ end
195
+
196
+ end # class TestRollingFile
197
+ end # module TestAppenders
198
+ end # module TestLogging
199
+
200
+ # EOF
@@ -0,0 +1,194 @@
1
+
2
+ require File.join(File.dirname(__FILE__), %w[.. setup])
3
+
4
+ if HAVE_SYSLOG
5
+
6
+ module TestLogging
7
+ module TestAppenders
8
+
9
+ class TestSyslog < Test::Unit::TestCase
10
+ include LoggingTestCase
11
+ include ::Syslog::Constants
12
+
13
+ def setup
14
+ super
15
+ Logging.init
16
+ @levels = Logging::LEVELS
17
+ @logopt = defined?(::Syslog::LOG_NDELAY) ?
18
+ (::Syslog::LOG_PERROR | ::Syslog::LOG_NDELAY) :
19
+ (::Syslog::LOG_PERROR)
20
+ end
21
+
22
+ def test_append
23
+ return if RUBY_PLATFORM =~ %r/cygwin/
24
+
25
+ stderr = IO::pipe
26
+
27
+ pid = fork do
28
+ stderr[0].close
29
+ STDERR.reopen(stderr[1])
30
+ stderr[1].close
31
+
32
+ appender = create_syslog
33
+ event = Logging::LogEvent.new('TestLogger', @levels['info'],
34
+ [1, 2, 3, 4], false)
35
+ appender.append event
36
+ event.level = @levels['debug']
37
+ event.data = 'the big log message'
38
+ appender.append event
39
+
40
+ appender.level = :warn
41
+ event.level = @levels['info']
42
+ event.data = 'this message should not get logged'
43
+ appender.append event
44
+ event.level = @levels['warn']
45
+ event.data = 'this is your last warning'
46
+ appender.append event
47
+
48
+ exit!
49
+ end
50
+
51
+ stderr[1].close
52
+ Process.waitpid(pid)
53
+
54
+ assert_equal("syslog_test: INFO TestLogger : <Array> #{[1,2,3,4]}\n",
55
+ stderr[0].gets)
56
+ assert_equal("syslog_test: DEBUG TestLogger : the big log message\n",
57
+ stderr[0].gets)
58
+ assert_equal("syslog_test: WARN TestLogger : this is your last warning\n",
59
+ stderr[0].gets)
60
+ end
61
+
62
+ def test_append_error
63
+ appender = create_syslog
64
+ appender.close false
65
+
66
+ event = Logging::LogEvent.new('TestLogger', @levels['warn'],
67
+ [1, 2, 3, 4], false)
68
+ assert_raise(RuntimeError) {appender.append event}
69
+ assert_equal true, appender.closed?
70
+ end
71
+
72
+ def test_close
73
+ appender = create_syslog
74
+ assert_equal false, appender.closed?
75
+
76
+ appender.close false
77
+ assert_equal true, appender.closed?
78
+ end
79
+
80
+ def test_concat
81
+ return if RUBY_PLATFORM =~ %r/cygwin/
82
+
83
+ stderr = IO::pipe
84
+
85
+ pid = fork do
86
+ stderr[0].close
87
+ STDERR.reopen(stderr[1])
88
+ stderr[1].close
89
+
90
+ appender = create_syslog
91
+ appender << 'this is a test message'
92
+ appender << 'this is another message'
93
+ appender << 'some other line'
94
+
95
+ exit!
96
+ end
97
+
98
+ stderr[1].close
99
+ Process.waitpid(pid)
100
+
101
+ assert_equal("syslog_test: this is a test message\n", stderr[0].gets)
102
+ assert_equal("syslog_test: this is another message\n", stderr[0].gets)
103
+ assert_equal("syslog_test: some other line\n", stderr[0].gets)
104
+ end
105
+
106
+ def test_concat_error
107
+ appender = create_syslog
108
+ appender.close false
109
+
110
+ assert_raise(RuntimeError) {appender << 'oopsy'}
111
+ assert_equal true, appender.closed?
112
+ end
113
+
114
+ def test_map_eq
115
+ appender = create_syslog
116
+
117
+ assert_equal(
118
+ [LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_CRIT],
119
+ get_map_from(appender)
120
+ )
121
+
122
+ appender.map = {
123
+ :debug => LOG_DEBUG,
124
+ :info => 'LOG_NOTICE',
125
+ :warn => :LOG_WARNING,
126
+ :error => 'log_err',
127
+ :fatal => :log_alert
128
+ }
129
+
130
+ assert_equal(
131
+ [LOG_DEBUG, LOG_NOTICE, LOG_WARNING, LOG_ERR, LOG_ALERT],
132
+ get_map_from(appender)
133
+ )
134
+ end
135
+
136
+ def test_map_eq_error
137
+ appender = create_syslog
138
+
139
+ # Object is not a valid syslog level
140
+ assert_raise(ArgumentError) do
141
+ appender.map = {:debug => Object}
142
+ end
143
+
144
+ # there is no syslog level named "info"
145
+ # it should be "log_info"
146
+ assert_raise(NameError) do
147
+ appender.map = {:info => 'lg_info'}
148
+ end
149
+ end
150
+
151
+ def test_initialize_map
152
+ appender = Logging.appenders.syslog(
153
+ 'syslog_test',
154
+ :logopt => @logopt,
155
+ :map => {
156
+ :debug => :log_debug,
157
+ :info => :log_info,
158
+ :warn => :log_warning,
159
+ :error => :log_err,
160
+ :fatal => :log_alert
161
+ }
162
+ )
163
+
164
+ assert_equal(
165
+ [LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_ALERT],
166
+ get_map_from(appender)
167
+ )
168
+ end
169
+
170
+
171
+ private
172
+
173
+ def create_syslog
174
+ layout = Logging.layouts.pattern(:pattern => '%5l %c : %m')
175
+ Logging.appenders.syslog(
176
+ 'syslog_test',
177
+ :logopt => @logopt,
178
+ :facility => ::Syslog::LOG_USER,
179
+ :layout => layout
180
+ )
181
+ end
182
+
183
+ def get_map_from( syslog )
184
+ syslog.instance_variable_get :@map
185
+ end
186
+
187
+ end # class TestSyslog
188
+
189
+ end # module TestAppenders
190
+ end # module TestLogging
191
+
192
+ end # HAVE_SYSLOG
193
+
194
+ # EOF
data/test/benchmark.rb ADDED
@@ -0,0 +1,86 @@
1
+
2
+ begin
3
+ require 'logging'
4
+ rescue LoadError
5
+ path = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ raise if $:.include? path
7
+ $: << path
8
+ retry
9
+ end
10
+
11
+ begin
12
+ require 'rubygems'
13
+ gem 'log4r'
14
+ require 'log4r'
15
+ $log4r = true
16
+ rescue LoadError
17
+ $log4r = false
18
+ end
19
+
20
+ require 'benchmark'
21
+ require 'logger'
22
+
23
+ module Logging
24
+ class Benchmark
25
+
26
+ def run
27
+ this_many = 300_000
28
+
29
+ sio = StringIO.new
30
+
31
+ logging = ::Logging.logger sio
32
+ logging.level = :warn
33
+
34
+ logger = ::Logger.new sio
35
+ logger.level = ::Logger::WARN
36
+
37
+ log4r = if $log4r
38
+ x = ::Log4r::Logger.new('benchmark')
39
+ x.level = ::Log4r::WARN
40
+ x.add ::Log4r::IOOutputter.new(
41
+ 'benchmark', sio,
42
+ :formatter => ::Log4r::PatternFormatter.new(
43
+ :pattern => "%.1l, [%d #\#{Process.pid}] %5l : %M\n",
44
+ :date_pattern => "%Y-%m-%dT%H:%M:%S.\#{Time.now.usec}"
45
+ )
46
+ )
47
+ x
48
+ end
49
+
50
+ puts "== Debug (not logged) ==\n"
51
+ ::Benchmark.bm(10) do |bm|
52
+ bm.report('Logging:') {this_many.times {logging.debug 'not logged'}}
53
+ bm.report('Logger:') {this_many.times {logger.debug 'not logged'}}
54
+ bm.report('Log4r:') {this_many.times {log4r.debug 'not logged'}} if log4r
55
+ end
56
+
57
+ puts "\n== Warn (logged) ==\n"
58
+ ::Benchmark.bm(10) do |bm|
59
+ sio.seek 0
60
+ bm.report('Logging:') {this_many.times {logging.warn 'logged'}}
61
+ sio.seek 0
62
+ bm.report('Logger:') {this_many.times {logger.warn 'logged'}}
63
+ sio.seek 0
64
+ bm.report('Log4r:') {this_many.times {log4r.warn 'logged'}} if log4r
65
+ end
66
+
67
+ puts "\n== Concat ==\n"
68
+ ::Benchmark.bm(10) do |bm|
69
+ sio.seek 0
70
+ bm.report('Logging:') {this_many.times {logging << 'logged'}}
71
+ sio.seek 0
72
+ bm.report('Logger:') {this_many.times {logger << 'logged'}}
73
+ puts "Log4r: not supported" if log4r
74
+ end
75
+ end
76
+
77
+ end # class Benchmark
78
+ end # module Logging
79
+
80
+
81
+ if __FILE__ == $0
82
+ bm = ::Logging::Benchmark.new
83
+ bm.run
84
+ end
85
+
86
+ # EOF