logging 0.9.8 → 1.0.0

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 (46) hide show
  1. data/History.txt +13 -0
  2. data/README.rdoc +51 -39
  3. data/Rakefile +1 -0
  4. data/examples/appenders.rb +44 -0
  5. data/examples/classes.rb +39 -0
  6. data/examples/formatting.rb +49 -0
  7. data/examples/hierarchies.rb +71 -0
  8. data/examples/layouts.rb +45 -0
  9. data/examples/loggers.rb +26 -0
  10. data/examples/names.rb +40 -0
  11. data/examples/simple.rb +14 -0
  12. data/lib/logging.rb +50 -21
  13. data/lib/logging/appender.rb +4 -56
  14. data/lib/logging/appenders.rb +120 -0
  15. data/lib/logging/appenders/buffering.rb +2 -1
  16. data/lib/logging/appenders/console.rb +0 -2
  17. data/lib/logging/appenders/rolling_file.rb +0 -2
  18. data/lib/logging/appenders/string_io.rb +1 -3
  19. data/lib/logging/appenders/syslog.rb +0 -7
  20. data/lib/logging/config/configurator.rb +1 -1
  21. data/lib/logging/config/yaml_configurator.rb +3 -7
  22. data/lib/logging/layout.rb +2 -4
  23. data/lib/logging/layouts.rb +47 -0
  24. data/lib/logging/layouts/basic.rb +2 -4
  25. data/lib/logging/layouts/parseable.rb +211 -0
  26. data/lib/logging/layouts/pattern.rb +6 -8
  27. data/lib/logging/log_event.rb +1 -1
  28. data/lib/logging/logger.rb +4 -4
  29. data/lib/spec/logging_helper.rb +2 -2
  30. data/test/appenders/test_buffered_io.rb +26 -18
  31. data/test/appenders/test_console.rb +10 -10
  32. data/test/appenders/test_email.rb +18 -19
  33. data/test/appenders/test_file.rb +12 -12
  34. data/test/appenders/test_growl.rb +11 -12
  35. data/test/appenders/test_io.rb +14 -15
  36. data/test/appenders/test_rolling_file.rb +15 -24
  37. data/test/appenders/test_syslog.rb +10 -10
  38. data/test/layouts/test_basic.rb +4 -5
  39. data/test/layouts/test_json.rb +112 -0
  40. data/test/layouts/test_pattern.rb +9 -9
  41. data/test/layouts/test_yaml.rb +121 -0
  42. data/test/setup.rb +1 -1
  43. data/test/test_appender.rb +0 -14
  44. data/test/test_log_event.rb +1 -1
  45. data/test/test_logging.rb +3 -3
  46. metadata +17 -2
@@ -0,0 +1,14 @@
1
+ #
2
+ # Logging provides a simple, default logger configured in the same manner as
3
+ # the default Ruby Logger class -- i.e. the output of the two will be the
4
+ # same. All log messags at "warn" or higher are printed to STDOUT; any
5
+ # message below the "warn" level are discarded.
6
+ #
7
+
8
+ require 'logging'
9
+
10
+ log = Logging.logger(STDOUT)
11
+ log.level = :warn
12
+
13
+ log.debug "this debug message will not be output by the logger"
14
+ log.warn "this is your last warning"
data/lib/logging.rb CHANGED
@@ -3,7 +3,24 @@
3
3
  # Used to prevent the class/module from being loaded more than once
4
4
  unless defined? Logging
5
5
 
6
+ require 'yaml'
7
+ require 'stringio'
6
8
  require 'thread'
9
+
10
+ begin
11
+ require 'lockfile'
12
+ rescue LoadError
13
+ retry if require 'rubygems'
14
+ raise
15
+ end
16
+
17
+ begin
18
+ require 'syslog'
19
+ HAVE_SYSLOG = true
20
+ rescue LoadError
21
+ HAVE_SYSLOG = false
22
+ end
23
+
7
24
  begin require 'fastthread'; rescue LoadError; end
8
25
 
9
26
  # TODO: Windows Log Service appender
@@ -13,7 +30,7 @@ begin require 'fastthread'; rescue LoadError; end
13
30
  module Logging
14
31
 
15
32
  # :stopdoc:
16
- VERSION = '0.9.8'
33
+ VERSION = '1.0.0'
17
34
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
18
35
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
19
36
  WIN32 = %r/djgpp|(cyg|ms|bcc)win|mingw/ =~ RUBY_PLATFORM
@@ -85,6 +102,8 @@ module Logging
85
102
  # full description of the :pattern and :date_pattern formatting strings.
86
103
  #
87
104
  def logger( *args )
