logging 1.4.3 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +8 -0
- data/Rakefile +2 -4
- data/examples/colorization.rb +62 -0
- data/lib/logging.rb +22 -8
- data/lib/logging/appender.rb +7 -7
- data/lib/logging/appenders/buffering.rb +30 -24
- data/lib/logging/appenders/email.rb +7 -11
- data/lib/logging/appenders/file.rb +0 -1
- data/lib/logging/appenders/io.rb +8 -14
- data/lib/logging/appenders/rolling_file.rb +9 -13
- data/lib/logging/appenders/string_io.rb +0 -1
- data/lib/logging/appenders/syslog.rb +1 -1
- data/lib/logging/color_scheme.rb +249 -0
- data/lib/logging/layouts/basic.rb +2 -3
- data/lib/logging/layouts/parseable.rb +5 -7
- data/lib/logging/layouts/pattern.rb +77 -18
- data/lib/logging/log_event.rb +1 -1
- data/lib/logging/logger.rb +3 -4
- data/lib/logging/proxy.rb +57 -0
- data/lib/logging/utils.rb +3 -2
- data/test/appenders/test_buffered_io.rb +2 -7
- data/test/appenders/test_console.rb +1 -1
- data/test/appenders/test_email.rb +1 -1
- data/test/appenders/test_file.rb +1 -1
- data/test/appenders/test_growl.rb +1 -1
- data/test/appenders/test_io.rb +4 -5
- data/test/appenders/test_rolling_file.rb +1 -1
- data/test/appenders/test_syslog.rb +1 -1
- data/test/benchmark.rb +15 -11
- data/test/config/test_configurator.rb +1 -1
- data/test/config/test_yaml_configurator.rb +1 -1
- data/test/layouts/test_basic.rb +1 -1
- data/test/layouts/test_color_pattern.rb +90 -0
- data/test/layouts/test_json.rb +1 -1
- data/test/layouts/test_pattern.rb +4 -5
- data/test/layouts/test_yaml.rb +1 -1
- data/test/test_appender.rb +1 -1
- data/test/test_color_scheme.rb +39 -0
- data/test/test_consolidate.rb +1 -1
- data/test/test_layout.rb +1 -1
- data/test/test_log_event.rb +1 -1
- data/test/test_logger.rb +1 -1
- data/test/test_logging.rb +1 -1
- data/test/test_proxy.rb +67 -0
- data/test/test_repository.rb +2 -2
- data/test/test_root_logger.rb +1 -1
- data/test/test_stats.rb +1 -1
- data/test/test_utils.rb +1 -1
- data/version.txt +1 -1
- metadata +40 -17
data/History.txt
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 1.5.0 / 2011-03-22
|
2
|
+
|
3
|
+
Minor Enhancements
|
4
|
+
- removed mutexes in favor of IO#syswrite
|
5
|
+
- no round tripping through the buffer array when auto_flushing is true
|
6
|
+
- added a Proxy object that will log all methods called on it
|
7
|
+
- colorization of log messages
|
8
|
+
|
1
9
|
== 1.4.3 / 2010-05-31
|
2
10
|
|
3
11
|
Bug Fixes
|
data/Rakefile
CHANGED
@@ -14,12 +14,10 @@ Bones {
|
|
14
14
|
authors 'Tim Pease'
|
15
15
|
email 'tim.pease@gmail.com'
|
16
16
|
url 'http://rubygems.org/gems/logging'
|
17
|
-
readme_file 'README.rdoc'
|
18
|
-
ignore_file '.gitignore'
|
19
17
|
|
20
18
|
rdoc.exclude << '^data'
|
21
19
|
rdoc.include << '^examples/.*\.rb'
|
22
|
-
|
20
|
+
rcov.opts << '-x' << '~/.rvm/'
|
23
21
|
|
24
22
|
use_gmail
|
25
23
|
|
@@ -27,6 +25,6 @@ Bones {
|
|
27
25
|
|
28
26
|
depend_on 'flexmock', :development => true
|
29
27
|
depend_on 'bones-git', :development => true
|
30
|
-
depend_on 'bones-
|
28
|
+
depend_on 'bones-rcov', :development => true
|
31
29
|
}
|
32
30
|
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# :stopdoc:
|
2
|
+
#
|
3
|
+
# The Pattern layout can colorize log events based on a provided color scheme.
|
4
|
+
# The configuration is a two part process. First the color scheme is defined
|
5
|
+
# with the level colors and any pattern token colors. This color scheme is
|
6
|
+
# then passed by name to the Pattern layout when it is created.
|
7
|
+
#
|
8
|
+
# The color scheme defines colors to be applied to the level token found in
|
9
|
+
# the pattern layout. So that the "info" level will have one color, and the
|
10
|
+
# "fatal" level will have a separate color. This applies only to the level
|
11
|
+
# token in the Pattern layout.
|
12
|
+
#
|
13
|
+
# Common tokens can have their own color, too. The date token can be colored
|
14
|
+
# blue, and the message token can be colored magenta.
|
15
|
+
#
|
16
|
+
# Colorization should only be applied to TTY logging destinations like STDOUT
|
17
|
+
# and STDERR. Inserting color codes into a log file is generally considered
|
18
|
+
# bad from; these color codes cause issues for some command lien programs like
|
19
|
+
# "less" and "more".
|
20
|
+
#
|
21
|
+
# A 'default" color scheme is provided with the Logging framework. In the
|
22
|
+
# example below we create our own color scheme called 'bright' and apply it to
|
23
|
+
# the 'stdout' appender.
|
24
|
+
#
|
25
|
+
|
26
|
+
require 'logging'
|
27
|
+
|
28
|
+
# here we setup a color scheme called 'bright'
|
29
|
+
Logging.color_scheme( 'bright',
|
30
|
+
:levels => {
|
31
|
+
:info => :green,
|
32
|
+
:warn => :yellow,
|
33
|
+
:error => :red,
|
34
|
+
:fatal => [:white, :on_red]
|
35
|
+
},
|
36
|
+
:date => :blue,
|
37
|
+
:logger => :cyan,
|
38
|
+
:message => :magenta
|
39
|
+
)
|
40
|
+
|
41
|
+
Logging.appenders.stdout(
|
42
|
+
'stdout',
|
43
|
+
:layout => Logging.layouts.pattern(
|
44
|
+
:pattern => '[%d] %-5l %c: %m\n',
|
45
|
+
:color_scheme => 'bright'
|
46
|
+
)
|
47
|
+
)
|
48
|
+
|
49
|
+
log = Logging.logger['Happy::Colors']
|
50
|
+
log.add_appenders 'stdout'
|
51
|
+
log.level = :debug
|
52
|
+
|
53
|
+
# these log messages will be nicely colored
|
54
|
+
# the level will be colored differently for each message
|
55
|
+
#
|
56
|
+
log.debug "a very nice little debug message"
|
57
|
+
log.info "things are operating nominally"
|
58
|
+
log.warn "this is your last warning"
|
59
|
+
log.error StandardError.new("something went horribly wrong")
|
60
|
+
log.fatal "I Die!"
|
61
|
+
|
62
|
+
# :startdoc:
|
data/lib/logging.rb
CHANGED
@@ -3,12 +3,10 @@
|
|
3
3
|
# Used to prevent the class/module from being loaded more than once
|
4
4
|
unless defined? Logging
|
5
5
|
|
6
|
-
require File.expand_path(
|
7
|
-
File.join(File.dirname(__FILE__), %w[logging utils]))
|
6
|
+
require File.expand_path('../logging/utils', __FILE__)
|
8
7
|
|
9
8
|
require 'yaml'
|
10
9
|
require 'stringio'
|
11
|
-
require 'thread'
|
12
10
|
require 'fileutils'
|
13
11
|
require 'little-plugger'
|
14
12
|
|
@@ -20,8 +18,8 @@ module Logging
|
|
20
18
|
extend LittlePlugger
|
21
19
|
|
22
20
|
# :stopdoc:
|
23
|
-
LIBPATH = ::File.expand_path(
|
24
|
-
PATH = ::File.
|
21
|
+
LIBPATH = ::File.expand_path('..', __FILE__) + ::File::SEPARATOR
|
22
|
+
PATH = ::File.expand_path('../..', __FILE__) + ::File::SEPARATOR
|
25
23
|
LEVELS = {}
|
26
24
|
LNAMES = []
|
27
25
|
module Plugins; end
|
@@ -161,6 +159,21 @@ module Logging
|
|
161
159
|
::Logging::Appenders
|
162
160
|
end
|
163
161
|
|
162
|
+
# Returns the color scheme identified by the given _name_. If there is no
|
163
|
+
# color scheme +nil+ is returned.
|
164
|
+
#
|
165
|
+
# If color scheme options are supplied then a new color scheme is created.
|
166
|
+
# Any existing color scheme with the given _name_ will be replaced by the
|
167
|
+
# new color scheme.
|
168
|
+
#
|
169
|
+
def color_scheme( name, opts = {} )
|
170
|
+
if opts.empty?
|
171
|
+
::Logging::ColorScheme[name]
|
172
|
+
else
|
173
|
+
::Logging::ColorScheme.new(name, opts)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
164
177
|
# Reopen all appenders. This method should be called immediately after a
|
165
178
|
# fork to ensure no conflict with file descriptors and calls to fcntl or
|
166
179
|
# flock.
|
@@ -290,7 +303,6 @@ module Logging
|
|
290
303
|
module_eval "MAX_LEVEL_LENGTH = #{longest.length}", __FILE__, __LINE__
|
291
304
|
|
292
305
|
initialize_plugins
|
293
|
-
|
294
306
|
levels.keys
|
295
307
|
end
|
296
308
|
|
@@ -468,7 +480,7 @@ module Logging
|
|
468
480
|
|
469
481
|
# Convert the given level into a level number.
|
470
482
|
def level_num( level )
|
471
|
-
l = levelify level
|
483
|
+
l = levelify(level) rescue level
|
472
484
|
case l
|
473
485
|
when 'all'; 0
|
474
486
|
when 'off'; LEVELS.length
|
@@ -490,6 +502,7 @@ module Logging
|
|
490
502
|
def reset
|
491
503
|
::Logging::Repository.reset
|
492
504
|
::Logging::Appenders.reset
|
505
|
+
::Logging::ColorScheme.reset
|
493
506
|
LEVELS.clear
|
494
507
|
LNAMES.clear
|
495
508
|
remove_instance_variable :@backtrace if defined? @backtrace
|
@@ -509,8 +522,10 @@ Logging.libpath {
|
|
509
522
|
require 'logging/repository'
|
510
523
|
require 'logging/root_logger'
|
511
524
|
require 'logging/stats'
|
525
|
+
require 'logging/color_scheme'
|
512
526
|
require 'logging/appenders'
|
513
527
|
require 'logging/layouts'
|
528
|
+
require 'logging/proxy'
|
514
529
|
|
515
530
|
require 'logging/config/configurator'
|
516
531
|
require 'logging/config/yaml_configurator'
|
@@ -525,4 +540,3 @@ at_exit {Logging.shutdown}
|
|
525
540
|
|
526
541
|
end # unless defined?
|
527
542
|
|
528
|
-
# EOF
|
data/lib/logging/appender.rb
CHANGED
@@ -45,8 +45,8 @@ class Appender
|
|
45
45
|
header = @layout.header
|
46
46
|
|
47
47
|
unless header.nil? || header.empty?
|
48
|
-
begin
|
49
|
-
|
48
|
+
begin
|
49
|
+
write(header)
|
50
50
|
rescue StandardError => err
|
51
51
|
::Logging.log_internal(-2) {err}
|
52
52
|
end
|
@@ -71,7 +71,7 @@ class Appender
|
|
71
71
|
# appender level
|
72
72
|
unless @level > event.level
|
73
73
|
begin
|
74
|
-
|
74
|
+
write(event)
|
75
75
|
rescue StandardError => err
|
76
76
|
::Logging.log_internal(-2) {err}
|
77
77
|
end
|
@@ -94,7 +94,7 @@ class Appender
|
|
94
94
|
|
95
95
|
unless @level >= ::Logging::LEVELS.length
|
96
96
|
begin
|
97
|
-
|
97
|
+
write(str)
|
98
98
|
rescue StandardError => err
|
99
99
|
::Logging.log_internal(-2) {err}
|
100
100
|
end
|
@@ -170,13 +170,13 @@ class Appender
|
|
170
170
|
::Logging::Appenders.remove(@name)
|
171
171
|
@closed = true
|
172
172
|
|
173
|
-
|
173
|
+
flush
|
174
174
|
|
175
175
|
if footer
|
176
176
|
footer = @layout.footer
|
177
177
|
unless footer.nil? || footer.empty?
|
178
178
|
begin
|
179
|
-
|
179
|
+
write(footer)
|
180
180
|
rescue StandardError => err
|
181
181
|
::Logging.log_internal(-2) {err}
|
182
182
|
end
|
@@ -229,7 +229,7 @@ class Appender
|
|
229
229
|
end
|
230
230
|
|
231
231
|
|
232
|
-
|
232
|
+
private
|
233
233
|
|
234
234
|
# call-seq:
|
235
235
|
# write( event )
|
@@ -26,12 +26,20 @@ module Logging::Appenders
|
|
26
26
|
#
|
27
27
|
attr_reader :auto_flushing
|
28
28
|
|
29
|
-
#
|
30
|
-
#
|
31
|
-
# and it should clear the buffer when done.
|
29
|
+
# Call +flush+ to force an appender to write out any buffered log events.
|
30
|
+
# Similar to IO#flush, so use in a similar fashion.
|
32
31
|
#
|
33
32
|
def flush
|
34
|
-
|
33
|
+
return self if @buffer.empty?
|
34
|
+
|
35
|
+
str = nil
|
36
|
+
sync {
|
37
|
+
str = @buffer.join
|
38
|
+
@buffer.clear
|
39
|
+
}
|
40
|
+
|
41
|
+
canonical_write str unless str.empty?
|
42
|
+
self
|
35
43
|
end
|
36
44
|
|
37
45
|
# Configure the levels that will trigger and immediate flush of the
|
@@ -61,7 +69,7 @@ module Logging::Appenders
|
|
61
69
|
when String; level.split(',').map {|x| x.strip}
|
62
70
|
when Array; level
|
63
71
|
else Array(level) end
|
64
|
-
|
72
|
+
|
65
73
|
immediate_at.each do |lvl|
|
66
74
|
num = ::Logging.level_num(lvl)
|
67
75
|
next if num.nil?
|
@@ -108,7 +116,7 @@ module Logging::Appenders
|
|
108
116
|
end
|
109
117
|
|
110
118
|
|
111
|
-
|
119
|
+
protected
|
112
120
|
|
113
121
|
# Configure the buffering using the arguments found in the give options
|
114
122
|
# hash. This method must be called in order to use the message buffer.
|
@@ -124,20 +132,6 @@ module Logging::Appenders
|
|
124
132
|
self.auto_flushing = opts.getopt(:auto_flushing, true)
|
125
133
|
end
|
126
134
|
|
127
|
-
# Append the given event to the message buffer. The event can be either
|
128
|
-
# a string or a LogEvent object.
|
129
|
-
#
|
130
|
-
def add_to_buffer( event )
|
131
|
-
str = event.instance_of?(::Logging::LogEvent) ?
|
132
|
-
layout.format(event) : event.to_s
|
133
|
-
return if str.empty?
|
134
|
-
|
135
|
-
buffer << str
|
136
|
-
flush if buffer.length >= auto_flushing || immediate?(event)
|
137
|
-
|
138
|
-
self
|
139
|
-
end
|
140
|
-
|
141
135
|
# Returns true if the _event_ level matches one of the configured
|
142
136
|
# immediate logging levels. Otherwise returns false.
|
143
137
|
#
|
@@ -147,7 +141,7 @@ module Logging::Appenders
|
|
147
141
|
end
|
148
142
|
|
149
143
|
|
150
|
-
|
144
|
+
private
|
151
145
|
|
152
146
|
# call-seq:
|
153
147
|
# write( event )
|
@@ -156,13 +150,25 @@ module Logging::Appenders
|
|
156
150
|
# be either a LogEvent or a String. If a LogEvent, then it will be
|
157
151
|
# formatted using the layout given to the appender when it was created.
|
158
152
|
#
|
153
|
+
# The _event_ will be formatted and then buffered until the
|
154
|
+
# "auto_flushing" level has been reached. At thsi time the canonical_write
|
155
|
+
# method will be used to log all events stored in the buffer.
|
156
|
+
#
|
159
157
|
def write( event )
|
160
|
-
|
158
|
+
str = event.instance_of?(::Logging::LogEvent) ?
|
159
|
+
layout.format(event) : event.to_s
|
160
|
+
return if str.empty?
|
161
|
+
|
162
|
+
if @auto_flushing == 1
|
163
|
+
canonical_write(str)
|
164
|
+
else
|
165
|
+
sync { @buffer << str }
|
166
|
+
flush if @buffer.length >= @auto_flushing || immediate?(event)
|
167
|
+
end
|
168
|
+
|
161
169
|
self
|
162
170
|
end
|
163
171
|
|
164
|
-
|
165
172
|
end # module Buffering
|
166
173
|
end # module Logging::Appenders
|
167
174
|
|
168
|
-
# EOF
|
@@ -42,21 +42,20 @@ class Email < ::Logging::Appender
|
|
42
42
|
@params = [@server, @port, @domain, @acct, @passwd, @authtype]
|
43
43
|
end
|
44
44
|
|
45
|
-
# call-seq:
|
46
|
-
# flush
|
47
|
-
#
|
48
|
-
# Create and send an email containing the current message buffer.
|
49
|
-
#
|
50
|
-
def flush
|
51
|
-
return self if buffer.empty?
|
52
45
|
|
46
|
+
private
|
47
|
+
|
48
|
+
# This method is called by the buffering code when messages need to be
|
49
|
+
# sent out as an email.
|
50
|
+
#
|
51
|
+
def canonical_write( str )
|
53
52
|
### build a mail header for RFC 822
|
54
53
|
rfc822msg = "From: #{@from}\n"
|
55
54
|
rfc822msg << "To: #{@to.join(",")}\n"
|
56
55
|
rfc822msg << "Subject: #{@subject}\n"
|
57
56
|
rfc822msg << "Date: #{Time.new.rfc822}\n"
|
58
57
|
rfc822msg << "Message-Id: <#{"%.8f" % Time.now.to_f}@#{@domain}>\n\n"
|
59
|
-
rfc822msg <<
|
58
|
+
rfc822msg << str
|
60
59
|
|
61
60
|
### send email
|
62
61
|
Net::SMTP.start(*@params) {|smtp| smtp.sendmail(rfc822msg, @from, @to)}
|
@@ -65,11 +64,8 @@ class Email < ::Logging::Appender
|
|
65
64
|
self.level = :off
|
66
65
|
::Logging.log_internal {'e-mail notifications have been disabled'}
|
67
66
|
::Logging.log_internal(-2) {err}
|
68
|
-
ensure
|
69
|
-
buffer.clear
|
70
67
|
end
|
71
68
|
|
72
69
|
end # class Email
|
73
70
|
end # module Logging::Appenders
|
74
71
|
|
75
|
-
# EOF
|
data/lib/logging/appenders/io.rb
CHANGED
@@ -15,13 +15,11 @@ module Logging::Appenders
|
|
15
15
|
# stream as the logging destination.
|
16
16
|
#
|
17
17
|
def initialize( name, io, opts = {} )
|
18
|
-
unless io.respond_to? :
|
18
|
+
unless io.respond_to? :syswrite
|
19
19
|
raise TypeError, "expecting an IO object but got '#{io.class.name}'"
|
20
20
|
end
|
21
21
|
|
22
22
|
@io = io
|
23
|
-
@io.sync = true if @io.respond_to?(:sync) rescue nil
|
24
|
-
|
25
23
|
configure_buffering(opts)
|
26
24
|
super(name, opts)
|
27
25
|
end
|
@@ -44,26 +42,22 @@ module Logging::Appenders
|
|
44
42
|
return self
|
45
43
|
end
|
46
44
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
#
|
51
|
-
#
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# This method is called by the buffering code when messages need to be
|
49
|
+
# written to the logging destination.
|
52
50
|
#
|
53
|
-
def
|
51
|
+
def canonical_write( str )
|
54
52
|
return self if @io.nil?
|
55
|
-
@io.
|
56
|
-
@io.flush
|
53
|
+
@io.syswrite str
|
57
54
|
self
|
58
55
|
rescue StandardError => err
|
59
56
|
self.level = :off
|
60
57
|
::Logging.log_internal {"appender #{name.inspect} has been disabled"}
|
61
58
|
::Logging.log_internal(-2) {err}
|
62
|
-
ensure
|
63
|
-
buffer.clear
|
64
59
|
end
|
65
60
|
|
66
61
|
end # class IO
|
67
62
|
end # module Logging::Appenders
|
68
63
|
|
69
|
-
# EOF
|
@@ -168,29 +168,21 @@ module Logging::Appenders
|
|
168
168
|
end
|
169
169
|
@closed = false
|
170
170
|
@io = ::File.new(@fn, 'a')
|
171
|
-
@io.sync = true
|
172
171
|
}
|
173
172
|
self
|
174
173
|
end
|
175
174
|
|
176
175
|
|
177
|
-
|
176
|
+
private
|
178
177
|
|
179
|
-
alias :_write :write
|
180
|
-
|
181
|
-
# call-seq:
|
182
|
-
# write( event )
|
183
|
-
#
|
184
178
|
# Write the given _event_ to the log file. The log file will be rolled
|
185
179
|
# if the maximum file size is exceeded or if the file is older than the
|
186
180
|
# maximum age.
|
187
181
|
#
|
188
|
-
def
|
189
|
-
|
190
|
-
@layout.format(event) : event.to_s
|
191
|
-
return if str.empty?
|
182
|
+
def canonical_write( str )
|
183
|
+
return self if @io.nil?
|
192
184
|
|
193
|
-
@io.flock_sh {
|
185
|
+
@io.flock_sh { @io.syswrite(str) }
|
194
186
|
|
195
187
|
if roll_required?
|
196
188
|
@io.flock? {
|
@@ -199,6 +191,11 @@ module Logging::Appenders
|
|
199
191
|
}
|
200
192
|
@roller.roll_files
|
201
193
|
end
|
194
|
+
self
|
195
|
+
rescue StandardError => err
|
196
|
+
self.level = :off
|
197
|
+
::Logging.log_internal {"appender #{name.inspect} has been disabled"}
|
198
|
+
::Logging.log_internal(-2) {err}
|
202
199
|
end
|
203
200
|
|
204
201
|
# Returns +true+ if the log file needs to be rolled.
|
@@ -326,4 +323,3 @@ module Logging::Appenders
|
|
326
323
|
end # class RollingFile
|
327
324
|
end # module Logging::Appenders
|
328
325
|
|
329
|
-
# EOF
|