ottobar-logging 0.9.5.1

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 (53) hide show
  1. data/History.txt +158 -0
  2. data/README.rdoc +102 -0
  3. data/Rakefile +41 -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/lib/logging.rb +408 -0
  10. data/lib/logging/appender.rb +303 -0
  11. data/lib/logging/appenders/buffering.rb +167 -0
  12. data/lib/logging/appenders/console.rb +62 -0
  13. data/lib/logging/appenders/email.rb +75 -0
  14. data/lib/logging/appenders/file.rb +54 -0
  15. data/lib/logging/appenders/growl.rb +197 -0
  16. data/lib/logging/appenders/io.rb +69 -0
  17. data/lib/logging/appenders/rolling_file.rb +291 -0
  18. data/lib/logging/appenders/syslog.rb +201 -0
  19. data/lib/logging/config/configurator.rb +190 -0
  20. data/lib/logging/config/yaml_configurator.rb +195 -0
  21. data/lib/logging/layout.rb +107 -0
  22. data/lib/logging/layouts/basic.rb +34 -0
  23. data/lib/logging/layouts/pattern.rb +296 -0
  24. data/lib/logging/log_event.rb +49 -0
  25. data/lib/logging/logger.rb +491 -0
  26. data/lib/logging/repository.rb +172 -0
  27. data/lib/logging/root_logger.rb +61 -0
  28. data/lib/logging/stats.rb +278 -0
  29. data/lib/logging/utils.rb +130 -0
  30. data/test/appenders/test_buffered_io.rb +183 -0
  31. data/test/appenders/test_console.rb +66 -0
  32. data/test/appenders/test_email.rb +171 -0
  33. data/test/appenders/test_file.rb +93 -0
  34. data/test/appenders/test_growl.rb +128 -0
  35. data/test/appenders/test_io.rb +142 -0
  36. data/test/appenders/test_rolling_file.rb +207 -0
  37. data/test/appenders/test_syslog.rb +191 -0
  38. data/test/benchmark.rb +87 -0
  39. data/test/config/test_configurator.rb +70 -0
  40. data/test/config/test_yaml_configurator.rb +40 -0
  41. data/test/layouts/test_basic.rb +43 -0
  42. data/test/layouts/test_pattern.rb +177 -0
  43. data/test/setup.rb +69 -0
  44. data/test/test_appender.rb +166 -0
  45. data/test/test_layout.rb +107 -0
  46. data/test/test_log_event.rb +80 -0
  47. data/test/test_logger.rb +734 -0
  48. data/test/test_logging.rb +267 -0
  49. data/test/test_repository.rb +126 -0
  50. data/test/test_root_logger.rb +81 -0
  51. data/test/test_stats.rb +274 -0
  52. data/test/test_utils.rb +114 -0
  53. metadata +152 -0