105
+ return ::Logging::Logger if args.empty?
106
+
88
107
  opts = args.pop if args.last.instance_of?(Hash)
89
108
  opts ||= Hash.new
90
109
 
@@ -141,6 +160,18 @@ module Logging
141
160
  logger
142
161
  end
143
162
 
163
+ # Access to the layouts.
164
+ #
165
+ def layouts
166
+ ::Logging::Layouts
167
+ end
168
+
169
+ # Access to the appenders.
170
+ #
171
+ def appenders
172
+ ::Logging::Appenders
173
+ end
174
+
144
175
  # call-seq:
145
176
  # Logging.init( levels )
146
177
  #
@@ -182,8 +213,8 @@ module Logging
182
213
  args = %w(debug info warn error fatal) if args.empty?
183
214
 
184
215
  args.flatten!
185
- levels = ::Logging::LEVELS.clear
186
- names = ::Logging::LNAMES.clear
216
+ levels = LEVELS.clear
217
+ names = LNAMES.clear
187
218
 
188
219
  id = 0
189
220
  args.each do |lvl|
@@ -274,19 +305,6 @@ module Logging
274
305
  args.empty? ? PATH : ::File.join(PATH, args.flatten)
275
306
  end
276
307
 
277
- # Utility method used to rquire all files ending in .rb that lie in the
278
- # directory below this file that has the same name as the filename passed
279
- # in. Optionally, a specific _directory_ name can be passed in such that
280
- # the _filename_ does not have to be equivalent to the directory.
281
- #
282
- def require_all_libs_relative_to( fname, dir = nil )
283
- dir ||= ::File.basename(fname, '.*')
284
- search_me = ::File.expand_path(
285
- ::File.join(::File.dirname(fname), dir, '*.rb'))
286
-
287
- Dir.glob(search_me).sort.each {|rb| require rb}
288
- end
289
-
290
308
  # call-seq:
291
309
  # show_configuration( io = STDOUT, logger = 'root' )
292
310
  #
@@ -386,8 +404,21 @@ module Logging
386
404
  end
387
405
  end # module Logging
388
406
 
389
- Logging.require_all_libs_relative_to(__FILE__)
390
- Logging.require_all_libs_relative_to(__FILE__, 'logging/config')
407
+
408
+ require Logging.libpath(%w[logging utils])
409
+ require Logging.libpath(%w[logging appender])
410
+ require Logging.libpath(%w[logging layout])
411
+ require Logging.libpath(%w[logging log_event])
412
+ require Logging.libpath(%w[logging logger])
413
+ require Logging.libpath(%w[logging repository])
414
+ require Logging.libpath(%w[logging root_logger])
415
+ require Logging.libpath(%w[logging stats])
416
+ require Logging.libpath(%w[logging appenders])
417
+ require Logging.libpath(%w[logging layouts])
418
+
419
+ require Logging.libpath(%w[logging config configurator])
420
+ require Logging.libpath(%w[logging config yaml_configurator])
421
+
391
422
 
392
423
  # This exit handler will close all the appenders that exist in the system.
393
424
  # This is needed for closing IO streams and connections to the syslog server
@@ -395,9 +426,7 @@ Logging.require_all_libs_relative_to(__FILE__, 'logging/config')
395
426
  #
396
427
  at_exit {
397
428
  Logging.log_internal {'at_exit hook called - closing all appenders'}
398
- Logging::Appender.instance_variable_get(:@appenders).values.each do |ap|
399
- ap.close
400
- end
429
+ Logging::Appenders.each {|appender| appender.close}
401
430
  }
402
431
 
403
432
  end # unless defined?
@@ -16,58 +16,6 @@ module Logging
16
16
  #
17
17
  class Appender
18
18
 
19
- @appenders = Hash.new
20
-
21
- class << self
22
-
23
- # call-seq:
24
- # Appender[name]
25
- #
26
- # Returns the appender instance stroed in the Appender hash under the
27
- # key _name_, or +nil+ if no appender has been created using that name.
28
- #
29
- def []( name ) @appenders[name] end
30
-
31
- # call-seq:
32
- # Appender[name] = appender
33
- #
34
- # Stores the given _appender_ instance in the Appender hash under the
35
- # key _name_.
36
- #
37
- def []=( name, val ) @appenders[name] = val end
38
-
39
- # call-seq:
40
- # Appenders.remove( name )
41
- #
42
- # Removes the appender instance stored in the Appender hash under the
43
- # key _name_.
44
- #
45
- def remove( name ) @appenders.delete(name) end
46
-
47
- # call-seq:
48
- # Appender.stdout
49
- #
50
- # Returns an instance of the Stdout Appender. Unless the user explicitly
51
- # creates a new Stdout Appender, the instance returned by this method
52
- # will always be the same:
53
- #
54
- # Appender.stdout.object_id == Appender.stdout.object_id #=> true
55
- #
56
- def stdout( ) self['stdout'] || ::Logging::Appenders::Stdout.new end
57
-
58
- # call-seq:
59
- # Appender.stderr
60
- #
61
- # Returns an instance of the Stderr Appender. Unless the user explicitly
62
- # creates a new Stderr Appender, the instance returned by this method
63
- # will always be the same:
64
- #
65
- # Appender.stderr.object_id == Appender.stderr.object_id #=> true
66
- #
67
- def stderr( ) self['stderr'] || ::Logging::Appenders::Stderr.new end
68
-
69
- end # class << self
70
-
71
19
  attr_reader :name, :layout, :level
