logging 0.6.2 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +13 -5
- data/Manifest.txt +0 -1
- data/lib/logging.rb +56 -34
- data/lib/logging/appender.rb +214 -160
- data/lib/logging/appenders/console.rb +3 -1
- data/lib/logging/config/yaml_configurator.rb +22 -12
- data/lib/logging/layout.rb +82 -80
- data/tasks/annotations.rake +7 -15
- data/tasks/post_load.rake +1 -1
- data/tasks/setup.rb +3 -2
- data/test/appenders/test_console.rb +2 -2
- data/test/appenders/test_email.rb +2 -2
- data/test/appenders/test_file.rb +2 -3
- data/test/appenders/test_growl.rb +2 -2
- data/test/appenders/test_io.rb +2 -3
- data/test/appenders/test_rolling_file.rb +2 -3
- data/test/appenders/test_syslog.rb +2 -2
- data/test/config/test_yaml_configurator.rb +3 -5
- data/test/layouts/test_basic.rb +2 -2
- data/test/layouts/test_pattern.rb +2 -2
- data/test/setup.rb +11 -2
- data/test/test_appender.rb +2 -2
- data/test/test_layout.rb +2 -2
- data/test/test_log_event.rb +2 -2
- data/test/test_logger.rb +2 -3
- data/test/test_logging.rb +2 -3
- data/test/test_repository.rb +2 -2
- data/test/test_root_logger.rb +2 -3
- data/test/test_utils.rb +2 -3
- metadata +2 -3
- data/lib/logging/appenders/static_appender.rb +0 -60
data/History.txt
CHANGED
@@ -1,13 +1,21 @@
|
|
1
|
+
== 0.6.3 / 2008-02-08
|
2
|
+
|
3
|
+
2 minor enhancements
|
4
|
+
- YAML configuration now supports multiple keys -- i.e. development
|
5
|
+
or production or whatever
|
6
|
+
- Reorganized a lot of files so that requiring files is cleaner and
|
7
|
+
more deterministic
|
8
|
+
|
1
9
|
== 0.6.2 / 2008-02-06
|
2
10
|
|
3
|
-
2
|
11
|
+
2 bug fixes
|
4
12
|
- An extra e-mail was being pushed out when the e-mail
|
5
13
|
appender was closed
|
6
14
|
- Created an at_exit handler to close all appenders
|
7
15
|
|
8
16
|
== 0.6.1 / 2008-01-01
|
9
17
|
|
10
|
-
1
|
18
|
+
1 bug fix
|
11
19
|
- Fixed include order to avoid double loading when testing
|
12
20
|
|
13
21
|
== 0.6.0 / 2007-12-26
|
@@ -40,8 +48,8 @@
|
|
40
48
|
|
41
49
|
* Added a microsecond flag to the Pattern layout
|
42
50
|
* All appenders write immediately upon receipt of a logging event
|
43
|
-
* Added a basic logging method
|
44
|
-
same manner as the standard Ruby logger
|
51
|
+
* Added a basic logging method that returns a logger object configured in
|
52
|
+
the same manner as the standard Ruby logger
|
45
53
|
* Fixed a bug caused by nil log messages
|
46
54
|
|
47
55
|
== 0.3.1 / 2007-02-08
|
@@ -55,7 +63,7 @@
|
|
55
63
|
== 0.2.0 / 2007-01-29
|
56
64
|
|
57
65
|
* The "once every four years" release
|
58
|
-
* Storage and
|
66
|
+
* Storage and retrieval of appenders by name
|
59
67
|
* YAML configuration support
|
60
68
|
* Rolling file appender
|
61
69
|
|
data/Manifest.txt
CHANGED
@@ -11,7 +11,6 @@ lib/logging/appenders/file.rb
|
|
11
11
|
lib/logging/appenders/growl.rb
|
12
12
|
lib/logging/appenders/io.rb
|
13
13
|
lib/logging/appenders/rolling_file.rb
|
14
|
-
lib/logging/appenders/static_appender.rb
|
15
14
|
lib/logging/appenders/syslog.rb
|
16
15
|
lib/logging/config/yaml_configurator.rb
|
17
16
|
lib/logging/layout.rb
|
data/lib/logging.rb
CHANGED
@@ -1,39 +1,23 @@
|
|
1
|
-
# $Id: logging.rb
|
2
|
-
|
3
|
-
require 'logging/utils'
|
4
|
-
require 'logging/log_event'
|
5
|
-
require 'logging/logger'
|
6
|
-
require 'logging/root_logger'
|
7
|
-
require 'logging/repository'
|
8
|
-
require 'logging/appender'
|
9
|
-
require 'logging/layout'
|
10
|
-
|
11
|
-
# require all appenders
|
12
|
-
require 'logging/appenders/static_appender'
|
13
|
-
require 'logging/appenders/io'
|
14
|
-
require 'logging/appenders/console'
|
15
|
-
require 'logging/appenders/email'
|
16
|
-
require 'logging/appenders/file'
|
17
|
-
require 'logging/appenders/growl'
|
18
|
-
require 'logging/appenders/rolling_file'
|
19
|
-
require 'logging/appenders/syslog'
|
20
|
-
|
21
|
-
# require all layouts
|
22
|
-
require 'logging/layouts/basic'
|
23
|
-
require 'logging/layouts/pattern'
|
24
|
-
|
25
|
-
# require all configurators
|
26
|
-
require 'logging/config/yaml_configurator'
|
1
|
+
# $Id: logging.rb 90 2008-02-08 19:03:48Z tim_pease $
|
27
2
|
|
3
|
+
# Equivalent to a header guard in C/C++
|
4
|
+
# Used to prevent the class/module from being loaded more than once
|
5
|
+
unless defined? Logging
|
6
|
+
|
7
|
+
# TODO: internal logger for debugging
|
8
|
+
# TODO: Windows Log Service appender
|
28
9
|
|
29
10
|
#
|
30
11
|
#
|
31
12
|
module Logging
|
32
13
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
14
|
+
# :stopdoc:
|
15
|
+
VERSION = '0.6.3'
|
16
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
17
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
18
|
+
LEVELS = {}
|
19
|
+
LNAMES = {}
|
20
|
+
# :startdoc:
|
37
21
|
|
38
22
|
class << self
|
39
23
|
|
@@ -44,10 +28,10 @@ module Logging
|
|
44
28
|
# found in the given file. The file extension should be either '.yaml'
|
45
29
|
# or '.yml' (XML configuration is not yet supported).
|
46
30
|
#
|
47
|
-
def configure( filename )
|
31
|
+
def configure( filename, *args )
|
48
32
|
case File.extname(filename)
|
49
33
|
when '.yaml', '.yml'
|
50
|
-
::Logging::Config::YamlConfigurator.load(filename)
|
34
|
+
::Logging::Config::YamlConfigurator.load(filename, *args)
|
51
35
|
else raise ArgumentError, 'unknown configuration file format' end
|
52
36
|
end
|
53
37
|
|
@@ -232,8 +216,42 @@ module Logging
|
|
232
216
|
module_eval "OBJ_FORMAT = :#{f}"
|
233
217
|
end
|
234
218
|
|
235
|
-
#
|
219
|
+
# Returns the version string for the library.
|
220
|
+
#
|
221
|
+
def version
|
222
|
+
VERSION
|
223
|
+
end
|
236
224
|
|
225
|
+
# Returns the library path for the module. If any arguments are given,
|
226
|
+
# they will be joined to the end of the libray path using
|
227
|
+
# <tt>File.join</tt>.
|
228
|
+
#
|
229
|
+
def libpath( *args )
|
230
|
+
args.empty? ? LIBPATH : ::File.join(LIBPATH, *args)
|
231
|
+
end
|
232
|
+
|
233
|
+
# Returns the lpath for the module. If any arguments are given,
|
234
|
+
# they will be joined to the end of the path using
|
235
|
+
# <tt>File.join</tt>.
|
236
|
+
#
|
237
|
+
def path( *args )
|
238
|
+
args.empty? ? PATH : ::File.join(PATH, *args)
|
239
|
+
end
|
240
|
+
|
241
|
+
# Utility method used to rquire all files ending in .rb that lie in the
|
242
|
+
# directory below this file that has the same name as the filename passed
|
243
|
+
# in. Optionally, a specific _directory_ name can be passed in such that
|
244
|
+
# the _filename_ does not have to be equivalent to the directory.
|
245
|
+
#
|
246
|
+
def require_all_libs_relative_to( fname, dir = nil )
|
247
|
+
dir ||= ::File.basename(fname, '.*')
|
248
|
+
search_me = ::File.expand_path(
|
249
|
+
::File.join(::File.dirname(fname), dir, '*.rb'))
|
250
|
+
|
251
|
+
Dir.glob(search_me).sort.each {|rb| require rb}
|
252
|
+
end
|
253
|
+
|
254
|
+
# :stopdoc:
|
237
255
|
# Convert the given level into a connaconical form - a lowercase string.
|
238
256
|
def levelify( level )
|
239
257
|
case level
|
@@ -252,9 +270,11 @@ module Logging
|
|
252
270
|
end
|
253
271
|
# :startdoc:
|
254
272
|
end
|
255
|
-
|
256
273
|
end # module Logging
|
257
274
|
|
275
|
+
Logging.require_all_libs_relative_to(__FILE__)
|
276
|
+
Logging.require_all_libs_relative_to(__FILE__, 'logging/config')
|
277
|
+
|
258
278
|
# This exit handler will close all the appenders that exist in the system.
|
259
279
|
# This is needed for closing IO streams and connections to the syslog server
|
260
280
|
# or e-mail servers, etc.
|
@@ -265,4 +285,6 @@ at_exit {
|
|
265
285
|
end
|
266
286
|
}
|
267
287
|
|
288
|
+
end # unless defined?
|
289
|
+
|
268
290
|
# EOF
|
data/lib/logging/appender.rb
CHANGED
@@ -1,203 +1,257 @@
|
|
1
|
-
# $Id: appender.rb
|
1
|
+
# $Id: appender.rb 88 2008-02-08 18:47:36Z tim_pease $
|
2
2
|
|
3
3
|
require 'thread'
|
4
4
|
|
5
5
|
module Logging
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
7
|
+
# The +Appender+ class is provides methods for appending log events to a
|
8
|
+
# logging destination. The log events are formatted into strings using a
|
9
|
+
# Layout.
|
10
|
+
#
|
11
|
+
# All other Appenders inherit from this class which provides stub methods.
|
12
|
+
# Each subclass should provide a +write+ method that will write log
|
13
|
+
# messages to the logging destination.
|
14
|
+
#
|
15
|
+
# A private +sync+ method is provided for use by subclasses. It is used to
|
16
|
+
# synchronize writes to the logging destination, and can be used by
|
17
|
+
# subclasses to synchronize the closing or flushing of the logging
|
18
|
+
# destination.
|
19
|
+
#
|
20
|
+
class Appender
|
21
21
|
|
22
|
-
|
22
|
+
@appenders = Hash.new
|
23
|
+
|
24
|
+
class << self
|
23
25
|
|
24
26
|
# call-seq:
|
25
|
-
# Appender
|
26
|
-
# Appender.new( name, :layout => layout )
|
27
|
+
# Appender[name]
|
27
28
|
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
# layout will be written to the logging destination when the Appender is
|
31
|
-
# created.
|
29
|
+
# Returns the appender instance stroed in the Appender hash under the
|
30
|
+
# key _name_, or +nil+ if no appender has been created using that name.
|
32
31
|
#
|
33
|
-
def
|
34
|
-
@name = name.to_s
|
35
|
-
@closed = false
|
36
|
-
|
37
|
-
self.layout = opts.getopt(:layout, ::Logging::Layouts::Basic.new)
|
38
|
-
self.level = opts.getopt(:level)
|
39
|
-
|
40
|
-
@mutex = Mutex.new
|
41
|
-
header = @layout.header
|
42
|
-
sync {write(header)} unless header.nil? || header.empty?
|
43
|
-
|
44
|
-
::Logging::Appender[@name] = self
|
45
|
-
end
|
32
|
+
def []( name ) @appenders[name] end
|
46
33
|
|
47
34
|
# call-seq:
|
48
|
-
#
|
35
|
+
# Appender[name] = appender
|
49
36
|
#
|
50
|
-
#
|
51
|
-
#
|
37
|
+
# Stores the given _appender_ instance in the Appender hash under the
|
38
|
+
# key _name_.
|
52
39
|
#
|
53
|
-
def
|
54
|
-
if @closed
|
55
|
-
raise RuntimeError,
|
56
|
-
"appender '<#{self.class.name}: #{@name}>' is closed"
|
57
|
-
end
|
58
|
-
|
59
|
-
sync {write(event)} unless @level > event.level
|
60
|
-
self
|
61
|
-
end
|
40
|
+
def []=( name, val ) @appenders[name] = val end
|
62
41
|
|
63
42
|
# call-seq:
|
64
|
-
#
|
43
|
+
# Appenders.remove( name )
|
65
44
|
#
|
66
|
-
#
|
67
|
-
#
|
45
|
+
# Removes the appender instance stored in the Appender hash under the
|
46
|
+
# key _name_.
|
68
47
|
#
|
69
|
-
def
|
70
|
-
if @closed
|
71
|
-
raise RuntimeError,
|
72
|
-
"appender '<#{self.class.name}: #{@name}>' is closed"
|
73
|
-
end
|
74
|
-
|
75
|
-
sync {write(str)} unless @level >= ::Logging::LEVELS.length
|
76
|
-
self
|
77
|
-
end
|
48
|
+
def remove( name ) @appenders.delete(name) end
|
78
49
|
|
79
50
|
# call-seq:
|
80
|
-
#
|
81
|
-
#
|
82
|
-
# Set the level for this appender; log events below this level will be
|
83
|
-
# ignored by this appender. The level can be either a +String+, a
|
84
|
-
# +Symbol+, or a +Fixnum+. An +ArgumentError+ is raised if this is not
|
85
|
-
# the case.
|
51
|
+
# Appender.stdout
|
86
52
|
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
53
|
+
# Returns an instance of the Stdout Appender. Unless the user explicitly
|
54
|
+
# creates a new Stdout Appender, the instance returned by this method
|
55
|
+
# will always be the same:
|
90
56
|
#
|
91
|
-
#
|
57
|
+
# Appender.stdout.object_id == Appender.stdout.object_id #=> true
|
92
58
|
#
|
93
|
-
|
94
|
-
|
95
|
-
#
|
96
|
-
#
|
97
|
-
# appender.level = :all
|
59
|
+
def stdout( ) self['stdout'] || ::Logging::Appenders::Stdout.new end
|
60
|
+
|
61
|
+
# call-seq:
|
62
|
+
# Appender.stderr
|
98
63
|
#
|
99
|
-
#
|
64
|
+
# Returns an instance of the Stderr Appender. Unless the user explicitly
|
65
|
+
# creates a new Stderr Appender, the instance returned by this method
|
66
|
+
# will always be the same:
|
100
67
|
#
|
101
|
-
#
|
102
|
-
# appender.level = -1
|
103
|
-
# appender.level = 1_000_000_000_000
|
68
|
+
# Appender.stderr.object_id == Appender.stderr.object_id #=> true
|
104
69
|
#
|
105
|
-
def
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
70
|
+
def stderr( ) self['stderr'] || ::Logging::Appenders::Stderr.new end
|
71
|
+
|
72
|
+
end # class << self
|
73
|
+
|
74
|
+
attr_reader :name, :layout, :level
|
75
|
+
|
76
|
+
# call-seq:
|
77
|
+
# Appender.new( name )
|
78
|
+
# Appender.new( name, :layout => layout )
|
79
|
+
#
|
80
|
+
# Creates a new appender using the given name. If no Layout is specified,
|
81
|
+
# then a Basic layout will be used. Any logging header supplied by the
|
82
|
+
# layout will be written to the logging destination when the Appender is
|
83
|
+
# created.
|
84
|
+
#
|
85
|
+
def initialize( name, opts = {} )
|
86
|
+
@name = name.to_s
|
87
|
+
@closed = false
|
88
|
+
|
89
|
+
self.layout = opts.getopt(:layout, ::Logging::Layouts::Basic.new)
|
90
|
+
self.level = opts.getopt(:level)
|
91
|
+
|
92
|
+
@mutex = Mutex.new
|
93
|
+
header = @layout.header
|
94
|
+
sync {write(header)} unless header.nil? || header.empty?
|
95
|
+
|
96
|
+
::Logging::Appender[@name] = self
|
97
|
+
end
|
98
|
+
|
99
|
+
# call-seq:
|
100
|
+
# append( event )
|
101
|
+
#
|
102
|
+
# Write the given _event_ to the logging destination. The log event will
|
103
|
+
# be processed through the Layout associated with the Appender.
|
104
|
+
#
|
105
|
+
def append( event )
|
106
|
+
if @closed
|
107
|
+
raise RuntimeError,
|
108
|
+
"appender '<#{self.class.name}: #{@name}>' is closed"
|
119
109
|
end
|
120
110
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
111
|
+
sync {write(event)} unless @level > event.level
|
112
|
+
self
|
113
|
+
end
|
114
|
+
|
115
|
+
# call-seq:
|
116
|
+
# appender << string
|
117
|
+
#
|
118
|
+
# Write the given _string_ to the logging destination "as is" -- no
|
119
|
+
# layout formatting will be performed.
|
120
|
+
#
|
121
|
+
def <<( str )
|
122
|
+
if @closed
|
123
|
+
raise RuntimeError,
|
124
|
+
"appender '<#{self.class.name}: #{@name}>' is closed"
|
132
125
|
end
|
133
126
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
127
|
+
sync {write(str)} unless @level >= ::Logging::LEVELS.length
|
128
|
+
self
|
129
|
+
end
|
130
|
+
|
131
|
+
# call-seq:
|
132
|
+
# level = :all
|
133
|
+
#
|
134
|
+
# Set the level for this appender; log events below this level will be
|
135
|
+
# ignored by this appender. The level can be either a +String+, a
|
136
|
+
# +Symbol+, or a +Fixnum+. An +ArgumentError+ is raised if this is not
|
137
|
+
# the case.
|
138
|
+
#
|
139
|
+
# There are two special levels -- "all" and "off". The former will
|
140
|
+
# enable recording of all log events. The latter will disable the
|
141
|
+
# recording of all events.
|
142
|
+
#
|
143
|
+
# Example:
|
144
|
+
#
|
145
|
+
# appender.level = :debug
|
146
|
+
# appender.level = "INFO"
|
147
|
+
# appender.level = 4
|
148
|
+
# appender.level = 'off'
|
149
|
+
# appender.level = :all
|
150
|
+
#
|
151
|
+
# These prodcue an +ArgumentError+
|
152
|
+
#
|
153
|
+
# appender.level = Object
|
154
|
+
# appender.level = -1
|
155
|
+
# appender.level = 1_000_000_000_000
|
156
|
+
#
|
157
|
+
def level=( level )
|
158
|
+
lvl = case level
|
159
|
+
when String, Symbol; ::Logging::level_num(level)
|
160
|
+
when Fixnum; level
|
161
|
+
when nil; 0
|
162
|
+
else
|
163
|
+
raise ArgumentError,
|
164
|
+
"level must be a String, Symbol, or Integer"
|
165
|
+
end
|
166
|
+
if lvl.nil? or lvl < 0 or lvl > ::Logging::LEVELS.length
|
167
|
+
raise ArgumentError, "unknown level was given '#{level}'"
|
151
168
|
end
|
152
169
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
170
|
+
@level = lvl
|
171
|
+
end
|
172
|
+
|
173
|
+
# call-seq
|
174
|
+
# appender.layout = Logging::Layouts::Basic.new
|
175
|
+
#
|
176
|
+
# Sets the layout to be used by this appender.
|
177
|
+
#
|
178
|
+
def layout=( layout )
|
179
|
+
unless layout.kind_of? ::Logging::Layout
|
180
|
+
raise TypeError,
|
181
|
+
"#{layout.inspect} is not a kind of 'Logging::Layout'"
|
162
182
|
end
|
183
|
+
@layout = layout
|
184
|
+
end
|
163
185
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
186
|
+
# call-seq:
|
187
|
+
# close( footer = true )
|
188
|
+
#
|
189
|
+
# Close the appender and writes the layout footer to the logging
|
190
|
+
# destination if the _footer_ flag is set to +true+. Log events will
|
191
|
+
# no longer be written to the logging destination after the appender
|
192
|
+
# is closed.
|
193
|
+
#
|
194
|
+
def close( footer = true )
|
195
|
+
return self if @closed
|
196
|
+
::Logging::Appender.remove(@name)
|
197
|
+
@closed = true
|
198
|
+
if footer
|
199
|
+
footer = @layout.footer
|
200
|
+
sync {write(footer)} unless footer.nil? || footer.empty?
|
172
201
|
end
|
202
|
+
self
|
203
|
+
end
|
173
204
|
|
205
|
+
# call-seq:
|
206
|
+
# closed?
|
207
|
+
#
|
208
|
+
# Returns +true+ if the appender has been closed; returns +false+
|
209
|
+
# otherwise. When an appender is closed, no more log events can be
|
210
|
+
# written to the logging destination.
|
211
|
+
#
|
212
|
+
def closed?
|
213
|
+
@closed
|
214
|
+
end
|
174
215
|
|
175
|
-
|
216
|
+
# call-seq:
|
217
|
+
# flush
|
218
|
+
#
|
219
|
+
# Call +flush+ to force an appender to write out any buffered log events.
|
220
|
+
# Similar to IO#flush, so use in a similar fashion.
|
221
|
+
#
|
222
|
+
def flush
|
223
|
+
self
|
224
|
+
end
|
176
225
|
|
177
|
-
# call-seq:
|
178
|
-
# write( event )
|
179
|
-
#
|
180
|
-
# Writes the given _event_ to the logging destination. Subclasses should
|
181
|
-
# provide an implementation of this method. The _event_ can be either a
|
182
|
-
# LogEvent or a String. If a LogEvent, then it will be formatted using
|
183
|
-
# the layout given to the appender when it was created.
|
184
|
-
#
|
185
|
-
def write( event )
|
186
|
-
nil
|
187
|
-
end
|
188
226
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
227
|
+
private
|
228
|
+
|
229
|
+
# call-seq:
|
230
|
+
# write( event )
|
231
|
+
#
|
232
|
+
# Writes the given _event_ to the logging destination. Subclasses should
|
233
|
+
# provide an implementation of this method. The _event_ can be either a
|
234
|
+
# LogEvent or a String. If a LogEvent, then it will be formatted using
|
235
|
+
# the layout given to the appender when it was created.
|
236
|
+
#
|
237
|
+
def write( event )
|
238
|
+
nil
|
239
|
+
end
|
199
240
|
|
200
|
-
|
241
|
+
# call-seq:
|
242
|
+
# sync { block }
|
243
|
+
#
|
244
|
+
# Obtains an exclusive lock, runs the block, and releases the lock when
|
245
|
+
# the block completes. This method is re-entrant so that a single thread
|
246
|
+
# can call +sync+ multiple times without hanging the thread.
|
247
|
+
#
|
248
|
+
def sync
|
249
|
+
@mutex.synchronize {yield}
|
250
|
+
end
|
251
|
+
|
252
|
+
end # class Appender
|
201
253
|
end # module Logging
|
202
254
|
|
255
|
+
Logging.require_all_libs_relative_to(__FILE__, 'appenders')
|
256
|
+
|
203
257
|
# EOF
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: yaml_configurator.rb
|
1
|
+
# $Id: yaml_configurator.rb 88 2008-02-08 18:47:36Z tim_pease $
|
2
2
|
|
3
3
|
require 'yaml'
|
4
4
|
|
@@ -15,44 +15,54 @@ module Config
|
|
15
15
|
class << self
|
16
16
|
|
17
17
|
# call-seq:
|
18
|
-
# YamlConfigurator.load( file )
|
18
|
+
# YamlConfigurator.load( file, key = 'logging_config' )
|
19
19
|
#
|
20
20
|
# Load the given YAML _file_ and use it to configure the Logging
|
21
21
|
# framework. The file can be either a filename, and open File, or an
|
22
22
|
# IO object. If it is the latter two, the File / IO object will not be
|
23
23
|
# closed by this method.
|
24
24
|
#
|
25
|
-
|
25
|
+
# The configuration will be loaded from the given _key_ in the YAML
|
26
|
+
# stream.
|
27
|
+
#
|
28
|
+
def load( file, key = 'logging_config' )
|
26
29
|
io, close = nil, false
|
27
30
|
case file
|
28
31
|
when String
|
29
32
|
io = File.open(file, 'r')
|
30
33
|
close = true
|
31
|
-
when IO
|
32
|
-
|
34
|
+
when IO
|
35
|
+
io = file
|
36
|
+
else
|
37
|
+
raise Error, 'expecting a filename or a File'
|
38
|
+
end
|
33
39
|
|
34
|
-
begin
|
40
|
+
begin
|
41
|
+
new(io, key).load
|
42
|
+
ensure
|
43
|
+
io.close if close
|
44
|
+
end
|
35
45
|
nil
|
36
46
|
end
|
37
47
|
end # class << self
|
38
48
|
|
39
49
|
# call-seq:
|
40
|
-
# YamlConfigurator.new( io )
|
50
|
+
# YamlConfigurator.new( io, key )
|
41
51
|
#
|
42
52
|
# Creates a new YAML configurator that will load the Logging
|
43
|
-
# configuration from the given _io_ stream.
|
53
|
+
# configuration from the given _io_ stream. The configuration will be
|
54
|
+
# loaded from the given _key_ in the YAML stream.
|
44
55
|
#
|
45
|
-
def initialize( io )
|
56
|
+
def initialize( io, key )
|
46
57
|
YAML.load_documents(io) do |doc|
|
47
|
-
@config = doc[
|
58
|
+
@config = doc[key]
|
48
59
|
break if @config.instance_of?(Hash)
|
49
60
|
end
|
50
61
|
|
51
62
|
unless @config.instance_of?(Hash)
|
52
|
-
raise Error, "Key '
|
63
|
+
raise Error, "Key '#{key}' not defined in YAML configuration"
|
53
64
|
end
|
54
65
|
end
|
55
|
-
private :initialize
|
56
66
|
|
57
67
|
# call-seq:
|
58
68
|
# load
|
data/lib/logging/layout.rb
CHANGED
@@ -1,101 +1,103 @@
|
|
1
|
-
# $Id: layout.rb
|
1
|
+
# $Id: layout.rb 88 2008-02-08 18:47:36Z tim_pease $
|
2
2
|
|
3
3
|
require 'yaml'
|
4
4
|
|
5
5
|
module Logging
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
# The +Layout+ class provides methods for formatting log events into a
|
8
|
+
# string representation. Layouts are used by Appenders to format log
|
9
|
+
# events before writing them to the logging destination.
|
10
|
+
#
|
11
|
+
# All other Layouts inherit from this class which provides stub methods.
|
12
|
+
# Each subclass should provide a +format+ method. A layout can be used by
|
13
|
+
# more than one +Appender+ so all the methods need to be thread safe.
|
14
|
+
#
|
15
|
+
class Layout
|
16
|
+
|
17
|
+
# call-seq:
|
18
|
+
# Layout.new( :format_as => :string )
|
19
|
+
#
|
20
|
+
# Creates a new layout that will format objecs as strings using the
|
21
|
+
# given <tt>:format_as</tt> style. This can be one of <tt>:string</tt>,
|
22
|
+
# <tt>:inspect</tt>, or <tt>:yaml</tt>. These formatting commands map to
|
23
|
+
# the following object methods:
|
10
24
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
25
|
+
# * :string => to_s
|
26
|
+
# * :inspect => inspect
|
27
|
+
# * :yaml => to_yaml
|
14
28
|
#
|
15
|
-
|
29
|
+
# If the format is not specified then the global object format is used
|
30
|
+
# (see Logging#format_as). If the global object format is not specified
|
31
|
+
# then <tt>:string</tt> is used.
|
32
|
+
#
|
33
|
+
def initialize( opts = {} )
|
34
|
+
default = ::Logging.const_defined?('OBJ_FORMAT') ?
|
35
|
+
::Logging::OBJ_FORMAT : nil
|
16
36
|
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
# Creates a new layout that will format objecs as strings using the
|
21
|
-
# given <tt>:format_as</tt> style. This can be one of <tt>:string</tt>,
|
22
|
-
# <tt>:inspect</tt>, or <tt>:yaml</tt>. These formatting commands map to
|
23
|
-
# the following object methods:
|
24
|
-
#
|
25
|
-
# * :string => to_s
|
26
|
-
# * :inspect => inspect
|
27
|
-
# * :yaml => to_yaml
|
28
|
-
#
|
29
|
-
# If the format is not specified then the global object format is used
|
30
|
-
# (see Logging#format_as). If the global object format is not specified
|
31
|
-
# then <tt>:string</tt> is used.
|
32
|
-
#
|
33
|
-
def initialize( opts = {} )
|
34
|
-
default = ::Logging.const_defined?('OBJ_FORMAT') ?
|
35
|
-
::Logging::OBJ_FORMAT : nil
|
37
|
+
f = opts.getopt(:format_as, default)
|
38
|
+
f = f.intern if f.instance_of? String
|
36
39
|
|
37
|
-
|
38
|
-
|
40
|
+
@obj_format = case f
|
41
|
+
when :inspect, :yaml; f
|
42
|
+
else :string end
|
43
|
+
end
|
39
44
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
#
|
48
|
-
# Returns a string representation of the given loggging _event_. It is
|
49
|
-
# up to subclasses to implement this method.
|
50
|
-
#
|
51
|
-
def format( event ) nil end
|
45
|
+
# call-seq:
|
46
|
+
# format( event )
|
47
|
+
#
|
48
|
+
# Returns a string representation of the given loggging _event_. It is
|
49
|
+
# up to subclasses to implement this method.
|
50
|
+
#
|
51
|
+
def format( event ) nil end
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
53
|
+
# call-seq:
|
54
|
+
# header
|
55
|
+
#
|
56
|
+
# Returns a header string to be used at the beginning of a logging
|
57
|
+
# appender.
|
58
|
+
#
|
59
|
+
def header( ) '' end
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
61
|
+
# call-seq:
|
62
|
+
# footer
|
63
|
+
#
|
64
|
+
# Returns a footer string to be used at the end of a logging appender.
|
65
|
+
#
|
66
|
+
def footer( ) '' end
|
67
67
|
|
68
68
|
|
69
|
-
|
69
|
+
protected
|
70
70
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
-
str
|
87
|
-
when nil; "<#{obj.class.name}> nil"
|
88
|
-
else
|
89
|
-
str = "<#{obj.class.name}> "
|
90
|
-
str << case @obj_format
|
91
|
-
when :inspect; obj.inspect
|
92
|
-
when :yaml; "\n#{obj.to_yaml}"
|
93
|
-
else obj.to_s end
|
94
|
-
str
|
71
|
+
# call-seq:
|
72
|
+
# format_obj( obj )
|
73
|
+
#
|
74
|
+
# Return a string representation of the given object. Depending upon
|
75
|
+
# the configuration of the logger system the format will be an +inspect+
|
76
|
+
# based represenation or a +yaml+ based representation.
|
77
|
+
#
|
78
|
+
def format_obj( obj )
|
79
|
+
case obj
|
80
|
+
when String; obj
|
81
|
+
when Exception
|
82
|
+
str = "<#{obj.class.name}> #{obj.message}"
|
83
|
+
unless obj.backtrace.nil?
|
84
|
+
str << "\n\t" << obj.backtrace.join("\n\t")
|
95
85
|
end
|
86
|
+
str
|
87
|
+
when nil; "<#{obj.class.name}> nil"
|
88
|
+
else
|
89
|
+
str = "<#{obj.class.name}> "
|
90
|
+
str << case @obj_format
|
91
|
+
when :inspect; obj.inspect
|
92
|
+
when :yaml; "\n#{obj.to_yaml}"
|
93
|
+
else obj.to_s end
|
94
|
+
str
|
96
95
|
end
|
96
|
+
end
|
97
97
|
|
98
|
-
|
98
|
+
end # class Layout
|
99
99
|
end # module Logging
|
100
100
|
|
101
|
+
Logging.require_all_libs_relative_to(__FILE__, 'layouts')
|
102
|
+
|
101
103
|
# EOF
|
data/tasks/annotations.rake
CHANGED
@@ -1,27 +1,19 @@
|
|
1
|
-
# $Id$
|
1
|
+
# $Id: annotations.rake 87 2008-02-08 17:21:07Z tim_pease $
|
2
2
|
|
3
3
|
if HAVE_BONES
|
4
4
|
|
5
5
|
desc "Enumerate all annotations"
|
6
6
|
task :notes do
|
7
7
|
Bones::AnnotationExtractor.enumerate(
|
8
|
-
PROJ,
|
8
|
+
PROJ, PROJ.annotation_tags.join('|'), :tag => true)
|
9
9
|
end
|
10
10
|
|
11
11
|
namespace :notes do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
desc "Enumerate all FIXME annotations"
|
18
|
-
task :fixme do
|
19
|
-
Bones::AnnotationExtractor.enumerate(PROJ, "FIXME")
|
20
|
-
end
|
21
|
-
|
22
|
-
desc "Enumerate all TODO annotations"
|
23
|
-
task :todo do
|
24
|
-
Bones::AnnotationExtractor.enumerate(PROJ, "TODO")
|
12
|
+
PROJ.annotation_tags.each do |tag|
|
13
|
+
desc "Enumerate all #{tag} annotations"
|
14
|
+
task tag.downcase.to_sym do
|
15
|
+
Bones::AnnotationExtractor.enumerate(PROJ, tag)
|
16
|
+
end
|
25
17
|
end
|
26
18
|
end
|
27
19
|
|
data/tasks/post_load.rake
CHANGED
data/tasks/setup.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: setup.rb
|
1
|
+
# $Id: setup.rb 87 2008-02-08 17:21:07Z tim_pease $
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'rake'
|
@@ -57,8 +57,9 @@ PROJ.need_tar = true
|
|
57
57
|
PROJ.need_zip = false
|
58
58
|
|
59
59
|
# File Annotations
|
60
|
-
PROJ.annotation_exclude =
|
60
|
+
PROJ.annotation_exclude = %w(^tasks/setup.rb$)
|
61
61
|
PROJ.annotation_extensions = %w(.txt .rb .erb) << ''
|
62
|
+
PROJ.annotation_tags = %w(FIXME OPTIMIZE TODO)
|
62
63
|
|
63
64
|
# Subversion Repository
|
64
65
|
PROJ.svn = false
|
data/test/appenders/test_file.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
# $Id: test_file.rb
|
1
|
+
# $Id: test_file.rb 88 2008-02-08 18:47:36Z tim_pease $
|
2
2
|
|
3
|
-
require
|
4
|
-
require 'fileutils'
|
3
|
+
require File.join(File.dirname(__FILE__), %w[.. setup])
|
5
4
|
|
6
5
|
module TestLogging
|
7
6
|
module TestAppenders
|
data/test/appenders/test_io.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
# $Id: test_rolling_file.rb
|
1
|
+
# $Id: test_rolling_file.rb 88 2008-02-08 18:47:36Z tim_pease $
|
2
2
|
|
3
|
-
require
|
4
|
-
require 'fileutils'
|
3
|
+
require File.join(File.dirname(__FILE__), %w[.. setup])
|
5
4
|
|
6
5
|
module TestLogging
|
7
6
|
module TestAppenders
|
@@ -1,8 +1,6 @@
|
|
1
|
-
# $Id: test_yaml_configurator.rb
|
1
|
+
# $Id: test_yaml_configurator.rb 88 2008-02-08 18:47:36Z tim_pease $
|
2
2
|
|
3
|
-
require
|
4
|
-
require 'yaml'
|
5
|
-
require 'test/setup.rb'
|
3
|
+
require File.join(File.dirname(__FILE__), %w[.. setup])
|
6
4
|
|
7
5
|
module TestLogging
|
8
6
|
module TestConfig
|
@@ -31,7 +29,7 @@ module TestConfig
|
|
31
29
|
io.seek 0
|
32
30
|
|
33
31
|
assert_raise(::Logging::Config::YamlConfigurator::Error) {
|
34
|
-
::Logging::Config::YamlConfigurator.new(io)
|
32
|
+
::Logging::Config::YamlConfigurator.new(io, :meh)
|
35
33
|
}
|
36
34
|
end
|
37
35
|
|
data/test/layouts/test_basic.rb
CHANGED
data/test/setup.rb
CHANGED
@@ -1,13 +1,20 @@
|
|
1
|
-
# $Id: setup.rb
|
1
|
+
# $Id: setup.rb 88 2008-02-08 18:47:36Z tim_pease $
|
2
|
+
|
3
|
+
# Equivalent to a header guard in C/C++
|
4
|
+
# Used to prevent the class/module from being loaded more than once
|
5
|
+
unless defined? LOGGING_TEST_SETUP
|
6
|
+
LOGGING_TEST_SETUP = true
|
2
7
|
|
3
8
|
require 'test/unit'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'stringio'
|
4
11
|
|
5
12
|
# This line is needed for Ruby 1.9 -- hashes throw a "KeyError" in 1.9
|
6
13
|
# whereas they throw an "IndexError" in 1.8
|
7
14
|
#
|
8
15
|
KeyError = IndexError if not defined? KeyError
|
9
16
|
|
10
|
-
require File.join(File.dirname(__FILE__),
|
17
|
+
require File.join(File.dirname(__FILE__), %w[.. lib logging])
|
11
18
|
|
12
19
|
begin
|
13
20
|
require 'turn'
|
@@ -59,4 +66,6 @@ module LoggingTestCase
|
|
59
66
|
end # module LoggingTestCase
|
60
67
|
end # module TestLogging
|
61
68
|
|
69
|
+
end # unless defined?
|
70
|
+
|
62
71
|
# EOF
|
data/test/test_appender.rb
CHANGED
data/test/test_layout.rb
CHANGED
data/test/test_log_event.rb
CHANGED
data/test/test_logger.rb
CHANGED
data/test/test_logging.rb
CHANGED
data/test/test_repository.rb
CHANGED
data/test/test_root_logger.rb
CHANGED
data/test/test_utils.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logging
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Pease
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-02-
|
12
|
+
date: 2008-02-08 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -53,7 +53,6 @@ files:
|
|
53
53
|
- lib/logging/appenders/growl.rb
|
54
54
|
- lib/logging/appenders/io.rb
|
55
55
|
- lib/logging/appenders/rolling_file.rb
|
56
|
-
- lib/logging/appenders/static_appender.rb
|
57
56
|
- lib/logging/appenders/syslog.rb
|
58
57
|
- lib/logging/config/yaml_configurator.rb
|
59
58
|
- lib/logging/layout.rb
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# $Id: static_appender.rb 85 2008-02-06 17:59:00Z tim_pease $
|
2
|
-
|
3
|
-
module Logging
|
4
|
-
class Appender
|
5
|
-
|
6
|
-
@appenders = Hash.new
|
7
|
-
|
8
|
-
class << self
|
9
|
-
|
10
|
-
# call-seq:
|
11
|
-
# Appender[name]
|
12
|
-
#
|
13
|
-
# Returns the appender instance stroed in the Appender hash under the
|
14
|
-
# key _name_, or +nil+ if no appender has been created using that name.
|
15
|
-
#
|
16
|
-
def []( name ) @appenders[name] end
|
17
|
-
|
18
|
-
# call-seq:
|
19
|
-
# Appender[name] = appender
|
20
|
-
#
|
21
|
-
# Stores the given _appender_ instance in the Appender hash under the
|
22
|
-
# key _name_.
|
23
|
-
#
|
24
|
-
def []=( name, val ) @appenders[name] = val end
|
25
|
-
|
26
|
-
# call-seq:
|
27
|
-
# Appenders.remove( name )
|
28
|
-
#
|
29
|
-
# Removes the appender instance stored in the Appender hash under the
|
30
|
-
# key _name_.
|
31
|
-
#
|
32
|
-
def remove( name ) @appenders.delete(name) end
|
33
|
-
|
34
|
-
# call-seq:
|
35
|
-
# Appender.stdout
|
36
|
-
#
|
37
|
-
# Returns an instance of the Stdout Appender. Unless the user explicitly
|
38
|
-
# creates a new Stdout Appender, the instance returned by this method
|
39
|
-
# will always be the same:
|
40
|
-
#
|
41
|
-
# Appender.stdout.object_id == Appender.stdout.object_id #=> true
|
42
|
-
#
|
43
|
-
def stdout( ) self['stdout'] || ::Logging::Appenders::Stdout.new end
|
44
|
-
|
45
|
-
# call-seq:
|
46
|
-
# Appender.stderr
|
47
|
-
#
|
48
|
-
# Returns an instance of the Stderr Appender. Unless the user explicitly
|
49
|
-
# creates a new Stderr Appender, the instance returned by this method
|
50
|
-
# will always be the same:
|
51
|
-
#
|
52
|
-
# Appender.stderr.object_id == Appender.stderr.object_id #=> true
|
53
|
-
#
|
54
|
-
def stderr( ) self['stderr'] || ::Logging::Appenders::Stderr.new end
|
55
|
-
|
56
|
-
end # class << self
|
57
|
-
end # class Appender
|
58
|
-
end # module Logging
|
59
|
-
|
60
|
-
# EOF
|