logging 0.1.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/README.txt +11 -0
- data/lib/logging.rb +129 -0
- data/lib/logging/appender.rb +205 -0
- data/lib/logging/appenders/console.rb +47 -0
- data/lib/logging/appenders/file.rb +45 -0
- data/lib/logging/appenders/io.rb +87 -0
- data/lib/logging/appenders/static_appender.rb +58 -0
- data/lib/logging/layout.rb +102 -0
- data/lib/logging/layouts/basic.rb +48 -0
- data/lib/logging/layouts/pattern.rb +320 -0
- data/lib/logging/log_event.rb +52 -0
- data/lib/logging/logger.rb +345 -0
- data/lib/logging/repository.rb +148 -0
- data/lib/logging/root_logger.rb +69 -0
- data/test/appenders/test_console.rb +40 -0
- data/test/appenders/test_file.rb +76 -0
- data/test/appenders/test_io.rb +113 -0
- data/test/benchmark.rb +80 -0
- data/test/layouts/test_basic.rb +46 -0
- data/test/layouts/test_pattern.rb +175 -0
- data/test/setup.rb +45 -0
- data/test/test_all.rb +5 -0
- data/test/test_appender.rb +136 -0
- data/test/test_layout.rb +85 -0
- data/test/test_log_event.rb +81 -0
- data/test/test_logger.rb +472 -0
- data/test/test_logging.rb +121 -0
- data/test/test_repository.rb +113 -0
- data/test/test_root_logger.rb +67 -0
- metadata +75 -0
data/README.txt
ADDED
data/lib/logging.rb
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# $Id: logging.rb 12 2007-01-14 20:03:40Z tim_pease $
|
|
2
|
+
|
|
3
|
+
require 'logging/repository'
|
|
4
|
+
|
|
5
|
+
# require all appenders
|
|
6
|
+
require 'logging/appenders/console'
|
|
7
|
+
require 'logging/appenders/file'
|
|
8
|
+
require 'logging/appenders/static_appender'
|
|
9
|
+
|
|
10
|
+
# require all layouts
|
|
11
|
+
require 'logging/layouts/basic'
|
|
12
|
+
require 'logging/layouts/pattern'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
#
|
|
17
|
+
#
|
|
18
|
+
module Logging
|
|
19
|
+
|
|
20
|
+
LEVELS = {} # :nodoc:
|
|
21
|
+
LNAMES = {} # :nodoc:
|
|
22
|
+
|
|
23
|
+
class << self
|
|
24
|
+
#
|
|
25
|
+
# call-seq:
|
|
26
|
+
# define_levels( levels )
|
|
27
|
+
#
|
|
28
|
+
# Defines the levels available to the loggers. The _levels_ is an array
|
|
29
|
+
# of strings and symbols. Each element in the array is downcased and
|
|
30
|
+
# converted to a symbol; these symbols are used to create the logging
|
|
31
|
+
# methods in the loggers.
|
|
32
|
+
#
|
|
33
|
+
# The first element in the array is the lowest logging level. Setting the
|
|
34
|
+
# logging level to this value will enable all log messages. The last
|
|
35
|
+
# element in the array is the highest logging level. Setting the logging
|
|
36
|
+
# level to this value will disable all log messages except this highest
|
|
37
|
+
# level.
|
|
38
|
+
#
|
|
39
|
+
# This method should only be invoked once to configure the logging
|
|
40
|
+
# levels. It is automatically invoked with the default logging levels
|
|
41
|
+
# when the first logger is created.
|
|
42
|
+
#
|
|
43
|
+
# The levels "all" and "off" are reserved and will be ignored if passed
|
|
44
|
+
# to this method.
|
|
45
|
+
#
|
|
46
|
+
# Example:
|
|
47
|
+
#
|
|
48
|
+
# Logging.define_levels :debug, :info, :warn, :error, :fatal
|
|
49
|
+
# log = Logging::Logger['my logger']
|
|
50
|
+
# log.level = :warn
|
|
51
|
+
# log.warn 'Danger! Danger! Will Robinson'
|
|
52
|
+
# log.info 'Just FYI' # => not logged
|
|
53
|
+
#
|
|
54
|
+
# or
|
|
55
|
+
#
|
|
56
|
+
# Logging.define_levels %w(DEBUG INFO NOTICE WARNING ERR CRIT ALERT EMERG)
|
|
57
|
+
# log = Logging::Logger['syslog']
|
|
58
|
+
# log.level = :notice
|
|
59
|
+
# log.warning 'This is your first warning'
|
|
60
|
+
# log.info 'Just FYI' # => not logged
|
|
61
|
+
#
|
|
62
|
+
def define_levels( *args )
|
|
63
|
+
return nil if args.empty?
|
|
64
|
+
|
|
65
|
+
args.flatten!
|
|
66
|
+
levels = ::Logging::LEVELS.clear
|
|
67
|
+
names = ::Logging::LNAMES.clear
|
|
68
|
+
|
|
69
|
+
id = 0
|
|
70
|
+
args.each do |lvl|
|
|
71
|
+
lvl = levelify lvl
|
|
72
|
+
unless levels.has_key?(lvl) or lvl == 'all' or lvl == 'off'
|
|
73
|
+
levels[lvl] = id
|
|
74
|
+
names[id] = lvl.upcase
|
|
75
|
+
id += 1
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
longest = names.values.inject {|x,y| (x.length > y.length) ? x : y}
|
|
80
|
+
module_eval "MAX_LEVEL_LENGTH = #{longest.length}"
|
|
81
|
+
|
|
82
|
+
levels.keys
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
#
|
|
86
|
+
# call-seq:
|
|
87
|
+
# format_as( obj_format )
|
|
88
|
+
#
|
|
89
|
+
# Defines the default _obj_format_ method to use when converting objects
|
|
90
|
+
# into string representations for logging. _obj_format_ can be one of
|
|
91
|
+
# <tt>:string</tt>, <tt>:inspect</tt>, or <tt>:yaml</tt>. These
|
|
92
|
+
# formatting commands map to the following object methods
|
|
93
|
+
#
|
|
94
|
+
# * :string => to_s
|
|
95
|
+
# * :inspect => inspect
|
|
96
|
+
# * :yaml => to_yaml
|
|
97
|
+
#
|
|
98
|
+
# An +ArgumentError+ is raised if anything other than +:string+,
|
|
99
|
+
# +:inspect+, +:yaml+ is passed to this method.
|
|
100
|
+
#
|
|
101
|
+
def format_as( f )
|
|
102
|
+
unless [:string, :inspect, :yaml].include? f
|
|
103
|
+
raise ArgumentError, "unknown object format '#{f}'"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
module_eval "OBJ_FORMAT = :#{f}"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# :stopdoc:
|
|
110
|
+
def levelify( level )
|
|
111
|
+
case level
|
|
112
|
+
when String: level.downcase
|
|
113
|
+
when Symbol: level.to_s.downcase
|
|
114
|
+
else raise ArgumentError, "levels must be a String or Symbol" end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def level_num( level )
|
|
118
|
+
l = levelify level
|
|
119
|
+
case l
|
|
120
|
+
when 'all': 0
|
|
121
|
+
when 'off': LEVELS.length
|
|
122
|
+
else LEVELS[l] end
|
|
123
|
+
end
|
|
124
|
+
# :startdoc:
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
end # module Logging
|
|
128
|
+
|
|
129
|
+
# EOF
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# $Id: appender.rb 12 2007-01-14 20:03:40Z tim_pease $
|
|
2
|
+
|
|
3
|
+
require 'sync'
|
|
4
|
+
require 'logging'
|
|
5
|
+
require 'logging/logger'
|
|
6
|
+
require 'logging/layout'
|
|
7
|
+
require 'logging/layouts/basic'
|
|
8
|
+
|
|
9
|
+
module Logging
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# The +Appender+ class is provides methods for appending log events to a
|
|
13
|
+
# logging destination. The log events are formatted into strings using a
|
|
14
|
+
# Layout.
|
|
15
|
+
#
|
|
16
|
+
# All other Appenders inherit from this class which provides stub methods.
|
|
17
|
+
# Each subclass should provide a +write+ method that will write log
|
|
18
|
+
# messages to the logging destination.
|
|
19
|
+
#
|
|
20
|
+
# A private +sync+ method is provided for use by subclasses. It is used to
|
|
21
|
+
# synchronize writes to the logging destination, and can be used by
|
|
22
|
+
# subclasses to synchronize the closing or flushing of the logging
|
|
23
|
+
# destination.
|
|
24
|
+
#
|
|
25
|
+
class Appender
|
|
26
|
+
|
|
27
|
+
attr_reader :name, :layout, :level
|
|
28
|
+
|
|
29
|
+
#
|
|
30
|
+
# call-seq:
|
|
31
|
+
# Appender.new( name )
|
|
32
|
+
# Appender.new( name, :layout => layout )
|
|
33
|
+
#
|
|
34
|
+
# Creates a new appender using the given name. If no Layout is specified,
|
|
35
|
+
# then a Basic layout will be used. Any logging header supplied by the
|
|
36
|
+
# layout will be written to the logging destination when the Appender is
|
|
37
|
+
# created.
|
|
38
|
+
#
|
|
39
|
+
def initialize( name, opts = {} )
|
|
40
|
+
@name = name.to_s
|
|
41
|
+
@closed = false
|
|
42
|
+
@level = 0
|
|
43
|
+
self.layout = opts[:layout] if opts.include? :layout
|
|
44
|
+
@layout ||= ::Logging::Layouts::Basic.new
|
|
45
|
+
|
|
46
|
+
@sync = Sync.new
|
|
47
|
+
sync {write(@layout.header)}
|
|
48
|
+
|
|
49
|
+
::Logging::Appender[@name] = self
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
# call-seq:
|
|
54
|
+
# append( event )
|
|
55
|
+
#
|
|
56
|
+
# Write the given _event_ to the logging destination. The log event will
|
|
57
|
+
# be processed through the Layout associated with the Appender.
|
|
58
|
+
#
|
|
59
|
+
def append( event )
|
|
60
|
+
if @closed
|
|
61
|
+
raise RuntimeError,
|
|
62
|
+
"appender '<#{self.class.name}: #{@name}>' is closed"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
sync {write(@layout.format(event))} unless @level > event.level
|
|
66
|
+
self
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
#
|
|
70
|
+
# call-seq:
|
|
71
|
+
# appender << string
|
|
72
|
+
#
|
|
73
|
+
# Write the given _string_ to the logging destination "as is" -- no
|
|
74
|
+
# layout formatting will be performed.
|
|
75
|
+
#
|
|
76
|
+
def <<( str )
|
|
77
|
+
if @closed
|
|
78
|
+
raise RuntimeError,
|
|
79
|
+
"appender '<#{self.class.name}: #{@name}>' is closed"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
sync {write(str)}
|
|
83
|
+
self
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
#
|
|
87
|
+
# call-seq:
|
|
88
|
+
# level = :all
|
|
89
|
+
#
|
|
90
|
+
# Set the level for this appender; log events below this level will be
|
|
91
|
+
# ignored by this appender. The level can be either a +String+, a
|
|
92
|
+
# +Symbol+, or a +Fixnum+. An +ArgumentError+ is raised if this is not
|
|
93
|
+
# the case.
|
|
94
|
+
#
|
|
95
|
+
# There are two special levels -- "all" and "off". The former will
|
|
96
|
+
# enable recording of all log events. The latter will disable the
|
|
97
|
+
# recording of all events.
|
|
98
|
+
#
|
|
99
|
+
# Example:
|
|
100
|
+
#
|
|
101
|
+
# appender.level = :debug
|
|
102
|
+
# appender.level = "INFO"
|
|
103
|
+
# appender.level = 4
|
|
104
|
+
# appender.level = 'off'
|
|
105
|
+
# appender.level = :all
|
|
106
|
+
#
|
|
107
|
+
# These prodcue an +ArgumentError+
|
|
108
|
+
#
|
|
109
|
+
# appender.level = Object
|
|
110
|
+
# appender.level = -1
|
|
111
|
+
# appender.level = 1_000_000_000_000
|
|
112
|
+
#
|
|
113
|
+
def level=( level )
|
|
114
|
+
lvl = case level
|
|
115
|
+
when String, Symbol: ::Logging::level_num(level)
|
|
116
|
+
when Fixnum: level
|
|
117
|
+
when nil: 0
|
|
118
|
+
else
|
|
119
|
+
raise ArgumentError,
|
|
120
|
+
"level must be a String, Symbol, or Integer"
|
|
121
|
+
end
|
|
122
|
+
if lvl.nil? or lvl < 0 or lvl > ::Logging::LEVELS.length
|
|
123
|
+
raise ArgumentError, "unknown level was given '#{level}'"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
@level = lvl
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
#
|
|
130
|
+
# call-seq
|
|
131
|
+
# appender.layout = Logging::Layouts::Basic.new
|
|
132
|
+
#
|
|
133
|
+
# Sets the layout to be used by this appender.
|
|
134
|
+
#
|
|
135
|
+
def layout=( layout )
|
|
136
|
+
unless layout.kind_of? ::Logging::Layout
|
|
137
|
+
raise TypeError,
|
|
138
|
+
"#{layout.inspect} is not a kind of 'Logging::Layout'"
|
|
139
|
+
end
|
|
140
|
+
@layout = layout
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
#
|
|
144
|
+
# call-seq:
|
|
145
|
+
# close( footer = true )
|
|
146
|
+
#
|
|
147
|
+
# Close the appender and writes the layout footer to the logging
|
|
148
|
+
# destination if the _footer_ flag is set to +true+. Log events will
|
|
149
|
+
# no longer be written to the logging destination after the appender
|
|
150
|
+
# is closed.
|
|
151
|
+
#
|
|
152
|
+
def close( footer = true )
|
|
153
|
+
return self if @closed
|
|
154
|
+
@closed = true
|
|
155
|
+
sync {write(@layout.footer)} if footer
|
|
156
|
+
self
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
#
|
|
160
|
+
# call-seq:
|
|
161
|
+
# closed?
|
|
162
|
+
#
|
|
163
|
+
# Returns +true+ if the appender has been closed; returns +false+
|
|
164
|
+
# otherwise. When an appender is closed, no more log events can be
|
|
165
|
+
# written to the logging destination.
|
|
166
|
+
#
|
|
167
|
+
def closed?( ) @closed end
|
|
168
|
+
|
|
169
|
+
#
|
|
170
|
+
# call-seq:
|
|
171
|
+
# flush
|
|
172
|
+
#
|
|
173
|
+
# Call +flush+ to force an appender to write out any buffered log events.
|
|
174
|
+
# Similar to IO#flush, so use in a similar fashion.
|
|
175
|
+
#
|
|
176
|
+
def flush( ) self end
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
private
|
|
180
|
+
#
|
|
181
|
+
# call-seq:
|
|
182
|
+
# write( str )
|
|
183
|
+
#
|
|
184
|
+
# Writes the given string to the logging destination. Subclasses should
|
|
185
|
+
# provide an implementation of this method.
|
|
186
|
+
#
|
|
187
|
+
def write( str ) nil end
|
|
188
|
+
|
|
189
|
+
#
|
|
190
|
+
# call-seq:
|
|
191
|
+
# sync { block }
|
|
192
|
+
#
|
|
193
|
+
# Obtains an exclusive lock, runs the block, and releases the lock when
|
|
194
|
+
# the block completes. This method is re-entrant so that a single thread
|
|
195
|
+
# can call +sync+ multiple times without hanging the thread.
|
|
196
|
+
#
|
|
197
|
+
def sync
|
|
198
|
+
if Thread.current == @sync.sync_ex_locker then yield
|
|
199
|
+
else @sync.synchronize(:EX) {yield} end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
end # class Appender
|
|
203
|
+
end # module Logging
|
|
204
|
+
|
|
205
|
+
# EOF
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# $Id: console.rb 2 2007-01-09 18:10:50Z tim_pease $
|
|
2
|
+
|
|
3
|
+
require 'logging/appenders/io'
|
|
4
|
+
|
|
5
|
+
module Logging
|
|
6
|
+
module Appenders
|
|
7
|
+
|
|
8
|
+
#
|
|
9
|
+
# This class provides an Appender that can write to STDOUT.
|
|
10
|
+
#
|
|
11
|
+
class StdOut< ::Logging::Appenders::IO
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
# call-seq:
|
|
15
|
+
# StdOut.new
|
|
16
|
+
# StdOut.new( :layout => layout )
|
|
17
|
+
#
|
|
18
|
+
# Creates a new StdOut Appender. The name 'stdout' will always be used for
|
|
19
|
+
# this appender.
|
|
20
|
+
#
|
|
21
|
+
def initialize( opts = {} )
|
|
22
|
+
super('stdout', STDOUT, opts)
|
|
23
|
+
end
|
|
24
|
+
end # class StdOut
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# This class provides an Appender that can write to STDERR.
|
|
28
|
+
#
|
|
29
|
+
class StdErr< ::Logging::Appenders::IO
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# call-seq:
|
|
33
|
+
# StdErr.new
|
|
34
|
+
# StdErr.new( :layout => layout )
|
|
35
|
+
#
|
|
36
|
+
# Creates a new StdErr Appender. The name 'stderr' will always be used for
|
|
37
|
+
# this appender.
|
|
38
|
+
#
|
|
39
|
+
def initialize( opts = {} )
|
|
40
|
+
super('stderr', STDERR, opts)
|
|
41
|
+
end
|
|
42
|
+
end # class StdErr
|
|
43
|
+
|
|
44
|
+
end # module Appenders
|
|
45
|
+
end # module Logging
|
|
46
|
+
|
|
47
|
+
# EOF
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# $Id: file.rb 2 2007-01-09 18:10:50Z tim_pease $
|
|
2
|
+
|
|
3
|
+
require 'logging/appenders/io'
|
|
4
|
+
|
|
5
|
+
module Logging
|
|
6
|
+
module Appenders
|
|
7
|
+
|
|
8
|
+
#
|
|
9
|
+
# This class provides an Appender that can write to a File.
|
|
10
|
+
#
|
|
11
|
+
class File < ::Logging::Appenders::IO
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
# call-seq:
|
|
15
|
+
# File.new( filename )
|
|
16
|
+
# File.new( filename, :truncate => true )
|
|
17
|
+
# File.new( filename, :layout => layout )
|
|
18
|
+
#
|
|
19
|
+
# Creates a new File Appender that will use the given _filename_ as the
|
|
20
|
+
# logging destination. If the file does not already exist it will be
|
|
21
|
+
# created. If the :truncate option is set to +true+ then the file will be
|
|
22
|
+
# truncated before writing begins; otherwise, log messages will be appened
|
|
23
|
+
# to the file.
|
|
24
|
+
#
|
|
25
|
+
def initialize( filename, opts = {} )
|
|
26
|
+
mode = opts.delete(:truncate) ? 'w' : 'a'
|
|
27
|
+
|
|
28
|
+
if ::File.exist?(filename)
|
|
29
|
+
if not ::File.file?(filename)
|
|
30
|
+
raise StandardError, "#{filename} is not a regular file"
|
|
31
|
+
elsif not ::File.writable?(filename)
|
|
32
|
+
raise StandardError, "#{filename} is not writeable"
|
|
33
|
+
end
|
|
34
|
+
elsif not ::File.writable?(::File.dirname(filename))
|
|
35
|
+
raise StandardError, "#{::File.dirname(filename)} is not writable"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
super(filename, ::File.new(filename, mode), opts)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end # class FileAppender
|
|
42
|
+
end # module Appenders
|
|
43
|
+
end # module Logging
|
|
44
|
+
|
|
45
|
+
# EOF
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# $Id: io.rb 10 2007-01-12 18:57:07Z tim_pease $
|
|
2
|
+
|
|
3
|
+
require 'logging/appender'
|
|
4
|
+
|
|
5
|
+
module Logging
|
|
6
|
+
module Appenders
|
|
7
|
+
|
|
8
|
+
#
|
|
9
|
+
# This class provides an Appender that can write to any IO stream
|
|
10
|
+
# configured for writing.
|
|
11
|
+
#
|
|
12
|
+
class IO < ::Logging::Appender
|
|
13
|
+
|
|
14
|
+
#
|
|
15
|
+
# call-seq:
|
|
16
|
+
# IO.new( name, io )
|
|
17
|
+
# IO.new( name, io, :layout => layout )
|
|
18
|
+
#
|
|
19
|
+
# Creates a new IO Appender using the given name that will use the _io_
|
|
20
|
+
# stream as the logging destination.
|
|
21
|
+
#
|
|
22
|
+
def initialize( name, io, opts = {} )
|
|
23
|
+
unless io.respond_to? :print
|
|
24
|
+
raise TypeError, "expecting an IO object but got '#{io.class.name}'"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
@io = io
|
|
28
|
+
@io.sync = true
|
|
29
|
+
|
|
30
|
+
super(name, opts)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
#
|
|
34
|
+
# call-seq:
|
|
35
|
+
# close( footer = true )
|
|
36
|
+
#
|
|
37
|
+
# Close the appender and writes the layout footer to the logging
|
|
38
|
+
# destination if the _footer_ flag is set to +true+. Log events will
|
|
39
|
+
# no longer be written to the logging destination after the appender
|
|
40
|
+
# is closed.
|
|
41
|
+
#
|
|
42
|
+
def close( *args )
|
|
43
|
+
return self if @io.nil?
|
|
44
|
+
sync do
|
|
45
|
+
super(*args)
|
|
46
|
+
@io.close unless [STDIN, STDERR, STDOUT].include?(@io)
|
|
47
|
+
@io = nil
|
|
48
|
+
end
|
|
49
|
+
self
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
# call-seq:
|
|
54
|
+
# flush
|
|
55
|
+
#
|
|
56
|
+
# Call +flush+ to force an appender to write out any buffered log events.
|
|
57
|
+
# Similar to IO#flush, so use in a similar fashion.
|
|
58
|
+
#
|
|
59
|
+
def flush
|
|
60
|
+
return self if @io.nil?
|
|
61
|
+
@io.flush
|
|
62
|
+
self
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
#
|
|
68
|
+
# call-seq:
|
|
69
|
+
# write( str )
|
|
70
|
+
#
|
|
71
|
+
# Writes the given string to the IO stream. If an +IOError+ is detected,
|
|
72
|
+
# than this appender will be closed and the error reported.
|
|
73
|
+
#
|
|
74
|
+
def write( str )
|
|
75
|
+
begin
|
|
76
|
+
@io.print str
|
|
77
|
+
rescue IOError
|
|
78
|
+
close false
|
|
79
|
+
raise
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end # class IO
|
|
84
|
+
end # module Appenders
|
|
85
|
+
end # module Logging
|
|
86
|
+
|
|
87
|
+
# EOF
|