logging 0.1.0 → 0.2.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/examples/logging.yaml +63 -0
- data/lib/logging.rb +23 -2
- data/lib/logging/appender.rb +9 -7
- data/lib/logging/appenders/console.rb +13 -9
- data/lib/logging/appenders/file.rb +25 -23
- data/lib/logging/appenders/io.rb +4 -8
- data/lib/logging/appenders/rolling_file.rb +189 -0
- data/lib/logging/config/yaml_configurator.rb +190 -0
- data/lib/logging/layout.rb +10 -8
- data/lib/logging/layouts/pattern.rb +7 -9
- data/lib/logging/logger.rb +37 -7
- data/test/appenders/test_console.rb +7 -7
- data/test/appenders/test_file.rb +20 -10
- data/test/appenders/test_rolling_file.rb +141 -0
- data/test/config/test_yaml_configurator.rb +47 -0
- data/test/layouts/test_pattern.rb +2 -2
- data/test/setup.rb +3 -1
- data/test/test_layout.rb +7 -7
- data/test/test_log_event.rb +3 -3
- data/test/test_logger.rb +37 -1
- data/test/test_logging.rb +82 -2
- data/test/test_root_logger.rb +17 -1
- metadata +7 -2
@@ -0,0 +1,190 @@
|
|
1
|
+
# $Id: yaml_configurator.rb 22 2007-01-29 16:20:54Z tim_pease $
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'logging'
|
5
|
+
|
6
|
+
module Logging
|
7
|
+
module Config
|
8
|
+
|
9
|
+
#
|
10
|
+
# The YamlConfigurator class is used to configure the Logging framework
|
11
|
+
# using information found in a YAML file.
|
12
|
+
#
|
13
|
+
class YamlConfigurator
|
14
|
+
|
15
|
+
class Error < StandardError; end # :nodoc:
|
16
|
+
|
17
|
+
class << self
|
18
|
+
#
|
19
|
+
# call-seq:
|
20
|
+
# YamlConfigurator.load( file )
|
21
|
+
#
|
22
|
+
# Load the given YAML _file_ and use it to configure the Logging
|
23
|
+
# framework. The file can be either a filename, and open File, or an
|
24
|
+
# IO object. If it is the latter two, the File / IO object will not be
|
25
|
+
# closed by this method.
|
26
|
+
#
|
27
|
+
def load( file )
|
28
|
+
io, close = nil, false
|
29
|
+
case file
|
30
|
+
when String
|
31
|
+
io = File.open(file, 'r')
|
32
|
+
close = true
|
33
|
+
when IO: io = file
|
34
|
+
else raise Error, 'expecting a filename or a File' end
|
35
|
+
|
36
|
+
begin new(io).load; ensure; io.close if close end
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end # class << self
|
40
|
+
|
41
|
+
#
|
42
|
+
# call-seq:
|
43
|
+
# YamlConfigurator.new( io )
|
44
|
+
#
|
45
|
+
# Creates a new YAML configurator that will load the Logging
|
46
|
+
# configuration from the given _io_ stream.
|
47
|
+
#
|
48
|
+
def initialize( io )
|
49
|
+
YAML.load_documents(io) do |doc|
|
50
|
+
@config = doc['logging_config']
|
51
|
+
break if @config.instance_of?(Hash)
|
52
|
+
end
|
53
|
+
|
54
|
+
unless @config.instance_of?(Hash)
|
55
|
+
raise Error, "Key 'logging_config' not defined in YAML configuration"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
private :initialize
|
59
|
+
|
60
|
+
#
|
61
|
+
# call-seq:
|
62
|
+
# load
|
63
|
+
#
|
64
|
+
# Loads the Logging configuration from the data loaded from the YAML
|
65
|
+
# file.
|
66
|
+
#
|
67
|
+
def load
|
68
|
+
pre_config @config['pre_config']
|
69
|
+
appenders @config['appenders']
|
70
|
+
loggers @config['loggers']
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# call-seq:
|
75
|
+
# pre_config( config )
|
76
|
+
#
|
77
|
+
# Configures the logging levels, object format style, and root logging
|
78
|
+
# level.
|
79
|
+
#
|
80
|
+
def pre_config( config )
|
81
|
+
# if no pre_config section was given, just create an empty hash
|
82
|
+
# we do this to ensure that some logging levels are always defined
|
83
|
+
config ||= Hash.new
|
84
|
+
|
85
|
+
# define levels
|
86
|
+
levels = config['define_levels']
|
87
|
+
::Logging.define_levels(levels) unless levels.nil?
|
88
|
+
|
89
|
+
# format as
|
90
|
+
format = config['format_as']
|
91
|
+
::Logging.format_as(format) unless format.nil?
|
92
|
+
|
93
|
+
# grab the root logger and set the logging level
|
94
|
+
root = ::Logging::Logger.root
|
95
|
+
if config.has_key?('root')
|
96
|
+
root.level = config['root']['level']
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# call-seq:
|
102
|
+
# appenders( ary )
|
103
|
+
#
|
104
|
+
# Given an array of Appender configurations, this method will iterate
|
105
|
+
# over each and create the Appender(s).
|
106
|
+
#
|
107
|
+
def appenders( ary )
|
108
|
+
return if ary.nil?
|
109
|
+
|
110
|
+
ary.each {|h| appender(h)}
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# call-seq:
|
115
|
+
# loggers( ary )
|
116
|
+
#
|
117
|
+
# Given an array of Logger configurations, this method will iterate over
|
118
|
+
# each and create the Logger(s).
|
119
|
+
#
|
120
|
+
def loggers( ary )
|
121
|
+
return if ary.nil?
|
122
|
+
|
123
|
+
ary.each do |config|
|
124
|
+
name = config['name']
|
125
|
+
raise Error, 'Logger name not given' if name.nil?
|
126
|
+
|
127
|
+
l = Logging::Logger.new name
|
128
|
+
l.level = config['level'] if config.has_key?('level')
|
129
|
+
l.additive = config['additive'] if l.respond_to? :additive=
|
130
|
+
l.trace = config['trace'] if l.respond_to? :trace=
|
131
|
+
|
132
|
+
if config.has_key?('appenders')
|
133
|
+
l.appenders = config['appenders'].map {|n| ::Logging::Appender[n]}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
#
|
139
|
+
# call-seq:
|
140
|
+
# appender( config )
|
141
|
+
#
|
142
|
+
# Creates a new Appender based on the given _config_ options (a hash).
|
143
|
+
# The type of Appender created is determined by the 'type' option in the
|
144
|
+
# config. The remaining config options are passed to the Appender
|
145
|
+
# initializer.
|
146
|
+
#
|
147
|
+
# The config options can also contain a 'layout' option. This should be
|
148
|
+
# another set of options used to create a Layout for this Appender.
|
149
|
+
#
|
150
|
+
def appender( config )
|
151
|
+
return if config.nil?
|
152
|
+
config = config.dup
|
153
|
+
|
154
|
+
type = config.delete('type')
|
155
|
+
raise Error, 'Appender type not given' if type.nil?
|
156
|
+
|
157
|
+
name = config.delete('name')
|
158
|
+
raise Error, 'Appender name not given' if type.nil?
|
159
|
+
|
160
|
+
config['layout'] = layout(config.delete('layout'))
|
161
|
+
|
162
|
+
clazz = ::Logging::Appenders.const_get type
|
163
|
+
clazz.new(name, config)
|
164
|
+
end
|
165
|
+
|
166
|
+
#
|
167
|
+
# call-seq:
|
168
|
+
# layout( config )
|
169
|
+
#
|
170
|
+
# Creates a new Layout based on the given _config_ options (a hash).
|
171
|
+
# The type of Layout created is determined by the 'type' option in the
|
172
|
+
# config. The remaining config options are passed to the Layout
|
173
|
+
# initializer.
|
174
|
+
#
|
175
|
+
def layout( config )
|
176
|
+
return if config.nil?
|
177
|
+
config = config.dup
|
178
|
+
|
179
|
+
type = config.delete('type')
|
180
|
+
raise Error, 'Layout type not given' if type.nil?
|
181
|
+
|
182
|
+
clazz = ::Logging::Layouts.const_get type
|
183
|
+
clazz.new config
|
184
|
+
end
|
185
|
+
|
186
|
+
end # class YamlConfigurator
|
187
|
+
end # module Config
|
188
|
+
end # module Logging
|
189
|
+
|
190
|
+
# EOF
|
data/lib/logging/layout.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: layout.rb
|
1
|
+
# $Id: layout.rb 17 2007-01-20 18:47:43Z tim_pease $
|
2
2
|
|
3
3
|
require 'yaml'
|
4
4
|
require 'logging'
|
@@ -18,11 +18,10 @@ module Logging
|
|
18
18
|
|
19
19
|
#
|
20
20
|
# call-seq:
|
21
|
-
# Layout.new
|
22
|
-
# Layout.new( obj_format )
|
21
|
+
# Layout.new( :format_as => :string )
|
23
22
|
#
|
24
|
-
# Creates a new layout that
|
25
|
-
#
|
23
|
+
# Creates a new layout that will format objecs as strings using the
|
24
|
+
# given <tt>:format_as</tt> style. This can be one of <tt>:string</tt>,
|
26
25
|
# <tt>:inspect</tt>, or <tt>:yaml</tt>. These formatting commands map to
|
27
26
|
# the following object methods:
|
28
27
|
#
|
@@ -30,12 +29,15 @@ module Logging
|
|
30
29
|
# * :inspect => inspect
|
31
30
|
# * :yaml => to_yaml
|
32
31
|
#
|
33
|
-
# If
|
32
|
+
# If the format is not specified then the global object format is used
|
34
33
|
# (see Logging#format_as). If the global object format is not specified
|
35
|
-
# then
|
34
|
+
# then <tt>:string</tt> is used.
|
36
35
|
#
|
37
|
-
def initialize(
|
36
|
+
def initialize( opts = {} )
|
37
|
+
f = opts[:format_as] || opts['format_as']
|
38
38
|
f ||= ::Logging::OBJ_FORMAT if ::Logging.const_defined? 'OBJ_FORMAT'
|
39
|
+
f = f.intern if f.instance_of? String
|
40
|
+
|
39
41
|
@obj_format = case f
|
40
42
|
when :inspect, :yaml: f
|
41
43
|
else :string end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: pattern.rb
|
1
|
+
# $Id: pattern.rb 17 2007-01-20 18:47:43Z tim_pease $
|
2
2
|
|
3
3
|
require 'logging'
|
4
4
|
require 'logging/layout'
|
@@ -243,14 +243,12 @@ module Layouts
|
|
243
243
|
# If used, :date_method will supersede :date_pattern.
|
244
244
|
#
|
245
245
|
def initialize( opts = {} )
|
246
|
-
|
247
|
-
super(f)
|
248
|
-
|
246
|
+
super
|
249
247
|
@created_at = Time.now
|
250
248
|
|
251
|
-
@pattern = opts[:pattern]
|
252
|
-
@date_pattern = opts[:date_pattern]
|
253
|
-
@date_method = opts[:date_method]
|
249
|
+
@pattern = opts[:pattern] || opts['pattern']
|
250
|
+
@date_pattern = opts[:date_pattern] || opts['date_pattern']
|
251
|
+
@date_method = opts[:date_method] || opts['date_method']
|
254
252
|
|
255
253
|
@pattern ||= "[%d] %-#{::Logging::MAX_LEVEL_LENGTH}l -- %c : %m\n"
|
256
254
|
@date_pattern = ISO8601 if @date_pattern.nil? and @date_method.nil?
|
@@ -268,7 +266,7 @@ module Layouts
|
|
268
266
|
# Set the message formatting pattern to be used by the layout.
|
269
267
|
#
|
270
268
|
def pattern=( var )
|
271
|
-
@pattern = var
|
269
|
+
@pattern = var
|
272
270
|
Pattern.create_format_methods(self)
|
273
271
|
end
|
274
272
|
|
@@ -280,7 +278,7 @@ module Layouts
|
|
280
278
|
# in the log messages.
|
281
279
|
#
|
282
280
|
def date_pattern=( var )
|
283
|
-
@date_pattern = var
|
281
|
+
@date_pattern = var
|
284
282
|
Pattern.create_date_format_methods(self)
|
285
283
|
end
|
286
284
|
|
data/lib/logging/logger.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
# $Id: logger.rb
|
1
|
+
# $Id: logger.rb 22 2007-01-29 16:20:54Z tim_pease $
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'thread'
|
4
4
|
require 'logging'
|
5
5
|
require 'logging/appender'
|
6
6
|
require 'logging/log_event'
|
@@ -33,10 +33,9 @@ module Logging
|
|
33
33
|
#
|
34
34
|
class Logger
|
35
35
|
|
36
|
-
@mutex =
|
36
|
+
@mutex = Mutex.new # :nodoc:
|
37
37
|
|
38
38
|
class << self
|
39
|
-
|
40
39
|
#
|
41
40
|
# call-seq:
|
42
41
|
# Logger.root
|
@@ -59,7 +58,7 @@ module Logging
|
|
59
58
|
repo = ::Logging::Repository.instance
|
60
59
|
name = repo.to_key(args.shift)
|
61
60
|
|
62
|
-
@mutex.synchronize
|
61
|
+
@mutex.synchronize do
|
63
62
|
logger = repo[name]
|
64
63
|
if logger.nil?
|
65
64
|
logger = super(name, *args)
|
@@ -121,8 +120,7 @@ module Logging
|
|
121
120
|
|
122
121
|
end # class << self
|
123
122
|
|
124
|
-
attr_reader :level, :name, :parent
|
125
|
-
attr_accessor :additive, :trace
|
123
|
+
attr_reader :level, :name, :parent, :additive, :trace
|
126
124
|
|
127
125
|
#
|
128
126
|
# call-seq:
|
@@ -192,6 +190,38 @@ module Logging
|
|
192
190
|
@parent << msg if @additive
|
193
191
|
end
|
194
192
|
|
193
|
+
#
|
194
|
+
# call-seq:
|
195
|
+
# additive = true
|
196
|
+
#
|
197
|
+
# Sets the additivity of the logger. Acceptable values are +true+,
|
198
|
+
# 'true', +false+, 'false', or +nil+. In this case +nil+ does not
|
199
|
+
# change the additivity
|
200
|
+
#
|
201
|
+
def additive=( val )
|
202
|
+
@additive = case val
|
203
|
+
when true, 'true': true
|
204
|
+
when false, 'false': false
|
205
|
+
when nil: @additive
|
206
|
+
else raise ArgumentError, 'expecting a boolean' end
|
207
|
+
end
|
208
|
+
|
209
|
+
#
|
210
|
+
# call-seq:
|
211
|
+
# trace = true
|
212
|
+
#
|
213
|
+
# Sets the tracing of the logger. Acceptable values are +true+,
|
214
|
+
# 'true', +false+, 'false', or +nil+. In this case +nil+ does not
|
215
|
+
# change the tracing.
|
216
|
+
#
|
217
|
+
def trace=( val )
|
218
|
+
@trace = case val
|
219
|
+
when true, 'true': true
|
220
|
+
when false, 'false': false
|
221
|
+
when nil: @trace
|
222
|
+
else raise ArgumentError, 'expecting a boolean' end
|
223
|
+
end
|
224
|
+
|
195
225
|
#
|
196
226
|
# call-seq:
|
197
227
|
# level = :all
|
@@ -1,15 +1,15 @@
|
|
1
|
-
# $Id: test_console.rb
|
1
|
+
# $Id: test_console.rb 17 2007-01-20 18:47:43Z tim_pease $
|
2
2
|
|
3
3
|
require 'test/setup.rb'
|
4
4
|
|
5
5
|
module TestLogging
|
6
6
|
module TestAppenders
|
7
7
|
|
8
|
-
class
|
8
|
+
class TestStdout < Test::Unit::TestCase
|
9
9
|
include LoggingTestCase
|
10
10
|
|
11
11
|
def test_initialize
|
12
|
-
appender = ::Logging::Appenders::
|
12
|
+
appender = ::Logging::Appenders::Stdout.new
|
13
13
|
assert_equal 'stdout', appender.name
|
14
14
|
assert_same STDOUT, appender.instance_variable_get(:@io)
|
15
15
|
|
@@ -18,12 +18,12 @@ module TestAppenders
|
|
18
18
|
assert_equal false, STDOUT.closed?
|
19
19
|
end
|
20
20
|
|
21
|
-
end # class
|
21
|
+
end # class TestStdout
|
22
22
|
|
23
|
-
class
|
23
|
+
class TestStderr < Test::Unit::TestCase
|
24
24
|
|
25
25
|
def test_initialize
|
26
|
-
appender = ::Logging::Appenders::
|
26
|
+
appender = ::Logging::Appenders::Stderr.new
|
27
27
|
assert_equal 'stderr', appender.name
|
28
28
|
assert_same STDERR, appender.instance_variable_get(:@io)
|
29
29
|
|
@@ -32,7 +32,7 @@ module TestAppenders
|
|
32
32
|
assert_equal false, STDERR.closed?
|
33
33
|
end
|
34
34
|
|
35
|
-
end # class
|
35
|
+
end # class TestStderr
|
36
36
|
|
37
37
|
end # module TestAppenders
|
38
38
|
end # module TestLogging
|
data/test/appenders/test_file.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: test_file.rb
|
1
|
+
# $Id: test_file.rb 17 2007-01-20 18:47:43Z tim_pease $
|
2
2
|
|
3
3
|
require 'test/setup.rb'
|
4
4
|
require 'fileutils'
|
@@ -27,19 +27,26 @@ module TestAppenders
|
|
27
27
|
|
28
28
|
def test_initialize
|
29
29
|
log = File.join(TMP, 'uw_dir', 'file.log')
|
30
|
-
assert_raise(StandardError)
|
30
|
+
assert_raise(StandardError) do
|
31
|
+
::Logging::Appenders::File.new(nil, :filename => log)
|
32
|
+
end
|
31
33
|
|
32
34
|
log = File.join(TMP, 'dir')
|
33
|
-
assert_raise(StandardError)
|
35
|
+
assert_raise(StandardError) do
|
36
|
+
::Logging::Appenders::File.new(nil, :filename => log)
|
37
|
+
end
|
34
38
|
|
35
39
|
log = File.join(TMP, 'uw_file')
|
36
|
-
assert_raise(StandardError)
|
40
|
+
assert_raise(StandardError) do
|
41
|
+
::Logging::Appenders::File.new(nil, :filename => log)
|
42
|
+
end
|
37
43
|
|
38
44
|
log = File.join(TMP, 'file.log')
|
39
|
-
appender = ::Logging::Appenders::File.new log
|
40
|
-
assert_equal
|
45
|
+
appender = ::Logging::Appenders::File.new 'logfile', 'filename' => log
|
46
|
+
assert_equal 'logfile', appender.name
|
41
47
|
appender << "This will be the first line\n"
|
42
48
|
appender << "This will be the second line\n"
|
49
|
+
appender.flush
|
43
50
|
File.open(log, 'r') do |file|
|
44
51
|
assert_equal "This will be the first line\n", file.readline
|
45
52
|
assert_equal "This will be the second line\n", file.readline
|
@@ -47,9 +54,10 @@ module TestAppenders
|
|
47
54
|
end
|
48
55
|
appender.close
|
49
56
|
|
50
|
-
appender = ::Logging::Appenders::File.new log
|
51
|
-
assert_equal
|
57
|
+
appender = ::Logging::Appenders::File.new 'logfile', :filename => log
|
58
|
+
assert_equal 'logfile', appender.name
|
52
59
|
appender << "This will be the third line\n"
|
60
|
+
appender.flush
|
53
61
|
File.open(log, 'r') do |file|
|
54
62
|
assert_equal "This will be the first line\n", file.readline
|
55
63
|
assert_equal "This will be the second line\n", file.readline
|
@@ -58,9 +66,11 @@ module TestAppenders
|
|
58
66
|
end
|
59
67
|
appender.close
|
60
68
|
|
61
|
-
appender = ::Logging::Appenders::File.new
|
62
|
-
|
69
|
+
appender = ::Logging::Appenders::File.new 'logfile', :filename => log,
|
70
|
+
:truncate => true
|
71
|
+
assert_equal 'logfile', appender.name
|
63
72
|
appender << "The file was truncated\n"
|
73
|
+
appender.flush
|
64
74
|
File.open(log, 'r') do |file|
|
65
75
|
assert_equal "The file was truncated\n", file.readline
|
66
76
|
assert_raise(EOFError) {file.readline}
|