72
20
 
73
21
  # call-seq:
@@ -85,6 +33,8 @@ class Appender
85
33
  # :level => the level at which to log
86
34
  #
87
35
  def initialize( name, opts = {} )
36
+ ::Logging.init unless ::Logging.const_defined? :MAX_LEVEL_LENGTH
37
+
88
38
  @name = name.to_s
89
39
  @closed = false
90
40
 
@@ -102,7 +52,7 @@ class Appender
102
52
  end
103
53
  end
104
54
 
105
- ::Logging::Appender[@name] = self
55
+ ::Logging::Appenders[@name] = self
106
56
  end
107
57
 
108
58
  # call-seq:
@@ -217,7 +167,7 @@ class Appender
217
167
  #
218
168
  def close( footer = true )
219
169
  return self if @closed
220
- ::Logging::Appender.remove(@name)
170
+ ::Logging::Appenders.remove(@name)
221
171
  @closed = true
222
172
 
223
173
  sync {flush}
@@ -298,6 +248,4 @@ class Appender
298
248
  end # class Appender
299
249
  end # module Logging
300
250
 
301
- Logging.require_all_libs_relative_to(__FILE__, 'appenders')
302
-
303
251
  # EOF
@@ -0,0 +1,120 @@
1
+
2
+ module Logging
3
+ module Appenders
4
+
5
+ # Accessor / Factory for the Email appender.
6
+ #
7
+ def email( *args )
8
+ return ::Logging::Appenders::Email if args.empty?
9
+ ::Logging::Appenders::Email.new(*args)
10
+ end
11
+
12
+ # Accessor / Factory for the File appender.
13
+ #
14
+ def file( *args )
15
+ return ::Logging::Appenders::File if args.empty?
16
+ ::Logging::Appenders::File.new(*args)
17
+ end
18
+
19
+ # Accessor / Factory for the Growl appender.
20
+ #
21
+ def growl( *args )
22
+ return ::Logging::Appenders::Growl if args.empty?
23
+ ::Logging::Appenders::Growl.new(*args)
24
+ end
25
+
26
+ # Accessor / Factory for the IO appender.
27
+ #
28
+ def io( *args )
29
+ return ::Logging::Appenders::IO if args.empty?
30
+ ::Logging::Appenders::IO.new(*args)
31
+ end
32
+
33
+ # Accessor / Factory for the RollingFile appender.
34
+ #
35
+ def rolling_file( *args )
36
+ return ::Logging::Appenders::RollingFile if args.empty?
37
+ ::Logging::Appenders::RollingFile.new(*args)
38
+ end
39
+
40
+ # Accessor / Factory for the Stderr appender.
41
+ #
42
+ def stderr( *args )
43
+ if args.empty?
44
+ return self['stderr'] || ::Logging::Appenders::Stderr.new
45
+ end
46
+ ::Logging::Appenders::Stderr.new(*args)
47
+ end
48
+
49
+ # Accessor / Factory for the Stdout appender.
50
+ #
51
+ def stdout( *args )
52
+ if args.empty?
53
+ return self['stdout'] || ::Logging::Appenders::Stdout.new
54
+ end
55
+ ::Logging::Appenders::Stdout.new(*args)
56
+ end
57
+
58
+ # Accessor / Factory for the StringIo appender.
59
+ #
60
+ def string_io( *args )
61
+ return ::Logging::Appenders::StringIo if args.empty?
62
+ ::Logging::Appenders::StringIo.new(*args)
63
+ end
64
+
65
+ if HAVE_SYSLOG
66
+ # Accessor / Factory for the Syslog appender.
67
+ #
68
+ def syslog( *args )
69
+ return ::Logging::Appenders::Syslog if args.empty?
70
+ ::Logging::Appenders::Syslog.new(*args)
71
+ end
72
+ end
73
+
74
+ # call-seq:
75
+ # Appenders[name]
76
+ #
77
+ # Returns the appender instance stroed in the appender hash under the
78
+ # key _name_, or +nil+ if no appender has been created using that name.
79
+ #
80
+ def []( name ) @appenders[name] end
81
+
82
+ # call-seq:
83
+ # Appenders[name] = appender
84
+ #
85
+ # Stores the given _appender_ instance in the appender hash under the
86
+ # key _name_.
87
+ #
88
+ def []=( name, value ) @appenders[name] = value end
89
+
90
+ # call-seq:
91
+ # Appenders.remove( name )
92
+ #
93
+ # Removes the appender instance stored in the appender hash under the
94
+ # key _name_.
95
+ #
96
+ def remove( name ) @appenders.delete(name) end
97
+
98
+ # call-seq:
99
+ # each {|appender| block}
100
+ #
101
+ # Yield each appender to the _block_.
102
+ #
103
+ def each( &block )
104
+ @appenders.values.each(&block)
105
+ nil
106
+ end
107
+
108
+ extend self
109
+ @appenders = Hash.new
110
+
111
+ end # module Appenders
112
+ end # module Logging
113
+
114
+
115
+ %w[buffering io console email file growl rolling_file string_io syslog].
116
+ each do |fn|
117
+ require ::Logging.libpath('logging', 'appenders', fn)
118
+ end
119
+
120
+ # EOF
@@ -117,8 +117,9 @@ module Logging::Appenders
117
117
  # options.
