logging 1.8.2 → 2.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -3
  3. data/History.txt +20 -0
  4. data/README.md +159 -0
  5. data/Rakefile +9 -5
  6. data/examples/appenders.rb +0 -4
  7. data/examples/layouts.rb +1 -8
  8. data/examples/names.rb +4 -4
  9. data/lib/logging.rb +24 -76
  10. data/lib/logging/appender.rb +71 -16
  11. data/lib/logging/appenders.rb +0 -2
  12. data/lib/logging/appenders/buffering.rb +32 -16
  13. data/lib/logging/appenders/file.rb +2 -2
  14. data/lib/logging/appenders/io.rb +1 -1
  15. data/lib/logging/appenders/rolling_file.rb +228 -165
  16. data/lib/logging/appenders/string_io.rb +1 -1
  17. data/lib/logging/appenders/syslog.rb +4 -4
  18. data/lib/logging/color_scheme.rb +20 -3
  19. data/lib/logging/diagnostic_context.rb +142 -17
  20. data/lib/logging/filter.rb +18 -0
  21. data/lib/logging/filters.rb +4 -0
  22. data/lib/logging/filters/level.rb +29 -0
  23. data/lib/logging/layout.rb +2 -2
  24. data/lib/logging/layouts/parseable.rb +5 -2
  25. data/lib/logging/layouts/pattern.rb +309 -168
  26. data/lib/logging/log_event.rb +5 -5
  27. data/lib/logging/logger.rb +55 -68
  28. data/lib/logging/repository.rb +24 -39
  29. data/lib/logging/root_logger.rb +1 -1
  30. data/lib/logging/utils.rb +4 -65
  31. data/lib/logging/version.rb +8 -0
  32. data/lib/rspec/logging_helper.rb +3 -3
  33. data/logging.gemspec +46 -0
  34. data/test/appenders/test_buffered_io.rb +29 -0
  35. data/test/appenders/test_file.rb +2 -2
  36. data/test/appenders/test_rolling_file.rb +62 -1
  37. data/test/layouts/test_color_pattern.rb +1 -1
  38. data/test/layouts/test_json.rb +3 -0
  39. data/test/layouts/test_pattern.rb +6 -2
  40. data/test/layouts/test_yaml.rb +4 -1
  41. data/test/test_appender.rb +56 -0
  42. data/test/test_filter.rb +33 -0
  43. data/test/test_layout.rb +4 -8
  44. data/test/test_log_event.rb +3 -3
  45. data/test/test_logger.rb +81 -57
  46. data/test/test_logging.rb +0 -59
  47. data/test/test_mapped_diagnostic_context.rb +49 -1
  48. data/test/test_nested_diagnostic_context.rb +16 -1
  49. data/test/test_repository.rb +24 -32
  50. data/test/test_utils.rb +14 -50
  51. metadata +35 -53
  52. data/README.rdoc +0 -143
  53. data/data/bad_logging_1.rb +0 -13
  54. data/data/bad_logging_2.rb +0 -21
  55. data/data/logging.rb +0 -42
  56. data/data/logging.yaml +0 -63
  57. data/data/simple_logging.rb +0 -13
  58. data/examples/consolidation.rb +0 -83
  59. data/lib/logging/appenders/email.rb +0 -178
  60. data/lib/logging/appenders/growl.rb +0 -200
  61. data/lib/logging/config/configurator.rb +0 -187
  62. data/lib/logging/config/yaml_configurator.rb +0 -190
  63. data/lib/logging/stats.rb +0 -277
  64. data/test/appenders/test_email.rb +0 -170
  65. data/test/appenders/test_growl.rb +0 -138
  66. data/test/config/test_configurator.rb +0 -69
  67. data/test/config/test_yaml_configurator.rb +0 -39
  68. data/test/test_consolidate.rb +0 -45
  69. data/test/test_stats.rb +0 -273
  70. data/version.txt +0 -1
@@ -17,17 +17,17 @@ module Logging
17
17
  # :startdoc:
18
18
 
19
19
  # call-seq:
