logging 1.4.3 → 1.5.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.
- 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
|