@@ -0,0 +1,191 @@
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
+ end
18
+
19
+ def test_append
20
+ return if RUBY_PLATFORM =~ %r/cygwin/
21
+
22
+ stderr = IO::pipe
23
+
24
+ pid = fork do
25
+ stderr[0].close
26
+ STDERR.reopen(stderr[1])
27
+ stderr[1].close
28
+
29
+ appender = create_syslog
30
+ event = ::Logging::LogEvent.new('TestLogger', @levels['info'],
31
+ [1, 2, 3, 4], false)
32
+ appender.append event
33
+ event.level = @levels['debug']
34
+ event.data = 'the big log message'
35
+ appender.append event
36
+
37
+ appender.level = :warn
38
+ event.level = @levels['info']
39
+ event.data = 'this message should not get logged'
40
+ appender.append event
41
+ event.level = @levels['warn']
42
+ event.data = 'this is your last warning'
43
+ appender.append event
44
+
45
+ exit!
46
+ end
47
+
48
+ stderr[1].close
49
+ Process.waitpid(pid)
50
+
51
+ assert_equal("syslog_test: INFO TestLogger : <Array> #{[1,2,3,4]}\n",
52
+ stderr[0].gets)
53
+ assert_equal("syslog_test: DEBUG TestLogger : the big log message\n",
54
+ stderr[0].gets)
55
+ assert_equal("syslog_test: WARN TestLogger : this is your last warning\n",
56
+ stderr[0].gets)
57
+ end
58
+
59
+ def test_append_error
60
+ appender = create_syslog
61
+ appender.close false
62
+
63
+ event = ::Logging::LogEvent.new('TestLogger', @levels['warn'],
64
+ [1, 2, 3, 4], false)
65
+ assert_raise(RuntimeError) {appender.append event}
66
+ assert_equal true, appender.closed?
67
+ end
68
+
69
+ def test_close
70
+ appender = create_syslog
71
+ assert_equal false, appender.closed?
72
+
73
+ appender.close false
74
+ assert_equal true, appender.closed?
75
+ end
76
+
77
+ def test_concat
78
+ return if RUBY_PLATFORM =~ %r/cygwin/
79
+
80
+ stderr = IO::pipe
81
+
82
+ pid = fork do
83
+ stderr[0].close
84
+ STDERR.reopen(stderr[1])
85
+ stderr[1].close
86
+
87
+ appender = create_syslog
88
+ appender << 'this is a test message'
89
+ appender << 'this is another message'
90
+ appender << 'some other line'
91
+
92
+ exit!
93
+ end
94
+
95
+ stderr[1].close
96
+ Process.waitpid(pid)
97
+
98
+ assert_equal("syslog_test: this is a test message\n", stderr[0].gets)
99
+ assert_equal("syslog_test: this is another message\n", stderr[0].gets)
100
+ assert_equal("syslog_test: some other line\n", stderr[0].gets)
101
+ end
102
+
103
+ def test_concat_error
104
+ appender = create_syslog
105
+ appender.close false
106
+
107
+ assert_raise(RuntimeError) {appender << 'oopsy'}
108
+ assert_equal true, appender.closed?
109
+ end
110
+
111
+ def test_map_eq
112
+ appender = create_syslog
113
+
114
+ assert_equal(
115
+ [LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_CRIT],
116
+ get_map_from(appender)
117
+ )
118
+
119
+ appender.map = {
120
+ :debug => LOG_DEBUG,
121
+ :info => 'LOG_NOTICE',
122
+ :warn => :LOG_WARNING,
123
+ :error => 'log_err',
124
+ :fatal => :log_alert
125
+ }
126
+
127
+ assert_equal(
128
+ [LOG_DEBUG, LOG_NOTICE, LOG_WARNING, LOG_ERR, LOG_ALERT],
129
+ get_map_from(appender)
130
+ )
131
+ end
132
+
133
+ def test_map_eq_error
134
+ appender = create_syslog
135
+
136
+ # Object is not a valid syslog level
137
+ assert_raise(ArgumentError) do
138
+ appender.map = {:debug => Object}
139
+ end
140
+
141
+ # there is no syslog level named "info"
142
+ # it should be "log_info"
143
+ assert_raise(NameError) do
144
+ appender.map = {:info => 'lg_info'}
145
+ end
146
+ end
147
+
148
+ def test_initialize_map
149
+ appender = ::Logging::Appenders::Syslog.new(
150
+ 'syslog_test',
151
+ :logopt => ::Syslog::LOG_PERROR | ::Syslog::LOG_NDELAY,
152
+ :map => {
153
+ :debug => :log_debug,
154
+ :info => :log_info,
155
+ :warn => :log_warning,
156
+ :error => :log_err,
157
+ :fatal => :log_alert
158
+ }
159
+ )
160
+
161
+ assert_equal(
162
+ [LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_ALERT],
163
+ get_map_from(appender)
164
+ )
165
+ end
166
+
167
+
168
+ private
169
+
170
+ def create_syslog
171
+ layout = ::Logging::Layouts::Pattern.new(:pattern => '%5l %c : %m')
172
+ ::Logging::Appenders::Syslog.new(
173
+ 'syslog_test',
174
+ :logopt => ::Syslog::LOG_PERROR | ::Syslog::LOG_NDELAY,
175
+ :facility => ::Syslog::LOG_USER,
176
+ :layout => layout
177
+ )
178
+ end
179
+
180
+ def get_map_from( syslog )
181
+ syslog.instance_variable_get :@map
182
+ end
183
+
184
+ end # class TestIO
185
+
186
+ end # module TestAppenders
187
+ end # module TestLogging
188
+
189
+ end # HAVE_SYSLOG
190
+
191
+ # EOF
@@ -0,0 +1,87 @@
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 'stringio'
22
+ require 'logger'
23
+
24
+ module Logging
25
+ class Benchmark
26
+
27
+ def run
28
+ this_many = 300_000
29
+
30
+ sio = StringIO.new
31
+
32
+ logging = ::Logging.logger sio
33
+ logging.level = :warn
34
+
35
+ logger = ::Logger.new sio
36
+ logger.level = ::Logger::WARN
37
+
38
+ log4r = if $log4r
39
+ x = ::Log4r::Logger.new('benchmark')
40
+ x.level = ::Log4r::WARN
41
+ x.add ::Log4r::IOOutputter.new(
42
+ 'benchmark', sio,
43
+ :formatter => ::Log4r::PatternFormatter.new(
44
+ :pattern => "%.1l, [%d #\#{Process.pid}] %5l : %M\n",
45
+ :date_pattern => "%Y-%m-%dT%H:%M:%S.\#{Time.now.usec}"
46
+ )
47
+ )
48
+ x
49
+ end
50
+
51
+ puts "== Debug (not logged) ==\n"
52
+ ::Benchmark.bm(10) do |bm|
53
+ bm.report('Logging:') {this_many.times {logging.debug 'not logged'}}
54
+ bm.report('Logger:') {this_many.times {logger.debug 'not logged'}}
55
+ bm.report('Log4r:') {this_many.times {log4r.debug 'not logged'}} if log4r
56
+ end
57
+
58
+ puts "\n== Warn (logged) ==\n"
59
+ ::Benchmark.bm(10) do |bm|
60
+ sio.seek 0
61
+ bm.report('Logging:') {this_many.times {logging.warn 'logged'}}
62
+ sio.seek 0
63
+ bm.report('Logger:') {this_many.times {logger.warn 'logged'}}
64
+ sio.seek 0
65
+ bm.report('Log4r:') {this_many.times {log4r.warn 'logged'}} if log4r
66
+ end
67
+
68
+ puts "\n== Concat ==\n"
69
+ ::Benchmark.bm(10) do |bm|
70
+ sio.seek 0
71
+ bm.report('Logging:') {this_many.times {logging << 'logged'}}
72
+ sio.seek 0
73
+ bm.report('Logger:') {this_many.times {logger << 'logged'}}
74
+ puts "Log4r: not supported" if log4r
75
+ end
76
+ end
77
+
78
+ end # class Benchmark
79
+ end # module Logging
80
+
81
+
82
+ if __FILE__ == $0
83
+ bm = ::Logging::Benchmark.new
84
+ bm.run
85
+ end
86
+
87
+ # EOF
@@ -0,0 +1,70 @@
1
+
2
+ require File.join(File.dirname(__FILE__), %w[.. setup])
3
+
4
+ module TestLogging
5
+ module TestConfig
6
+
7
+ class TestConfigurator < Test::Unit::TestCase
8
+ include LoggingTestCase
9
+
10
+ def test_configuration
11
+ begin
12
+ load Logging.path(%w[data logging.rb])
13
+ rescue Exception => err
14
+ flunk err.inspect
15
+ end
16
+
17
+ levels = {
18
+ 'deb' => 0,
19
+ 'inf' => 1,
20
+ 'prt' => 2,
21
+ 'wrn' => 3,
22
+ 'err' => 4,
23
+ 'fat' => 5
24
+ }
25
+ assert_equal levels, Logging::LEVELS
26
+ assert_equal :inspect, Logging::OBJ_FORMAT
27
+
28
+ hash = Logging::Repository.instance.instance_variable_get(:@h)
29
+ assert hash.has_key?('A::B::C')
30
+ assert hash.has_key?('yourlogger')
31
+ end
32
+
33
+ def test_simple_configuration
34
+ begin
35
+ load Logging.path(%w[data simple_logging.rb])
36
+ rescue Exception => err
37
+ flunk err.inspect
38
+ end
39
+
40
+ levels = {
41
+ 'debug' => 0,
42
+ 'info' => 1,
43
+ 'warn' => 2,
44
+ 'error' => 3,
45
+ 'fatal' => 4
46
+ }
47
+ assert_equal levels, Logging::LEVELS
48
+ assert_equal false, Logging.const_defined?('OBJ_FORMAT')
49
+
50
+ root = Logging::Logger.root
51
+ assert_equal 1, root.level
52
+ end
53
+
54
+ def test_bad_appender_configuration
55
+ assert_raise(Logging::Config::Configurator::Error) {
56
+ load Logging.path(%w[data bad_logging_1.rb])
57
+ }
58
+ end
59
+
60
+ def test_bad_layout_configuration
61
+ assert_raise(Logging::Config::Configurator::Error) {
62
+ load Logging.path(%w[data bad_logging_2.rb])
63
+ }
64
+ end
65
+ end
66
+
67
+ end # module TestConfig
68
+ end # module TestLogging
69
+
70
+ # EOF
@@ -0,0 +1,40 @@
1
+
2
+ require File.join(File.dirname(__FILE__), %w[.. setup])
3
+
4
+ module TestLogging
5
+ module TestConfig
6
+
7
+ class TestYamlConfigurator < Test::Unit::TestCase
8
+ include LoggingTestCase
9
+
10
+ def test_class_load
11
+ assert_raise(::Logging::Config::YamlConfigurator::Error) {
12
+ ::Logging::Config::YamlConfigurator.load(Object.new)
13
+ }
14
+
15
+ begin
16
+ fd = File.open('data/logging.yaml','r')
17
+ assert_nothing_raised {
18
+ ::Logging::Config::YamlConfigurator.load(fd)
19
+ }
20
+ ensure
21
+ fd.close
22
+ end
23
+ end
24
+
25
+ def test_initialize
26
+ io = StringIO.new
27
+ io << YAML.dump({:one => 1, :two => 2, :three => 3})
28
+ io.seek 0
29
+
30
+ assert_raise(::Logging::Config::YamlConfigurator::Error) {
31
+ ::Logging::Config::YamlConfigurator.new(io, :meh)
32
+ }
33
+ end
34
+
35
+ end # class TestYamlConfigurator
36
+
37
+ end # module TestConfig
38
+ end # module TestLogging
39
+
40
+ # EOF
@@ -0,0 +1,43 @@
1
+
2
+ require File.join(File.dirname(__FILE__), %w[.. setup])
3
+
4
+ module TestLogging
5
+ module TestLayouts
6
+
7
+ class TestBasic < Test::Unit::TestCase
8
+ include LoggingTestCase
9
+
10
+ def setup
11
+ super
12
+ ::Logging.init
13
+ @layout = ::Logging::Layouts::Basic.new
14
+ @levels = ::Logging::LEVELS
15
+ end
16
+
17
+ def test_format
18
+ event = ::Logging::LogEvent.new( 'ArrayLogger', @levels['info'],
19
+ 'log message', false)
20
+ assert_equal " INFO ArrayLogger : log message\n", @layout.format(event)
21
+
22
+ event.data = [1, 2, 3, 4]
23
+ assert_equal(" INFO ArrayLogger : <Array> #{[1,2,3,4]}\n",
24
+ @layout.format(event))
25
+
26
+ event.level = @levels['debug']
27
+ event.data = 'and another message'
28
+ log = "DEBUG ArrayLogger : and another message\n"
29
+ assert_equal log, @layout.format(event)
30
+
31
+ event.logger = 'Test'
32
+ event.level = @levels['fatal']
33
+ event.data = Exception.new
34
+ log = "FATAL Test : <Exception> Exception\n"
35
+ assert_equal log, @layout.format(event)
36
+ end
37
+
38
+ end # class TestBasic
39
+
40
+ end # module TestLayouts
41
+ end # module TestLogging
42
+
43
+ # EOF
@@ -0,0 +1,177 @@
1
+
2
+ require File.join(File.dirname(__FILE__), %w[.. setup])
3
+
4
+ module TestLogging
5
+ module TestLayouts
6
+
7
+ class TestPattern < Test::Unit::TestCase
8
+ include LoggingTestCase
9
+
10
+ def setup
11
+ super
12
+ ::Logging.init
13
+ @layout = ::Logging::Layouts::Pattern.new
14
+ @levels = ::Logging::LEVELS
15
+ @date_fmt = '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}'
16
+ end
17
+
18
+ def test_date_method
19
+ assert_nil @layout.date_method
20
+ end
21
+
22
+ def test_date_method_eq
23
+ @layout.date_method = :to_f
24
+ assert_equal :to_f, @layout.date_method
25
+ assert_instance_of Float, @layout.format_date
26
+
27
+ @layout.date_method = 'usec'
28
+ assert_equal 'usec', @layout.date_method
29
+ assert_instance_of Fixnum, @layout.format_date
30
+
31
+ @layout.date_method = :to_s
32
+ assert_equal :to_s, @layout.date_method
33
+ assert_instance_of String, @layout.format_date
34
+
35
+ # now, even if we have defined a date_pattern, the date_method should
36
+ # supersede the date_pattern
37
+ @layout.date_pattern = '%Y'
38
+
39
+ @layout.date_method = 'usec'
40
+ assert_equal 'usec', @layout.date_method
41
+ assert_instance_of Fixnum, @layout.format_date
42
+ end
43
+
44
+ def test_date_pattern
45
+ assert_equal '%Y-%m-%d %H:%M:%S', @layout.date_pattern
46
+ end
47
+
48
+ def test_date_pattern_eq
49
+ @layout.date_pattern = '%Y'
50
+ assert_equal '%Y', @layout.date_pattern
51
+ assert_match %r/\A\d{4}\z/, @layout.format_date
52
+
53
+ @layout.date_pattern = '%H:%M'
54
+ assert_equal '%H:%M', @layout.date_pattern
55
+ assert_match %r/\A\d{2}:\d{2}\z/, @layout.format_date
56
+ end
57
+
58
+ def test_format
59
+ fmt = '\[' + @date_fmt + '\] %s -- %s : %s\n'
60
+
61
+ event = ::Logging::LogEvent.new('ArrayLogger', @levels['info'],
62
+ 'log message', false)
63
+ rgxp = Regexp.new(sprintf(fmt, 'INFO ', 'ArrayLogger', 'log message'))
64
+ assert_match rgxp, @layout.format(event)
65
+
66
+ event.data = [1, 2, 3, 4]
67
+ rgxp = Regexp.new(sprintf(fmt, 'INFO ', 'ArrayLogger',
68
+ Regexp.escape("<Array> #{[1,2,3,4]}")))
69
+ assert_match rgxp, @layout.format(event)
70
+
71
+ event.level = @levels['debug']
72
+ event.data = 'and another message'
73
+ rgxp = Regexp.new(
74
+ sprintf(fmt, 'DEBUG', 'ArrayLogger', 'and another message'))
75
+ assert_match rgxp, @layout.format(event)
76
+
77
+ event.logger = 'Test'
78
+ event.level = @levels['fatal']
79
+ event.data = Exception.new
80
+ rgxp = Regexp.new(
81
+ sprintf(fmt, 'FATAL', 'Test', '<Exception> Exception'))
82
+ assert_match rgxp, @layout.format(event)
83
+ end
84
+
85
+ def test_format_date
86
+ rgxp = Regexp.new @date_fmt
87
+ assert_match rgxp, @layout.format_date
88
+ end
89
+
90
+ def test_pattern
91
+ assert_equal "[%d] %-5l -- %c : %m\n", @layout.pattern
92
+ end
93
+
94
+ def test_pattern_eq
95
+ event = ::Logging::LogEvent.new('TestLogger', @levels['info'],
96
+ ['log message'], false)
97
+
98
+ @layout.pattern = '%d'
99
+ assert_equal '%d', @layout.pattern
100
+ assert_match Regexp.new(@date_fmt), @layout.format(event)
101
+ end
102
+
103
+ def test_pattern_all
104
+ event = ::Logging::LogEvent.new('TestLogger', @levels['info'],
105
+ 'log message', false)
106
+ event.instance_variable_set :@file, 'test_file.rb'
107
+ event.instance_variable_set :@line, '123'
108
+ event.instance_variable_set :@method, 'method_name'
109
+
110
+ @layout.pattern = '%c'
111
+ assert_equal 'TestLogger', @layout.format(event)
112
+
113
+ @layout.pattern = '%d'
114
+ assert_match Regexp.new(@date_fmt), @layout.format(event)
115
+
116
+ @layout.pattern = '%F'
117
+ assert_equal 'test_file.rb', @layout.format(event)
118
+
119
+ @layout.pattern = '%l'
120
+ assert_equal 'INFO', @layout.format(event)
121
+
122
+ @layout.pattern = '%L'
123
+ assert_equal '123', @layout.format(event)
124
+
125
+ @layout.pattern = '%m'
126
+ assert_equal 'log message', @layout.format(event)
127
+
128
+ @layout.pattern = '%M'
129
+ assert_equal 'method_name', @layout.format(event)
130
+
131
+ @layout.pattern = '%p'
132
+ assert_match %r/\A\d+\z/, @layout.format(event)
133
+
134
+ @layout.pattern = '%r'
135
+ assert_match %r/\A\d+\z/, @layout.format(event)
136
+
137
+ @layout.pattern = '%t'
138
+ assert_match %r/\A-?\d+\z/, @layout.format(event)
139
+
140
+ @layout.pattern = '%T'
141
+ assert_equal "", @layout.format(event)
142
+ Thread.current[:name] = "Main"
143
+ assert_equal "Main", @layout.format(event)
144
+
145
+ @layout.pattern = '%%'
146
+ assert_equal '%', @layout.format(event)
147
+
148
+ # 'z' is not a recognized format character
149
+ assert_raise(ArgumentError) {
150
+ @layout.pattern = '[%d] %% %c - %l %z blah'
151
+ }
152
+ assert_equal '%', @layout.format(event)
153
+
154
+ @layout.pattern = '%5l'
155
+ assert_equal ' INFO', @layout.format(event)
156
+
157
+ @layout.pattern = '%-5l'
158
+ assert_equal 'INFO ', @layout.format(event)
159
+
160
+ @layout.pattern = '%.1l, %c'
161
+ assert_equal 'I, TestLogger', @layout.format(event)
162
+
163
+ @layout.pattern = '%7.7m'
164
+ assert_equal 'log mes', @layout.format(event)
165
+
166
+ event.data = 'tim'
167
+ assert_equal ' tim', @layout.format(event)
168
+
169
+ @layout.pattern = '%-7.7m'
170
+ assert_equal 'tim ', @layout.format(event)
171
+ end
172
+
173
+ end # class TestBasic
174
+ end # module TestLayouts
175
+ end # module TestLogging
176
+
177
+ # EOF