20
- # LogEvent.new( logger, level, [data], trace )
20
+ # LogEvent.new( logger, level, [data], caller_tracing )
21
21
  #
22
22
  # Creates a new log event with the given _logger_ name, numeric _level_,
23
- # array of _data_ from the user to be logged, and boolean _trace_ flag.
24
- # If the _trace_ flag is set to +true+ then Kernel::caller will be
23
+ # array of _data_ from the user to be logged, and boolean _caller_tracing_ flag.
24
+ # If the _caller_tracing_ flag is set to +true+ then Kernel::caller will be
25
25
  # invoked to get the execution trace of the logging method.
26
26
  #
27
- def initialize( logger, level, data, trace )
27
+ def initialize( logger, level, data, caller_tracing )
28
28
  f = l = m = ''
29
29
 
30
- if trace
30
+ if caller_tracing
31
31
  stack = Kernel.caller[CALLER_INDEX]
32
32
  return if stack.nil?
33
33
 
@@ -28,50 +28,36 @@ module Logging
28
28
 
29
29
  class << self
30
30
 
31
- # call-seq:
32
- # Logger.root
33
- #
34
31
  # Returns the root logger.
35
- #
36
32
  def root
37
33
  ::Logging::Repository.instance[:root]
38
34
  end
39
35
 
40
- # :stopdoc:
36
+ alias_method :instantiate, :new # the "real" new
41
37
 
42
38
  # Overrides the new method such that only one Logger will be created
43
39
  # for any given logger name.
44
- #
45
40
  def new( *args )
46
- return super if args.empty?
41
+ args.empty? ? super : self[args.shift]
42
+ end
47
43
 
44
+ # Returns a logger instance for the given name.
45
+ def []( name )
48
46
  repo = ::Logging::Repository.instance
49
- name = repo.to_key(args.shift)
47
+ name = repo.to_key(name)
48
+ logger = repo[name]
49
+ return logger unless logger.nil?
50
50
 
51
51
  @mutex.synchronize do
52
52
  logger = repo[name]
53
- if logger.nil?
54
-
55
- master = repo.master_for(name)
56
- if master
57
- if repo.has_logger?(master)
58
- logger = repo[master]
59
- else
60
- logger = super(master)
61
- repo[master] = logger
62
- repo.children(master).each {|c| c.__send__(:parent=, logger)}
63
- end
64
- repo[name] = logger
65
- else
66
- logger = super(name)
67
- repo[name] = logger
68
- repo.children(name).each {|c| c.__send__(:parent=, logger)}
69
- end
70
- end
53
+ return logger unless logger.nil? # thread-safe double checking
54
+
55
+ logger = instantiate(name)
56
+ repo[name] = logger
57
+ repo.children(name).each { |c| c.__send__(:parent=, logger) }
71
58
  logger
72
59
  end
73
60
  end
74
- alias :[] :new
75
61
 
76
62
  # This is where the actual logging methods are defined. Two methods
77
63
  # are created for each log level. The first is a query method used to
@@ -110,7 +96,7 @@ module Logging
110
96
  def #{name}?( ) true end
111
97
  def #{name}( data = nil )
112
98
  data = yield if block_given?
