logging 1.4.3 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/History.txt +8 -0
  2. data/Rakefile +2 -4
  3. data/examples/colorization.rb +62 -0
  4. data/lib/logging.rb +22 -8
  5. data/lib/logging/appender.rb +7 -7
  6. data/lib/logging/appenders/buffering.rb +30 -24
  7. data/lib/logging/appenders/email.rb +7 -11
  8. data/lib/logging/appenders/file.rb +0 -1
  9. data/lib/logging/appenders/io.rb +8 -14
  10. data/lib/logging/appenders/rolling_file.rb +9 -13
  11. data/lib/logging/appenders/string_io.rb +0 -1
  12. data/lib/logging/appenders/syslog.rb +1 -1
  13. data/lib/logging/color_scheme.rb +249 -0
  14. data/lib/logging/layouts/basic.rb +2 -3
  15. data/lib/logging/layouts/parseable.rb +5 -7
  16. data/lib/logging/layouts/pattern.rb +77 -18
  17. data/lib/logging/log_event.rb +1 -1
  18. data/lib/logging/logger.rb +3 -4
  19. data/lib/logging/proxy.rb +57 -0
  20. data/lib/logging/utils.rb +3 -2
  21. data/test/appenders/test_buffered_io.rb +2 -7
  22. data/test/appenders/test_console.rb +1 -1
  23. data/test/appenders/test_email.rb +1 -1
  24. data/test/appenders/test_file.rb +1 -1
  25. data/test/appenders/test_growl.rb +1 -1
  26. data/test/appenders/test_io.rb +4 -5
  27. data/test/appenders/test_rolling_file.rb +1 -1
  28. data/test/appenders/test_syslog.rb +1 -1
  29. data/test/benchmark.rb +15 -11
  30. data/test/config/test_configurator.rb +1 -1
  31. data/test/config/test_yaml_configurator.rb +1 -1
  32. data/test/layouts/test_basic.rb +1 -1
  33. data/test/layouts/test_color_pattern.rb +90 -0
  34. data/test/layouts/test_json.rb +1 -1
  35. data/test/layouts/test_pattern.rb +4 -5
  36. data/test/layouts/test_yaml.rb +1 -1
  37. data/test/test_appender.rb +1 -1
  38. data/test/test_color_scheme.rb +39 -0
  39. data/test/test_consolidate.rb +1 -1
  40. data/test/test_layout.rb +1 -1
  41. data/test/test_log_event.rb +1 -1
  42. data/test/test_logger.rb +1 -1
  43. data/test/test_logging.rb +1 -1
  44. data/test/test_proxy.rb +67 -0
  45. data/test/test_repository.rb +2 -2
  46. data/test/test_root_logger.rb +1 -1
  47. data/test/test_stats.rb +1 -1
  48. data/test/test_utils.rb +1 -1
  49. data/version.txt +1 -1
  50. metadata +40 -17
@@ -11,7 +11,7 @@ module Logging
11
11
  # * $1 == filename
12
12
  # * $2 == line number
13
13
  # * $3 == method name (might be nil)