118
118
  #
119
119
  def configure_buffering( opts )
120
- @buffer = []
120
+ ::Logging.init unless ::Logging.const_defined? :MAX_LEVEL_LENGTH
121
121
 
122
+ @buffer = []
122
123
  self.immediate_at = opts.getopt(:immediate_at, '')
123
124
  self.auto_flushing = opts.getopt(:auto_flushing, true)
124
125
  end
@@ -1,6 +1,4 @@
1
1
 
2
- require Logging.libpath(*%w[logging appenders io])
3
-
4
2
  module Logging::Appenders
5
3
 
6
4
  # This class provides an Appender that can write to STDOUT.
@@ -1,6 +1,4 @@
1
1
 
2
- require 'lockfile'
3
-
4
2
  module Logging::Appenders
5
3
 
6
4
  # An appender that writes to a file and ensures that the file size or age
@@ -1,6 +1,4 @@
1
1
 
2
- require 'stringio'
3
-
4
2
  module Logging::Appenders
5
3
 
6
4
  # This class provides an Appender that can write to a StringIO instance.
@@ -20,8 +18,8 @@ module Logging::Appenders
20
18
  def initialize( name, opts = {} )
21
19
  @sio = StringIO.new
22
20
  @sio.extend IoToS
21
+ @pos = 0
23
22
  super(name, @sio, opts)
24
- clear
25
23
  end
26
24
 
27
25
  # Clears the internal StringIO instance. All log messages are removed
@@ -1,11 +1,4 @@
1
1
 
2
- begin
3
- require 'syslog'
4
- HAVE_SYSLOG = true
5
- rescue LoadError
6
- HAVE_SYSLOG = false
7
- end
8
-
9
2
  # only load this class if we have the syslog library
10
3
  # Windows does not have syslog
11
4
  #
@@ -82,7 +82,7 @@ module Logging::Config
82
82
  l.additive = config[:additive] if l.respond_to? :additive=
83
83
  l.trace = config[:trace]
84
84
  l.appenders = Array(config[:appenders]).
85
- map {|nm| ::Logging::Appender[nm]}
85
+ map {|nm| ::Logging::Appenders[nm]}
86
86
  end
87
87
  end
88
88
 
@@ -1,8 +1,5 @@
1
1
 
2
- require 'yaml'
3
-
4
- module Logging
5
- module Config
2
+ module Logging::Config
6
3
 
7
4
  # The YamlConfigurator class is used to configure the Logging framework
8
5
  # using information found in a YAML file.
@@ -137,7 +134,7 @@ module Config
137
134
  l.trace = config['trace'] if l.respond_to? :trace=
138
135
 
139
136
  if config.has_key?('appenders')
140
- l.appenders = config['appenders'].map {|n| ::Logging::Appender[n]}
137
+ l.appenders = config['appenders'].map {|n| ::Logging::Appenders[n]}
141
138
  end
142
139
  end
143
140
  end
@@ -189,7 +186,6 @@ module Config
189
186
  end
190
187
 
191
188
  end # class YamlConfigurator
192
- end # module Config
193
- end # module Logging
189
+ end # module Logging::Config
194
190
 
195
191
  # EOF