113
- log_event(::Logging::LogEvent.new(@name, #{num}, data, @trace))
99
+ log_event(::Logging::LogEvent.new(@name, #{num}, data, @caller_tracing))
114
100
  true
115
101
  end
116
102
  CODE
@@ -120,11 +106,9 @@ module Logging
120
106
  end
121
107
  logger
122
108
  end
123
- # :startdoc:
124
-
125
109
  end # class << self
126
110
 
127
- attr_reader :name, :parent, :additive, :trace
111
+ attr_reader :name, :parent, :additive, :caller_tracing
128
112
 
129
113
  # call-seq:
130
114
  # Logger.new( name )
@@ -183,7 +167,7 @@ module Logging
183
167
  @appenders.each {|a| a << msg}
184
168
  @parent << msg if @additive
185
169
  end
186
- alias :write :<<
170
+ alias_method :write, :<<
187
171
 
188
172
  # call-seq:
189
173
  # add( severity, message = nil ) {block}
@@ -214,7 +198,7 @@ module Logging
214
198
  return false if lvl < level
215
199
 
216
200
  data = yield if block_given?
217
- log_event(::Logging::LogEvent.new(@name, lvl, data, @trace))
201
+ log_event(::Logging::LogEvent.new(@name, lvl, data, @caller_tracing))
218
202
  true
219
203
  end
220
204
 
@@ -234,18 +218,19 @@ module Logging
234
218
  end
235
219
 
236
220
  # call-seq:
237
- # trace = true
238
- #
239
- # Sets the tracing of the logger. Acceptable values are +true+,
240
- # 'true', +false+, 'false', or +nil+. In this case +nil+ does not
241
- # change the tracing.
242
- #
243
- def trace=( val )
244
- @trace = case val
245
- when true, 'true'; true
246
- when false, 'false'; false
247
- when nil; @trace
248
- else raise ArgumentError, 'expecting a boolean' end
221
+ # caller_tracing = true
222
+ #
223
+ # Sets the caller tracing of the logger. Acceptable values are +true+,
224
+ # 'true', +false+, 'false', or +nil+. In this case +nil+ does not change
225
+ # the tracing.
226
+ #
227
+ def caller_tracing=( val )
228
+ @caller_tracing =
229
+ case val
230
+ when true, 'true'; true
231
+ when false, 'false'; false
232
+ when nil; @caller_tracing
233
+ else raise ArgumentError, 'expecting a boolean' end
249
234
  end
250
235
 
251
236
  # call-seq:
@@ -443,11 +428,13 @@ module Logging
443
428
  #
444
429
  def _setup( name, opts = {} )
445
430
  @name = name
446
- @parent = opts.getopt(:parent)
447
- @appenders = opts.getopt(:appenders, [])
448
- @additive = opts.getopt(:additive, true)
449
- @trace = opts.getopt(:trace, false)
450
- @level = opts.getopt(:level)
431
+ @parent = opts.fetch(:parent, nil)
432
+ @appenders = opts.fetch(:appenders, [])
433
+ @additive = opts.fetch(:additive, true)
434
+ @level = opts.fetch(:level, nil)
435
+
436
+ @caller_tracing = opts.fetch(:caller_tracing, false)
437
+
451
438
  ::Logging::Logger.define_log_methods(self)
452
439
  end
453
440
 
@@ -456,21 +443,21 @@ module Logging
456
443
  #
457
444
  # An internal method that is used to dump this logger's configuration to
458
445
  # the given _io_ stream. The configuration includes the logger's name,
459
- # level, additivity, and trace settings. The configured appenders are
460
- # also printed to the _io_ stream.
446
+ # level, additivity, and caller_tracing settings. The configured appenders
447
+ # are also printed to the _io_ stream.
461
448
  #
462
- def _dump_configuration( io = STDOUT, indent = 0 )
449
+ def _dump_configuration( indent = 0 )
463
450
  str, spacer, base = '', ' ', 50
464
451
  indent_str = indent == 0 ? '' : ' ' * indent
465
452
 
466
453
  str << indent_str
467
- str << self.name.reduce(base - indent)
454
+ str << self.name.shrink(base - indent)
468
455
  if (str.length + spacer.length) < base
469
456
  str << spacer
470
457
  str << '.' * (base - str.length)
471
458
  end
472
- io.write(str.ljust(base))
473
- io.write(spacer)
459
+ str = str.ljust(base)
460
+ str << spacer
474
461
 
475
462
  level_str = @level.nil? ? '' : '*'
476
463
  level_str << if level < ::Logging::LEVELS.length
@@ -480,27 +467,27 @@ module Logging
480
467
  end
481
468
  level_len = ::Logging::MAX_LEVEL_LENGTH + 1
482
469
 
483
- io.write("%#{level_len}s" % level_str)
484
- io.write(spacer)
470
+ str << sprintf("%#{level_len}s" % level_str)
471
+ str << spacer
485
472
 
486
473
  if self.respond_to?(:additive)
487
- io.write(additive ? '+A' : '-A')
474
+ str << (additive ? '+A' : '-A')
488
475
  else
489
- io.write(' ')
476
+ str << ' '
490
477
  end
491
478
 
492
- io.write(spacer)
493
- io.write(trace ? '+T' : '-T')
494
- io.write("\n")
479
+ str << spacer
480
+ str << (caller_tracing ? '+T' : '-T')
481
+ str << "\n"
495
482
 
496
483
  @appenders.each do |appender|
497
- io.write(indent_str)
498
- io.write('- ')
499
- io.write(appender.inspect)
500
- io.write("\n")
484
+ str << indent_str
485
+ str << '- '
486
+ str << appender.inspect
487
+ str << "\n"
501
488
  end
502
489
 
503
- return io
490
+ return str
504
491
  end
505
492
  # :startdoc:
506
493
 
@@ -18,7 +18,6 @@ module Logging
18
18
  # +Repository+ instance.
19
19
  #
20
20
  def initialize
21
- @masters = []
22
21
  @h = {:root => ::Logging::RootLogger.new}
23
22
 
24
23
  # configures the internal logger which is disabled by default
@@ -71,7 +70,7 @@ module Logging
71
70
  # call-seq:
72
71
  # fetch( name )
73
72
  #
74
- # Returns the +Logger+ named _name_. An +IndexError+ will be raised if
73
+ # Returns the +Logger+ named _name_. An +KeyError+ will be raised if
75
74
  # the logger does not exist.
76
75
  #
77
76
  # When _name_ is a +String+ or a +Symbol+ it will be used "as is" to
@@ -94,6 +93,29 @@ module Logging
94
93
  #
95
94
  def has_logger?( key ) @h.has_key?(to_key(key)) end
96
95
 
96
+ # call-seq:
97
+ # delete( name )
98
+ #
99
+ # Deletes the named logger from the repository. All direct children of the
100
+ # logger will have their parent reassigned. So the parent of the logger
101
+ # being deleted becomes the new parent of the children.
102
+ #
103
+ # When _name_ is a +String+ or a +Symbol+ it will be used "as is" to
104
+ # remove the logger. When _name_ is a +Class+ the class name will be
105
+ # used to remove the logger. When _name_ is an object the name of the
106
+ # object's class will be used to remove the logger.
107
+ #
108
+ # Raises a RuntimeError if you try to delete the root logger.
109
+ # Raises an KeyError if the named logger is not found.
110
+ def delete( key )
111
+ key = to_key(key)
112
+ raise 'the :root logger cannot be deleted' if :root == key
113
+
114
+ parent = @h.fetch(key).parent
115
+ children(key).each {|c| c.__send__(:parent=, parent)}
116
+ @h.delete(key)
117
+ end
118
+
97
119
  # call-seq:
98
120
  # parent( key )
99
121
  #
@@ -167,43 +189,6 @@ module Logging
167
189
  p
168
190
  end
169
191
 
170
- # call-seq:
171
- # add_master( 'First::Name', 'Second::Name', ... )
172
- #
173
- # Add the given logger names to the list of consolidation masters. All
174
- # classes in the given namespace(s) will use these loggers instead of
175
- # creating their own individual loggers.
176
- #
177
- def add_master( *args )
178
- args.map do |key|
179
- key = to_key(key)
180
- @masters << key unless @masters.include? key
181
- key
182
- end
183
- end
184
-
185
- # call-seq:
186
- # master_for( key )
187
- #
188
- # Returns the consolidation master name for the given _key_. If there is
189
- # no consolidation master, then +nil+ is returned.
190
- #
191
- def master_for( key )
192
- return if @masters.empty?
193
- key = to_key(key)
194
-
195
- loop do
196
- break key if @masters.include? key
197
- break nil if :root == key
198
-
199
- if index = key.rindex(PATH_DELIMITER)
200
- key = key.slice(0, index)
201
- else
202
- key = :root
203
- end
204
- end
205
- end
206
-
207
192
  # :stopdoc:
208
193
  def self.reset
209
194
  if defined?(@singleton__instance__)
@@ -26,7 +26,7 @@ module Logging
26
26
  @name = 'root'
27
27
  @appenders = []
28
28
  @additive = false
29
- @trace = false
29
+ @caller_tracing = false
30
30
  @level = 0
31
31
  ::Logging::Logger.define_log_methods(self)
32
32
  end
@@ -2,61 +2,19 @@
2
2
  require 'thread'
3
3
  require 'rbconfig'
4
4
 
5
- # --------------------------------------------------------------------------
6
- class Hash
7
-
8
- # call-seq:
9
- # getopt( key, default = nil, :as => class )
10
- #
11
- # Returns the value associated with the _key_. If the has does not contain
12
- # the _key_, then the _default_ value is returned.
13
- #
14
- # Optionally, the value can be converted into to an instance of the given
15
- # _class_. The supported classes are:
16
- #
17
- # Integer
18
- # Float
19
- # Array
20
- # String
21
- # Symbol
22
- #
23
- # If the value is +nil+, then no conversion will be performed.
24
- #
25
- def getopt( *args )
26
- opts = args.last.instance_of?(Hash) ? args.pop : {}
27
- key, default = args
28
-
29
- val = if has_key?(key); self[key]
30
- elsif has_key?(key.to_s); self[key.to_s]
31
- elsif has_key?(key.to_s.intern); self[key.to_s.intern]
32
- else default end
33
-
34
- return if val.nil?
35
- return val unless opts.has_key?(:as)
36
-
37
- case opts[:as].name.intern
38
- when :Integer; Integer(val)
39
- when :Float; Float(val)
40
- when :Array; Array(val)
41
- when :String; String(val)
42
- when :Symbol; String(val).intern
43
- else val end
44
- end
45
- end
46
-
47
5
  # --------------------------------------------------------------------------
48
6
  class String
49
7
 
50
8
  # call-seq:
51
- # reduce( width, ellipses = '...' ) #=> string
9
+ # shrink( width, ellipses = '...' ) #=> string
52
10
  #
53
- # Reduce the size of the current string to the given _width_ by removing
11
+ # Shrink the size of the current string to the given _width_ by removing
54
12
  # characters from the middle of the string and replacing them with
55
13
  # _ellipses_. If the _width_ is greater than the length of the string, the
56
14
  # string is returned unchanged. If the _width_ is less than the length of
57
15
  # the _ellipses_, then the _ellipses_ are returned.
58
16
  #
59
- def reduce( width, ellipses = '...')
17
+ def shrink( width, ellipses = '...')
60
18
  raise ArgumentError, "width cannot be negative: #{width}" if width < 0
61
19
 
62
20
  return self if length <= width
@@ -108,25 +66,6 @@ class Module
108
66
  end
109
67
  end
110
68
 
111
- # --------------------------------------------------------------------------
112
- module Kernel
113
-
114
- # call-seq:
115
- # require?( string )
116
- #
117
- # Attempt to the load the library named _string_ using the standard
118
- # Kernel#require method. Returns +true+ if the library was successfully
119
- # loaded. Returns +false+ if the library could not be loaded. This method
120
- # will never raise an exception.
121
- #
122
- def require?( string )
123
- require string
124
- return true
125
- rescue LoadError
126
- return false
127
- end
128
- end # module Kernel
129
-
130
69
  # --------------------------------------------------------------------------
131
70
  class File
132
71
 
@@ -211,7 +150,7 @@ class ReentrantMutex < Mutex
211
150
  @locker = nil
212
151
  end
213
152
 
214
- alias :original_synchronize :synchronize
153
+ alias_method :original_synchronize, :synchronize
215
154
 
216
155
  def synchronize
217
156
  if @locker == Thread.current
@@ -0,0 +1,8 @@
1
+ module Logging
2
+ VERSION = "2.0.0".freeze
3
+
4
+ # Returns the version string for the library.
5
+ def self.version
6
+ VERSION
7
+ end
8
+ end