14
- CALLER_RGXP = %r/([\.\/\(\)\w]+):(\d+)(?::in `(\w+)')?/o
14
+ CALLER_RGXP = %r/([-\.\/\(\)\w]+):(\d+)(?::in `(\w+)')?/o
15
15
  CALLER_INDEX = 2
16
16
  #CALLER_INDEX = RUBY_PLATFORM[%r/^java/i] ? 1 : 2
17
17
  # :startdoc:
@@ -434,7 +434,7 @@ module Logging
434
434
  #
435
435
  # Configures internal variables for the logger. This method can be used
436
436
  # to avoid storing the logger in the repository.
437
- #
437
+ #
438
438
  def _setup( name, opts = {} )
439
439
  @name = name
440
440
  @parent = opts.getopt(:parent)
@@ -498,7 +498,6 @@ module Logging
498
498
  end
499
499
  # :startdoc:
500
500
 
501
- end # class Logger
502
- end # module Logging
501
+ end # Logger
502
+ end # Logging
503
503
 
504
- # EOF
@@ -0,0 +1,57 @@
1
+
2
+ module Logging
3
+
4
+ # Defines a Proxy that will log all method calls on the proxied object. This
5
+ # class uses +method_missing+ on a "blank slate" object to intercept all
6
+ # method calls. The method name being called and the arguments are all
7
+ # logged to the proxied object's logger instance. The log level and other
8
+ # settings for the proxied object are honored by the Proxy instance.
9
+ #
10
+ # If you want, you can also supply your own +method_missing+ code as a block
11
+ # to the constructor.
12
+ #
13
+ # Proxy.new(object) do |name, *args, &block|
14
+ # # code to be executed before the proxied method
15
+ # result = @object.send(name, *args, &block)
16
+ # # code to be executed after the proxied method
17
+ # result # <-- always return the result
18
+ # end
19
+ #
20
+ # The proxied object is avaiable as the "@object" variable. The logger is
21
+ # available as the "@logger" variable.
22
+ #
23
+ class Proxy
24
+
25
+ # :stopdoc:
26
+ KEEPERS = %r/^__|^object_id$|^initialize$/
27
+ instance_methods(true).each { |m| undef_method m unless m[KEEPERS] }
28
+ private_instance_methods(true).each { |m| undef_method m unless m[KEEPERS] }
29
+ # :startdoc:
30
+
31
+ # Create a new proxy for the given _object_. If an optional _block_ is
32
+ # given it will be called before the proxied method. This _block_ will
33
+ # replace the +method_missing+ implementation
34
+ #
35
+ def initialize( object, &block )
36
+ @object = object
37
+ @leader = @object.is_a?(Class) ? "#{@object.name}." : "#{@object.class.name}#"
38
+ @logger = Logging.logger[object]
39
+
40
+ if block
41
+ eigenclass = class << self; self; end
42
+ eigenclass.__send__(:define_method, :method_missing, &block)
43
+ end
44
+ end
45
+
46
+ # All hail the magic of method missing. Here is where we are going to log
47
+ # the method call and then forward to the proxied object. The return value
48
+ # from the proxied objet method call is passed back.
49
+ #
50
+ def method_missing( name, *args, &block )
51
+ @logger << "#@leader#{name}(#{args.inspect[1..-2]})\n"
52
+ @object.send(name, *args, &block)
53
+ end
54
+
55
+ end # Proxy
56
+ end # Logging
57
+
data/lib/logging/utils.rb CHANGED
@@ -1,4 +1,6 @@
1
1
 
2
+ require 'thread'
3
+
2
4
  # --------------------------------------------------------------------------
3
5
  class Hash
4
6
 
@@ -196,6 +198,5 @@ class ReentrantMutex < Mutex
196
198
  }
197
199
  end
198
200
  end
199
- end # class ReentrantMutex
201
+ end # ReentrantMutex
200
202
 
201
- # EOF
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../setup', File.dirname(__FILE__))
3
3
 
4
4
  module TestLogging
5
5
  module TestAppenders
@@ -135,15 +135,10 @@ module TestAppenders
135
135
  end
136
136
 
137
137
  def test_flush
138
- ary = []
139
- @sio.instance_variable_set :@ary, ary
140
- def @sio.flush() @ary << :flush end
141
-
142
138
  @appender << "this is a test message\n"
143
139
  assert_nil(readline)
144
140
 
145
141
  @appender.flush
146
- assert_equal :flush, ary.pop
147
142
  assert_equal "this is a test message\n", readline
148
143
  assert_nil(readline)
149
144
  end
@@ -163,7 +158,7 @@ module TestAppenders
163
158
  assert_nil(readline)
164
159
  end
165
160
 
166
- private
161
+ private
167
162
  def readline
168
163
  @appender.readline
169
164
  end
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../setup', File.dirname(__FILE__))
3
3
 
4
4
  module TestLogging
5
5
  module TestAppenders
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../setup', File.dirname(__FILE__))
3
3
  require 'flexmock'
4
4
 
5
5
  module TestLogging
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../setup', File.dirname(__FILE__))
3
3
 
4
4
  module TestLogging
5
5
  module TestAppenders
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../setup', File.dirname(__FILE__))
3
3
  require 'flexmock'
4
4
 
5
5
  module TestLogging
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../setup', File.dirname(__FILE__))
3
3
 
4
4
  module TestLogging
5
5
  module TestAppenders
@@ -103,12 +103,11 @@ module TestAppenders
103
103
  end
104
104
 
105
105
  def test_flush
106
- ary = []
107
- @sio.instance_variable_set :@ary, ary
108
- def @sio.flush() @ary << :flush end
106
+ @appender.buffer << 'flush'
107
+ assert_nil @appender.readline
109
108
 
110
109
  @appender.flush
111
- assert_equal :flush, ary.pop
110
+ assert_equal 'flush', @appender.readline
112
111
  end
113
112
 
114
113
  def test_initialize
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../setup', File.dirname(__FILE__))
3
3
 
4
4
  module TestLogging
