logging 0.4.0 → 0.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 +32 -0
- data/Manifest.txt +46 -0
- data/README.txt +85 -11
- data/Rakefile +29 -0
- data/{examples → data}/logging.yaml +0 -0
- data/lib/logging.rb +24 -6
- data/lib/logging/appender.rb +2 -12
- data/lib/logging/appenders/console.rb +3 -7
- data/lib/logging/appenders/file.rb +2 -4
- data/lib/logging/appenders/growl.rb +206 -0
- data/lib/logging/appenders/io.rb +2 -6
- data/lib/logging/appenders/rolling_file.rb +3 -7
- data/lib/logging/appenders/static_appender.rb +1 -5
- data/lib/logging/appenders/syslog.rb +210 -0
- data/lib/logging/config/yaml_configurator.rb +2 -10
- data/lib/logging/layout.rb +2 -7
- data/lib/logging/layouts/basic.rb +1 -3
- data/lib/logging/layouts/pattern.rb +1 -9
- data/lib/logging/log_event.rb +2 -4
- data/lib/logging/logger.rb +4 -19
- data/lib/logging/repository.rb +1 -10
- data/lib/logging/root_logger.rb +1 -5
- data/tasks/doc.rake +43 -0
- data/tasks/gem.rake +85 -0
- data/tasks/manifest.rake +39 -0
- data/tasks/rubyforge.rake +57 -0
- data/tasks/setup.rb +129 -0
- data/tasks/test.rake +35 -0
- data/tasks/website.rake +38 -0
- data/test/appenders/test_syslog.rb +192 -0
- data/test/benchmark.rb +13 -4
- data/test/config/test_yaml_configurator.rb +2 -2
- data/test/setup.rb +23 -21
- data/test/test_logging.rb +2 -2
- data/test/test_repository.rb +3 -5
- metadata +49 -14
- data/test/test_all.rb +0 -5
@@ -0,0 +1,206 @@
|
|
1
|
+
# $Id: growl.rb 48 2007-11-18 21:47:29Z tim_pease $
|
2
|
+
|
3
|
+
require 'logging/appender'
|
4
|
+
|
5
|
+
module Logging
|
6
|
+
module Appenders
|
7
|
+
|
8
|
+
# This class provides an Appender that can send notifications to the Growl
|
9
|
+
# notification system on Mac OS X.
|
10
|
+
#
|
11
|
+
# +growlnotify+ must be installed somewhere in the path in order for the
|
12
|
+
# appender to function properly.
|
13
|
+
#
|
14
|
+
class Growl < ::Logging::Appender
|
15
|
+
|
16
|
+
# call-seq:
|
17
|
+
# Growl.new( name, opts = {} )
|
18
|
+
#
|
19
|
+
# Create an appender that will log messages to the Growl framework on a
|
20
|
+
# Mac OS X machine.
|
21
|
+
#
|
22
|
+
def initialize( name, opts = {} )
|
23
|
+
super
|
24
|
+
|
25
|
+
@growl = "growlnotify -n '#{@name}' -t '%s' -m '%s' -p %d"
|
26
|
+
|
27
|
+
getopt = ::Logging.options(opts)
|
28
|
+
@coalesce = getopt[:coalesce, false]
|
29
|
+
@title_sep = getopt[:separator]
|
30
|
+
|
31
|
+
# provides a mapping from the default Logging levels
|
32
|
+
# to the Growl notification levels
|
33
|
+
@map = [-2, -1, 0, 1, 2]
|
34
|
+
|
35
|
+
map = getopt[:map]
|
36
|
+
self.map = map unless map.nil?
|
37
|
+
|
38
|
+
setup_coalescing if @coalesce
|
39
|
+
end
|
40
|
+
|
41
|
+
# call-seq:
|
42
|
+
# map = { logging_levels => growl_levels }
|
43
|
+
#
|
44
|
+
# Configure the mapping from the Logging levels to the Growl
|
45
|
+
# notification levels. This is needed in order to log events at the
|
46
|
+
# proper Growl level.
|
47
|
+
#
|
48
|
+
# Without any configuration, the following maping will be used:
|
49
|
+
#
|
50
|
+
# :debug => -2
|
51
|
+
# :info => -1
|
52
|
+
# :warn => 0
|
53
|
+
# :error => 1
|
54
|
+
# :fatal => 2
|
55
|
+
#
|
56
|
+
def map=( levels )
|
57
|
+
map = []
|
58
|
+
levels.keys.each do |lvl|
|
59
|
+
num = ::Logging.level_num(lvl)
|
60
|
+
map[num] = growl_level_num(levels[lvl])
|
61
|
+
end
|
62
|
+
@map = map
|
63
|
+
end
|
64
|
+
|
65
|
+
# call-seq:
|
66
|
+
# append( event )
|
67
|
+
#
|
68
|
+
# Send the given _event_ to the Growl framework. The log event will be
|
69
|
+
# processed through the Layout assciated with this appender. The message
|
70
|
+
# will be logged at the level specified by the event.
|
71
|
+
#
|
72
|
+
def append( event )
|
73
|
+
if closed?
|
74
|
+
raise RuntimeError,
|
75
|
+
"appender '<#{self.class.name}: #{@name}>' is closed"
|
76
|
+
end
|
77
|
+
|
78
|
+
sync do
|
79
|
+
title = ''
|
80
|
+
message = @layout.format(event)
|
81
|
+
priority = @map[event.level]
|
82
|
+
|
83
|
+
if @title_sep
|
84
|
+
title, message = message.split(@title_sep)
|
85
|
+
title, message = message, title if message.nil?
|
86
|
+
end
|
87
|
+
|
88
|
+
growl(title, message, priority)
|
89
|
+
end unless @level > event.level
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
# call-seq:
|
94
|
+
# syslog << string
|
95
|
+
#
|
96
|
+
# Write the given _string_ to the Growl framework "as is" -- no
|
97
|
+
# layout formatting will be performed. The string will be logged at the
|
98
|
+
# 0 notification level of the Growl framework.
|
99
|
+
#
|
100
|
+
def <<( str )
|
101
|
+
if closed?
|
102
|
+
raise RuntimeError,
|
103
|
+
"appender '<#{self.class.name}: #{@name}>' is closed"
|
104
|
+
end
|
105
|
+
|
106
|
+
title = ''
|
107
|
+
message = str
|
108
|
+
|
109
|
+
if @title_sep
|
110
|
+
title, message = message.split(@title_sep)
|
111
|
+
title, message = message, title if message.nil?
|
112
|
+
end
|
113
|
+
|
114
|
+
sync {growl(title, message, 0)}
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
# call-seq:
|
122
|
+
# growl_level_num( level ) => integer
|
123
|
+
#
|
124
|
+
# Takes the given _level_ as a string or integer and returns the
|
125
|
+
# corresponding Growl notification level number.
|
126
|
+
#
|
127
|
+
def growl_level_num( level )
|
128
|
+
level = case level
|
129
|
+
when Integer: level
|
130
|
+
when String: Integer(level)
|
131
|
+
else raise ArgumentError, "unkonwn level '#{level}'" end
|
132
|
+
if level < -2 or level > 2
|
133
|
+
raise ArgumentError, "level '#{level}' is not in range -2..2"
|
134
|
+
end
|
135
|
+
level
|
136
|
+
end
|
137
|
+
|
138
|
+
# call-seq:
|
139
|
+
# growl( title, message, priority )
|
140
|
+
#
|
141
|
+
# Send the _message_ to the growl notifier using the given _title_ and
|
142
|
+
# _priority_.
|
143
|
+
#
|
144
|
+
def growl( title, message, priority )
|
145
|
+
if @coalesce then coalesce(title, message, priority)
|
146
|
+
else system @growl % [title, message, priority] end
|
147
|
+
end
|
148
|
+
|
149
|
+
# call-seq:
|
150
|
+
# coalesce( title, message, priority )
|
151
|
+
#
|
152
|
+
# Attempt to coalesce the given _message_ with any that might be pending
|
153
|
+
# in the queue to send to the growl notifier. Messages are coalesced
|
154
|
+
# with any in the queue that have the same _title_ and _priority_.
|
155
|
+
#
|
156
|
+
# There can be only one message in the queue, so if the _title_ and/or
|
157
|
+
# _priority_ don't match, the message in the queue is sent immediately
|
158
|
+
# to the growl notifier, and the current _message_ is queued.
|
159
|
+
#
|
160
|
+
def coalesce( *msg )
|
161
|
+
@c_mutex.synchronize do
|
162
|
+
if @c_message.nil? or @c_message.first != msg.first or @c_message.last != msg.last
|
163
|
+
@c_message, msg = msg, @c_message
|
164
|
+
@c_thread.run
|
165
|
+
|
166
|
+
else
|
167
|
+
@c_message[1] << "\n" << msg[1]
|
168
|
+
msg = nil
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
system @growl % msg unless msg.nil?
|
173
|
+
Thread.pass
|
174
|
+
end
|
175
|
+
|
176
|
+
# call-seq:
|
177
|
+
# setup_coalescing
|
178
|
+
#
|
179
|
+
# Setup the appender to handle coalescing of messages before sending
|
180
|
+
# them to the growl notifier. This requires the creation of a thread and
|
181
|
+
# mutex for passing messages from the appender thread to the growl
|
182
|
+
# notifier thread.
|
183
|
+
#
|
184
|
+
def setup_coalescing
|
185
|
+
@c_mutex = Mutex.new
|
186
|
+
@c_message = nil
|
187
|
+
|
188
|
+
@c_thread = Thread.new do
|
189
|
+
loop do
|
190
|
+
Thread.stop
|
191
|
+
sleep 0.5
|
192
|
+
@c_mutex.synchronize do
|
193
|
+
break if @c_message.nil?
|
194
|
+
system @growl % @c_message
|
195
|
+
@c_message = nil
|
196
|
+
end
|
197
|
+
end # loop
|
198
|
+
end # Thread.new
|
199
|
+
end
|
200
|
+
|
201
|
+
end # class Growl
|
202
|
+
|
203
|
+
end # module Appenders
|
204
|
+
end # module Logging
|
205
|
+
|
206
|
+
# EOF
|
data/lib/logging/appenders/io.rb
CHANGED
@@ -1,17 +1,15 @@
|
|
1
|
-
# $Id: io.rb
|
1
|
+
# $Id: io.rb 37 2007-10-26 19:12:44Z tim_pease $
|
2
2
|
|
3
3
|
require 'logging/appender'
|
4
4
|
|
5
5
|
module Logging
|
6
6
|
module Appenders
|
7
7
|
|
8
|
-
#
|
9
8
|
# This class provides an Appender that can write to any IO stream
|
10
9
|
# configured for writing.
|
11
10
|
#
|
12
11
|
class IO < ::Logging::Appender
|
13
12
|
|
14
|
-
#
|
15
13
|
# call-seq:
|
16
14
|
# IO.new( name, io )
|
17
15
|
# IO.new( name, io, :layout => layout )
|
@@ -29,7 +27,6 @@ module Appenders
|
|
29
27
|
super(name, opts)
|
30
28
|
end
|
31
29
|
|
32
|
-
#
|
33
30
|
# call-seq:
|
34
31
|
# close( footer = true )
|
35
32
|
#
|
@@ -46,7 +43,6 @@ module Appenders
|
|
46
43
|
self
|
47
44
|
end
|
48
45
|
|
49
|
-
#
|
50
46
|
# call-seq:
|
51
47
|
# flush
|
52
48
|
#
|
@@ -61,7 +57,7 @@ module Appenders
|
|
61
57
|
|
62
58
|
|
63
59
|
private
|
64
|
-
|
60
|
+
|
65
61
|
# call-seq:
|
66
62
|
# write( str )
|
67
63
|
#
|
@@ -1,10 +1,9 @@
|
|
1
|
-
# $Id: rolling_file.rb
|
1
|
+
# $Id: rolling_file.rb 37 2007-10-26 19:12:44Z tim_pease $
|
2
2
|
|
3
3
|
require 'logging/appenders/file'
|
4
4
|
|
5
5
|
module Logging::Appenders
|
6
6
|
|
7
|
-
#
|
8
7
|
# An appender that writes to a file and ensures that the file size or age
|
9
8
|
# never exceeds some user specified level.
|
10
9
|
#
|
@@ -31,7 +30,6 @@ module Logging::Appenders
|
|
31
30
|
#
|
32
31
|
class RollingFile < ::Logging::Appenders::File
|
33
32
|
|
34
|
-
#
|
35
33
|
# call-seq:
|
36
34
|
# RollingFile.new( name, opts )
|
37
35
|
#
|
@@ -139,8 +137,9 @@ module Logging::Appenders
|
|
139
137
|
super(name, opts)
|
140
138
|
end
|
141
139
|
|
140
|
+
|
142
141
|
private
|
143
|
-
|
142
|
+
|
144
143
|
# call-seq:
|
145
144
|
# write( str )
|
146
145
|
#
|
@@ -154,7 +153,6 @@ module Logging::Appenders
|
|
154
153
|
roll if roll_required? # the file IO stream is probably not being
|
155
154
|
end # flushed to disk immediately
|
156
155
|
|
157
|
-
#
|
158
156
|
# call-seq:
|
159
157
|
# roll
|
160
158
|
#
|
@@ -167,7 +165,6 @@ module Logging::Appenders
|
|
167
165
|
@io = ::File.new(@fn, 'a')
|
168
166
|
end
|
169
167
|
|
170
|
-
#
|
171
168
|
# call-seq:
|
172
169
|
# roll_required?
|
173
170
|
#
|
@@ -184,7 +181,6 @@ module Logging::Appenders
|
|
184
181
|
return sufficiently_aged?
|
185
182
|
end
|
186
183
|
|
187
|
-
#
|
188
184
|
# call-seq:
|
189
185
|
# roll_files
|
190
186
|
#
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: static_appender.rb
|
1
|
+
# $Id: static_appender.rb 37 2007-10-26 19:12:44Z tim_pease $
|
2
2
|
|
3
3
|
require 'logging/appenders/console'
|
4
4
|
|
@@ -9,7 +9,6 @@ class Appender
|
|
9
9
|
|
10
10
|
class << self
|
11
11
|
|
12
|
-
#
|
13
12
|
# call-seq:
|
14
13
|
# Appender[name]
|
15
14
|
#
|
@@ -18,7 +17,6 @@ class Appender
|
|
18
17
|
#
|
19
18
|
def []( name ) @appenders[name] end
|
20
19
|
|
21
|
-
#
|
22
20
|
# call-seq:
|
23
21
|
# Appender[name] = appender
|
24
22
|
#
|
@@ -27,7 +25,6 @@ class Appender
|
|
27
25
|
#
|
28
26
|
def []=( name, val ) @appenders[name] = val end
|
29
27
|
|
30
|
-
#
|
31
28
|
# call-seq:
|
32
29
|
# Appender.stdout
|
33
30
|
#
|
@@ -39,7 +36,6 @@ class Appender
|
|
39
36
|
#
|
40
37
|
def stdout( ) self['stdout'] || ::Logging::Appenders::Stdout.new end
|
41
38
|
|
42
|
-
#
|
43
39
|
# call-seq:
|
44
40
|
# Appender.stderr
|
45
41
|
#
|
@@ -0,0 +1,210 @@
|
|
1
|
+
# $Id: syslog.rb 46 2007-10-31 14:39:01Z tim_pease $
|
2
|
+
|
3
|
+
require 'logging/appender'
|
4
|
+
require 'syslog'
|
5
|
+
|
6
|
+
module Logging
|
7
|
+
module Appenders
|
8
|
+
|
9
|
+
# This class provides an Appender that can write to the UNIX syslog
|
10
|
+
# daemon.
|
11
|
+
#
|
12
|
+
class Syslog < ::Logging::Appender
|
13
|
+
include ::Syslog::Constants
|
14
|
+
|
15
|
+
# call-seq:
|
16
|
+
# Syslog.new( name, opts = {} )
|
17
|
+
#
|
18
|
+
# Create an appender that will log messages to the system message
|
19
|
+
# logger. The message is then written to the system console, log files,
|
20
|
+
# logged-in users, or forwarded to other machines as appropriate. The
|
21
|
+
# options that can be used to configure the appender are as follows:
|
22
|
+
#
|
23
|
+
# :ident => identifier string (name is used by default)
|
24
|
+
# :logopt => options used when opening the connection
|
25
|
+
# :facility => the syslog facility to use
|
26
|
+
#
|
27
|
+
# The parameter :ident is a string that will be prepended to every
|
28
|
+
# message. The :logopt argument is a bit field specifying logging
|
29
|
+
# options, which is formed by OR'ing one or more of the following
|
30
|
+
# values:
|
31
|
+
#
|
32
|
+
# LOG_CONS If syslog() cannot pass the message to syslogd(8) it
|
33
|
+
# wil attempt to write the message to the console
|
34
|
+
# ('/dev/console').
|
35
|
+
#
|
36
|
+
# LOG_NDELAY Open the connection to syslogd(8) immediately. Normally
|
37
|
+
# the open is delayed until the first message is logged.
|
38
|
+
# Useful for programs that need to manage the order in
|
39
|
+
# which file descriptors are allocated.
|
40
|
+
#
|
41
|
+
# LOG_PERROR Write the message to standard error output as well to
|
42
|
+
# the system log.
|
43
|
+
#
|
44
|
+
# LOG_PID Log the process id with each message: useful for
|
45
|
+
# identifying instantiations of daemons.
|
46
|
+
#
|
47
|
+
# The :facility parameter encodes a default facility to be assigned to
|
48
|
+
# all messages that do not have an explicit facility encoded:
|
49
|
+
#
|
50
|
+
# LOG_AUTH The authorization system: login(1), su(1), getty(8),
|
51
|
+
# etc.
|
52
|
+
#
|
53
|
+
# LOG_AUTHPRIV The same as LOG_AUTH, but logged to a file readable
|
54
|
+
# only by selected individuals.
|
55
|
+
#
|
56
|
+
# LOG_CONSOLE Messages written to /dev/console by the kernel console
|
57
|
+
# output driver.
|
58
|
+
#
|
59
|
+
# LOG_CRON The cron daemon: cron(8).
|
60
|
+
#
|
61
|
+
# LOG_DAEMON System daemons, such as routed(8), that are not
|
62
|
+
# provided for explicitly by other facilities.
|
63
|
+
#
|
64
|
+
# LOG_FTP The file transfer protocol daemons: ftpd(8), tftpd(8).
|
65
|
+
#
|
66
|
+
# LOG_KERN Messages generated by the kernel. These cannot be
|
67
|
+
# generated by any user processes.
|
68
|
+
#
|
69
|
+
# LOG_LPR The line printer spooling system: lpr(1), lpc(8),
|
70
|
+
# lpd(8), etc.
|
71
|
+
#
|
72
|
+
# LOG_MAIL The mail system.
|
73
|
+
#
|
74
|
+
# LOG_NEWS The network news system.
|
75
|
+
#
|
76
|
+
# LOG_SECURITY Security subsystems, such as ipfw(4).
|
77
|
+
#
|
78
|
+
# LOG_SYSLOG Messages generated internally by syslogd(8).
|
79
|
+
#
|
80
|
+
# LOG_USER Messages generated by random user processes. This is
|
81
|
+
# the default facility identifier if none is specified.
|
82
|
+
#
|
83
|
+
# LOG_UUCP The uucp system.
|
84
|
+
#
|
85
|
+
# LOG_LOCAL0 Reserved for local use. Similarly for LOG_LOCAL1
|
86
|
+
# through LOG_LOCAL7.
|
87
|
+
#
|
88
|
+
def initialize( name, opts = {} )
|
89
|
+
super
|
90
|
+
|
91
|
+
ident = opts[:ident] || opts['ident'] || name
|
92
|
+
logopt = opts[:logopt] || opts['logopt'] || (LOG_PID | LOG_CONS)
|
93
|
+
facility = opts[:facility] || opts['facility'] || LOG_USER
|
94
|
+
@syslog = ::Syslog.open(ident, Integer(logopt), Integer(facility))
|
95
|
+
|
96
|
+
# provides a mapping from the default Logging levels
|
97
|
+
# to the syslog levels
|
98
|
+
@map = [LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR, LOG_CRIT]
|
99
|
+
|
100
|
+
if opts.has_key?('map') or opts.has_key?(:map)
|
101
|
+
self.map = opts[:map] || opts['map']
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# call-seq:
|
106
|
+
# map = { logging_levels => syslog_levels }
|
107
|
+
#
|
108
|
+
# Configure the mapping from the Logging levels to the syslog levels.
|
109
|
+
# This is needed in order to log events at the proper syslog level.
|
110
|
+
#
|
111
|
+
# Without any configuration, the following maping will be used:
|
112
|
+
#
|
113
|
+
# :debug => LOG_DEBUG
|
114
|
+
# :info => LOG_INFO
|
115
|
+
# :warn => LOG_WARNING
|
116
|
+
# :error => LOG_ERR
|
117
|
+
# :fatal => LOG_CRIT
|
118
|
+
#
|
119
|
+
def map=( levels )
|
120
|
+
map = []
|
121
|
+
levels.keys.each do |lvl|
|
122
|
+
num = ::Logging.level_num(lvl)
|
123
|
+
map[num] = syslog_level_num(levels[lvl])
|
124
|
+
end
|
125
|
+
@map = map
|
126
|
+
end
|
127
|
+
|
128
|
+
# call-seq:
|
129
|
+
# close
|
130
|
+
#
|
131
|
+
# Closes the connetion to the syslog facility.
|
132
|
+
#
|
133
|
+
def close
|
134
|
+
@syslog.close
|
135
|
+
end
|
136
|
+
|
137
|
+
# call-seq:
|
138
|
+
# closed? => true or false
|
139
|
+
#
|
140
|
+
# Queries the connection to the syslog facility and returns +true+ if
|
141
|
+
# the connection is closed.
|
142
|
+
#
|
143
|
+
def closed?
|
144
|
+
!@syslog.opened?
|
145
|
+
end
|
146
|
+
|
147
|
+
# call-seq:
|
148
|
+
# append( event )
|
149
|
+
#
|
150
|
+
# Write the given _event_ to the syslog facility. The log event will be
|
151
|
+
# processed through the Layout assciated with this appender. The message
|
152
|
+
# will be logged at the level specified by the event.
|
153
|
+
#
|
154
|
+
def append( event )
|
155
|
+
if closed?
|
156
|
+
raise RuntimeError,
|
157
|
+
"appender '<#{self.class.name}: #{@name}>' is closed"
|
158
|
+
end
|
159
|
+
|
160
|
+
sync do
|
161
|
+
msg = @layout.format(event)
|
162
|
+
pri = @map[event.level]
|
163
|
+
@syslog.log(pri, '%s', msg)
|
164
|
+
end unless @level > event.level
|
165
|
+
self
|
166
|
+
end
|
167
|
+
|
168
|
+
# call-seq:
|
169
|
+
# syslog << string
|
170
|
+
#
|
171
|
+
# Write the given _string_ to the syslog facility "as is" -- no
|
172
|
+
# layout formatting will be performed. The string will be logged at the
|
173
|
+
# LOG_DEBUG level of the syslog facility.
|
174
|
+
#
|
175
|
+
def <<( str )
|
176
|
+
if closed?
|
177
|
+
raise RuntimeError,
|
178
|
+
"appender '<#{self.class.name}: #{@name}>' is closed"
|
179
|
+
end
|
180
|
+
|
181
|
+
sync {@syslog.log(LOG_DEBUG, '%s', str)}
|
182
|
+
self
|
183
|
+
end
|
184
|
+
|
185
|
+
|
186
|
+
private
|
187
|
+
|
188
|
+
# call-seq:
|
189
|
+
# syslog_level_num( level ) => integer
|
190
|
+
#
|
191
|
+
# Takes the given _level_ as a string, symbol, or integer and returns
|
192
|
+
# the corresponding syslog level number.
|
193
|
+
#
|
194
|
+
def syslog_level_num( level )
|
195
|
+
case level
|
196
|
+
when Integer: level
|
197
|
+
when String, Symbol:
|
198
|
+
level = level.to_s.upcase
|
199
|
+
self.class.const_get level
|
200
|
+
else
|
201
|
+
raise ArgumentError, "unkonwn level '#{level}'"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
end # class Syslog
|
206
|
+
|
207
|
+
end # module Appenders
|
208
|
+
end # module Logging
|
209
|
+
|
210
|
+
# EOF
|