5
5
  module TestAppenders
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../setup', File.dirname(__FILE__))
3
3
 
4
4
  if HAVE_SYSLOG
5
5
 
data/test/benchmark.rb CHANGED
@@ -1,15 +1,11 @@
1
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
2
+ require 'rubygems'
3
+
4
+ libpath = File.expand_path('../../lib', __FILE__)
5
+ $:.unshift libpath
6
+ require 'logging'
10
7
 
11
8
  begin
12
- require 'rubygems'
13
9
  gem 'log4r'
14
10
  require 'log4r'
15
11
  $log4r = true
@@ -26,10 +22,18 @@ module Logging
26
22
  def run
27
23
  this_many = 300_000
28
24
 
29
- sio = StringIO.new
25
+ Logging.appenders.string_io(
26
+ 'sio',
27
+ :layout => Logging.layouts.pattern(
28
+ :pattern => '%.1l, [%d] %5l -- %c: %m\n',
29
+ :date_pattern => "%Y-%m-%dT%H:%M:%S.%s"
30
+ )
31
+ )
32
+ sio = Logging.appenders['sio'].sio
30
33
 
31
- logging = ::Logging.logger sio
34
+ logging = ::Logging.logger('benchmark')
32
35
  logging.level = :warn
36
+ logging.appenders = 'sio'
33
37
 
34
38
  logger = ::Logger.new sio
35
39
  logger.level = ::Logger::WARN
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../setup', File.dirname(__FILE__))
3
3
 
4
4
  module TestLogging
5
5
  module TestConfig
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../setup', File.dirname(__FILE__))
3
3
 
4
4
  module TestLogging
5
5
  module TestConfig
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../setup', File.dirname(__FILE__))
3
3
 
4
4
  module TestLogging
5
5
  module TestLayouts
@@ -0,0 +1,90 @@
1
+
2
+ require File.expand_path('../../setup', __FILE__)
3
+
4
+ module TestLogging
5
+ module TestLayouts
6
+
7
+ class TestColorPattern < Test::Unit::TestCase
8
+ include LoggingTestCase
9
+ CS = ::Logging::ColorScheme
10
+
11
+ def setup
12
+ super
13
+
14
+ ::Logging.color_scheme :levels, :levels => {
15
+ :debug => :blue, :info => :green, :warn => :yellow, :error => :red, :fatal => :cyan
16
+ }
17
+
18
+ ::Logging.color_scheme :lines, :lines => {
19
+ :debug => :blue, :info => :green, :warn => :yellow, :error => :red, :fatal => :cyan
20
+ }, :date => :blue, :logger => :cyan
21
+
22
+ ::Logging.color_scheme :tokens, :date => :blue, :logger => :green, :message => :magenta
23
+
24
+ @levels = Logging::LEVELS
25
+ end
26
+
27
+ def test_level_coloring
28
+ layout = Logging.layouts.pattern(:color_scheme => :levels)
29
+ event = Logging::LogEvent.new('ArrayLogger', @levels['info'], 'log message', false)
30
+
31
+ rgxp = Regexp.new(Regexp.escape("#{CS::GREEN}INFO #{CS::RESET}"))
32
+ assert_match rgxp, layout.format(event)
33
+
34
+ event.level = @levels['debug']
35
+ rgxp = Regexp.new(Regexp.escape("#{CS::BLUE}DEBUG#{CS::RESET}"))
36
+ assert_match rgxp, layout.format(event)
37
+
38
+ event.level = @levels['error']
39
+ rgxp = Regexp.new(Regexp.escape("#{CS::RED}ERROR#{CS::RESET}"))
40
+ assert_match rgxp, layout.format(event)
41
+ end
42
+
43
+ def test_multiple_level_coloring
44
+ layout = Logging.layouts.pattern(:pattern => '%.1l, %5l -- %c: %m\n', :color_scheme => :levels)
45
+ event = Logging::LogEvent.new('ArrayLogger', @levels['info'], 'log message', false)
46
+
47
+ rgxp = Regexp.new(Regexp.escape("#{CS::GREEN}I#{CS::RESET}, #{CS::GREEN} INFO#{CS::RESET}"))
48
+ assert_match rgxp, layout.format(event)
49
+
50
+ event.level = @levels['debug']
51
+ rgxp = Regexp.new(Regexp.escape("#{CS::BLUE}D#{CS::RESET}, #{CS::BLUE}DEBUG#{CS::RESET}"))
52
+ assert_match rgxp, layout.format(event)
53
+
54
+ event.level = @levels['error']
55
+ rgxp = Regexp.new(Regexp.escape("#{CS::RED}E#{CS::RESET}, #{CS::RED}ERROR#{CS::RESET}"))
56
+ assert_match rgxp, layout.format(event)
57
+ end
58
+
59
+ def test_line_coloring
60
+ layout = Logging.layouts.pattern(:color_scheme => :lines)
61
+ event = Logging::LogEvent.new('ArrayLogger', @levels['info'], 'log message', false)
62
+
63
+ rgxp = Regexp.new('^'+Regexp.escape(CS::GREEN)+'.*?'+Regexp.escape(CS::RESET)+'$', Regexp::MULTILINE)
64
+ assert_match rgxp, layout.format(event)
65
+
66
+ event.level = @levels['error']
67
+ rgxp = Regexp.new('^'+Regexp.escape(CS::RED)+'.*?'+Regexp.escape(CS::RESET)+'$', Regexp::MULTILINE)
68
+ assert_match rgxp, layout.format(event)
69
+
70
+ event.level = @levels['warn']
71
+ rgxp = Regexp.new('^'+Regexp.escape(CS::YELLOW)+'.*?'+Regexp.escape(CS::RESET)+'$', Regexp::MULTILINE)
72
+ assert_match rgxp, layout.format(event)
73
+ end
74
+
75
+ def test_token_coloring
76
+ layout = Logging.layouts.pattern(:color_scheme => :tokens)
77
+ event = Logging::LogEvent.new('ArrayLogger', @levels['info'], 'log message', false)
78
+
79
+ rgxp = Regexp.new(
80
+ '^\['+Regexp.escape(CS::BLUE)+'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}'+Regexp.escape(CS::RESET)+
81
+ '\] INFO -- '+Regexp.escape(CS::GREEN)+'ArrayLogger'+Regexp.escape(CS::RESET)+
82
+ ' : '+Regexp.escape(CS::MAGENTA)+'log message'+Regexp.escape(CS::RESET)
83
+ )
84
+ assert_match rgxp, layout.format(event)
85
+ end
86
+
87
+ end # TestColorPattern
88
+ end # TestLayouts
89
+ end # TestLogging
90
+
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../setup', File.dirname(__FILE__))
3
3
 
4
4
  module TestLogging
5
5
  module TestLayouts
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../../setup', __FILE__)
3
3
 
4
4
  module TestLogging
5
5
  module TestLayouts
@@ -191,8 +191,7 @@ module TestLayouts
191
191
  assert_equal 'message{42}', @layout.format(event)
192
192
  end
193
193
 
194
- end # class TestBasic
195
- end # module TestLayouts
196
- end # module TestLogging
194
+ end # TestBasic
195
+ end # TestLayouts
196
+ end # TestLogging
197
197
 
198
- # EOF
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[.. setup])
2
+ require File.expand_path('../setup', File.dirname(__FILE__))
3
3
 
4
4
  module TestLogging
5
5
  module TestLayouts
@@ -1,5 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), %w[setup])
2
+ require File.expand_path('setup', File.dirname(__FILE__))
3
3
 
4
4
  module TestLogging
5
5
 
@@ -0,0 +1,39 @@
1
+
2
+ require File.expand_path('../setup', __FILE__)
3
+
4
+ module TestLogging
5
+
6
+ class TestColorScheme < Test::Unit::TestCase
7
+ include LoggingTestCase
8
+
9
+ def setup
10
+ super
11
+ ::Logging.init
12
+ end
13
+
14
+ def test_default_color_scheme
15
+ scheme = Logging.color_scheme :default
16
+ assert_instance_of ::Logging::ColorScheme, scheme
17
+
18
+ assert_equal false, scheme.include?(:debug)
19
+ assert scheme.include?(:info)
20
+ assert scheme.include?(:warn)
21
+ assert scheme.include?(:error)
22
+ assert scheme.include?(:fatal)
23
+ end
24
+
25
+ def test_lines_levels_exclusivity
26
+ assert_raise(ArgumentError) { Logging.color_scheme(:error, :lines => {}, :levels => {}) }
27
+ end
28
+
29
+ def test_colorization
30
+ scheme = Logging.color_scheme :default
31
+
32
+ assert_equal "no change", scheme.color('no change', :debug)
33
+ assert_equal "\e[32minfo is green\e[0m", scheme.color('info is green', :info)
34
+ assert_equal "\e[37m\e[41mfatal has multiple color codes\e[0m", scheme.color('fatal has multiple color codes', :fatal)
35
+ end
36
+
37
+ end # TestColorScheme
38
+ end # TestLogging
39
+