logging 1.5.2 → 1.6.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 +7 -0
- data/lib/logging/appenders/buffering.rb +229 -8
- data/lib/logging/appenders/file.rb +1 -1
- data/lib/logging/appenders/io.rb +12 -2
- data/lib/logging/appenders/rolling_file.rb +1 -1
- data/lib/logging/appenders/string_io.rb +19 -1
- data/lib/logging/appenders/syslog.rb +1 -1
- data/lib/logging/logger.rb +6 -0
- data/lib/rspec/logging_helper.rb +39 -0
- data/lib/spec/logging_helper.rb +7 -31
- data/test/appenders/test_buffered_io.rb +3 -0
- data/test/appenders/test_periodic_flushing.rb +140 -0
- data/test/appenders/test_string_io.rb +36 -0
- data/version.txt +1 -1
- metadata +71 -106
data/History.txt
CHANGED
@@ -26,6 +26,47 @@ module Logging::Appenders
|
|
26
26
|
#
|
27
27
|
attr_reader :auto_flushing
|
28
28
|
|
29
|
+
# When set, the buffer will be flushed at regular intervals defined by the
|
30
|
+
# flush_period.
|
31
|
+
#
|
32
|
+
attr_reader :flush_period
|
33
|
+
|
34
|
+
# Setup the message buffer and other variables for automatically and
|
35
|
+
# periodically flushing the buffer.
|
36
|
+
#
|
37
|
+
def initialize( *args, &block )
|
38
|
+
@buffer = []
|
39
|
+
@immediate = []
|
40
|
+
@auto_flushing = 1
|
41
|
+
@flush_period = @periodic_flusher = nil
|
42
|
+
|
43
|
+
super(*args, &block)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Close the message buffer by flusing all log events to the appender. If a
|
47
|
+
# periodic flusher thread is running, shut it down and allow it to exit.
|
48
|
+
#
|
49
|
+
def close( *args )
|
50
|
+
flush
|
51
|
+
|
52
|
+
if @periodic_flusher
|
53
|
+
@periodic_flusher.stop
|
54
|
+
@periodic_flusher = nil
|
55
|
+
Thread.pass
|
56
|
+
end
|
57
|
+
|
58
|
+
super(*args)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Reopen the connection to the underlying logging destination. In addtion
|
62
|
+
# if the appender is configured for periodic flushing, then the flushing
|
63
|
+
# thread will be stopped and restarted.
|
64
|
+
#
|
65
|
+
def reopen
|
66
|
+
_setup_periodic_flusher
|
67
|
+
super
|
68
|
+
end
|
69
|
+
|
29
70
|
# Call +flush+ to force an appender to write out any buffered log events.
|
30
71
|
# Similar to IO#flush, so use in a similar fashion.
|
31
72
|
#
|
@@ -42,7 +83,7 @@ module Logging::Appenders
|
|
42
83
|
self
|
43
84
|
end
|
44
85
|
|
45
|
-
# Configure the levels that will trigger
|
86
|
+
# Configure the levels that will trigger an immediate flush of the
|
46
87
|
# logging buffer. When a log event of the given level is seen, the
|
47
88
|
# buffer will be flushed immediately. Only the levels explicitly given
|
48
89
|
# in this assignment will flush the buffer; if an "error" message is
|
@@ -59,7 +100,6 @@ module Logging::Appenders
|
|
59
100
|
# immediate_at = "warn, error"
|
60
101
|
#
|
61
102
|
def immediate_at=( level )
|
62
|
-
@immediate ||= []
|
63
103
|
@immediate.clear
|
64
104
|
|
65
105
|
# get the immediate levels -- no buffering occurs at these levels, and
|
@@ -77,8 +117,8 @@ module Logging::Appenders
|
|
77
117
|
end
|
78
118
|
end
|
79
119
|
|
80
|
-
# Configure the auto-flushing
|
81
|
-
# contents of the logging buffer to the logging destination
|
120
|
+
# Configure the auto-flushing threshold. Auto-flushing is used to flush
|
121
|
+
# the contents of the logging buffer to the logging destination
|
82
122
|
# automatically when the buffer reaches a certain threshold.
|
83
123
|
#
|
84
124
|
# By default, the auto-flushing will be configured to flush after each
|
@@ -109,12 +149,50 @@ module Logging::Appenders
|
|
109
149
|
"unrecognized auto_flushing period: #{period.inspect}"
|
110
150
|
end
|
111
151
|
|
112
|
-
if @auto_flushing
|
152
|
+
if @auto_flushing <= 0
|
113
153
|
raise ArgumentError,
|
114
|
-
"auto_flushing period
|
154
|
+
"auto_flushing period must be greater than zero: #{period.inspect}"
|
115
155
|
end
|
156
|
+
|
157
|
+
@auto_flushing = DEFAULT_BUFFER_SIZE if @flush_period and @auto_flushing <= 1
|
116
158
|
end
|
117
159
|
|
160
|
+
# Configure periodic flushing of the message buffer. Periodic flushing is
|
161
|
+
# used to flush the contents of the logging buffer at some regular
|
162
|
+
# interval. Periodic flushing is disabled by default.
|
163
|
+
#
|
164
|
+
# When enabling periodic flushing the flush period should be set using one
|
165
|
+
# of the following formats: "HH:MM:SS" or seconds as an numeric or string.
|
166
|
+
#
|
167
|
+
# "01:00:00" : every hour
|
168
|
+
# "00:05:00" : every 5 minutes
|
169
|
+
# "00:00:30" : every 30 seconds
|
170
|
+
# 60 : every 60 seconds (1 minute)
|
171
|
+
# "120" : every 120 seconds (2 minutes)
|
172
|
+
#
|
173
|
+
# For the periodic flusher to work properly, the auto-flushing threshold
|
174
|
+
# will be set to the default value of 500. The auto-flushing threshold can
|
175
|
+
# be changed, but it must be greater than 1.
|
176
|
+
#
|
177
|
+
# To disable the periodic flusher simply set the flush period to +nil+.
|
178
|
+
# The auto-flushing threshold will not be changed; it must be disabled
|
179
|
+
# manually if so desired.
|
180
|
+
#
|
181
|
+
def flush_period=( period )
|
182
|
+
period =
|
183
|
+
case period
|
184
|
+
when Integer, Float, nil; period
|
185
|
+
when String;
|
186
|
+
num = _parse_hours_minutes_seconds(period) || _parse_numeric(period)
|
187
|
+
num = ArgumentError.new("unrecognized flush period: #{period.inspect}") if num.nil?
|
188
|
+
num
|
189
|
+
else ArgumentError.new("unrecognized flush period: #{period.inspect}") end
|
190
|
+
|
191
|
+
raise period if Exception === period
|
192
|
+
@flush_period = period
|
193
|
+
|
194
|
+
_setup_periodic_flusher
|
195
|
+
end
|
118
196
|
|
119
197
|
protected
|
120
198
|
|
@@ -127,9 +205,9 @@ module Logging::Appenders
|
|
127
205
|
def configure_buffering( opts )
|
128
206
|
::Logging.init unless ::Logging.const_defined? :MAX_LEVEL_LENGTH
|
129
207
|
|
130
|
-
@buffer = []
|
131
208
|
self.immediate_at = opts.getopt(:immediate_at, '')
|
132
209
|
self.auto_flushing = opts.getopt(:auto_flushing, true)
|
210
|
+
self.flush_period = opts.getopt(:flush_period, nil)
|
133
211
|
end
|
134
212
|
|
135
213
|
# Returns true if the _event_ level matches one of the configured
|
@@ -151,7 +229,7 @@ module Logging::Appenders
|
|
151
229
|
# formatted using the layout given to the appender when it was created.
|
152
230
|
#
|
153
231
|
# The _event_ will be formatted and then buffered until the
|
154
|
-
# "auto_flushing" level has been reached. At
|
232
|
+
# "auto_flushing" level has been reached. At this time the canonical_write
|
155
233
|
# method will be used to log all events stored in the buffer.
|
156
234
|
#
|
157
235
|
def write( event )
|
@@ -163,12 +241,155 @@ module Logging::Appenders
|
|
163
241
|
canonical_write(str)
|
164
242
|
else
|
165
243
|
sync { @buffer << str }
|
244
|
+
@periodic_flusher.signal if @periodic_flusher
|
166
245
|
flush if @buffer.length >= @auto_flushing || immediate?(event)
|
167
246
|
end
|
168
247
|
|
169
248
|
self
|
170
249
|
end
|
171
250
|
|
251
|
+
# Attempt to parse an hours/minutes/seconds value from the string and return
|
252
|
+
# an integer number of seconds.
|
253
|
+
#
|
254
|
+
# _parse_hours_minutes_seconds("14:12:42") #=> 51162
|
255
|
+
# _parse_hours_minutes_seconds("foo") #=> nil
|
256
|
+
#
|
257
|
+
def _parse_hours_minutes_seconds( str )
|
258
|
+
m = %r/^\s*(\d{2,}):(\d{2}):(\d{2}(?:\.\d+)?)\s*$/.match(str)
|
259
|
+
return if m.nil?
|
260
|
+
|
261
|
+
(3600 * m[1].to_i) + (60 * m[2].to_i) + (m[3].to_f)
|
262
|
+
end
|
263
|
+
|
264
|
+
# Convert the string into a numeric value. If the string does not
|
265
|
+
# represent a valid Integer or Float then +nil+ is returned.
|
266
|
+
#
|
267
|
+
# _parse_numeric("10") #=> 10
|
268
|
+
# _parse_numeric("1.0") #=> 1.0
|
269
|
+
# _parse_numeric("foo") #=> nil
|
270
|
+
#
|
271
|
+
def _parse_numeric( str )
|
272
|
+
Integer(str) rescue (Float(str) rescue nil)
|
273
|
+
end
|
274
|
+
|
275
|
+
# Using the flush_period, create a new PeriodicFlusher attached to this
|
276
|
+
# appender. If the flush_period is nil, then no action will be taken. If a
|
277
|
+
# PeriodicFlusher alreayd exists, it will be stopped and a new one will be
|
278
|
+
# created.
|
279
|
+
#
|
280
|
+
def _setup_periodic_flusher
|
281
|
+
# stop and remove any existing periodic flusher instance
|
282
|
+
if @periodic_flusher
|
283
|
+
@periodic_flusher.stop
|
284
|
+
@periodic_flusher = nil
|
285
|
+
Thread.pass
|
286
|
+
end
|
287
|
+
|
288
|
+
# create a new periodic flusher if we have a valid flush period
|
289
|
+
if @flush_period
|
290
|
+
@auto_flushing = DEFAULT_BUFFER_SIZE unless @auto_flushing > 1
|
291
|
+
@periodic_flusher = PeriodicFlusher.new(self, @flush_period)
|
292
|
+
@periodic_flusher.start
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
# :stopdoc:
|
297
|
+
|
298
|
+
# The PeriodicFlusher contains an internal run loop that will periodically
|
299
|
+
# wake up and flush any log events contained in the message buffer of the
|
300
|
+
# owning appender instance. The PeriodicFlusher relies on a _signal_ from
|
301
|
+
# the appender in order to wakeup and perform the flush on the appender.
|
302
|
+
#
|
303
|
+
class PeriodicFlusher
|
304
|
+
|
305
|
+
# Create a new PeriodicFlusher instance that will call the +flush+
|
306
|
+
# method on the given _appender_. The +flush+ method will be called
|
307
|
+
# every _period_ seconds, but only when the message buffer is non-empty.
|
308
|
+
#
|
309
|
+
def initialize( appender, period )
|
310
|
+
@appender = appender
|
311
|
+
@period = period
|
312
|
+
|
313
|
+
@mutex = Mutex.new
|
314
|
+
@cv = ConditionVariable.new
|
315
|
+
@thread = nil
|
316
|
+
@waiting = nil
|
317
|
+
@signaled = false
|
318
|
+
end
|
319
|
+
|
320
|
+
# Start the periodic flusher's internal run loop.
|
321
|
+
#
|
322
|
+
def start
|
323
|
+
return if @thread
|
324
|
+
|
325
|
+
@thread = Thread.new { loop {
|
326
|
+
begin
|
327
|
+
break if Thread.current[:stop]
|
328
|
+
_wait_for_signal
|
329
|
+
sleep @period unless Thread.current[:stop]
|
330
|
+
@appender.flush
|
331
|
+
rescue => err
|
332
|
+
::Logging.log_internal {"PeriodicFlusher for appender #{@appender.inspect} encountered an error"}
|
333
|
+
::Logging.log_internal(-2) {err}
|
334
|
+
end
|
335
|
+
}; @thread = nil }
|
336
|
+
|
337
|
+
self
|
338
|
+
end
|
339
|
+
|
340
|
+
# Stop the periodic flusher's internal run loop.
|
341
|
+
#
|
342
|
+
def stop
|
343
|
+
return if @thread.nil?
|
344
|
+
@thread[:stop] = true
|
345
|
+
signal if waiting?
|
346
|
+
self
|
347
|
+
end
|
348
|
+
|
349
|
+
# Signal the periodic flusher. This will wake up the run loop if it is
|
350
|
+
# currently waiting for something to do. If the signal method is never
|
351
|
+
# called, the periodic flusher will never perform the flush action on
|
352
|
+
# the appender.
|
353
|
+
#
|
354
|
+
def signal
|
355
|
+
return if Thread.current == @thread # don't signal ourselves
|
356
|
+
return if @signaled # don't need to signal again
|
357
|
+
|
358
|
+
@mutex.synchronize {
|
359
|
+
@signaled = true
|
360
|
+
@cv.signal
|
361
|
+
}
|
362
|
+
self
|
363
|
+
end
|
364
|
+
|
365
|
+
# Returns +true+ if the flusher is waiting for a signal. Returns +false+
|
366
|
+
# if the flusher is somewhere in the processing loop.
|
367
|
+
#
|
368
|
+
def waiting?
|
369
|
+
@waiting
|
370
|
+
end
|
371
|
+
|
372
|
+
private
|
373
|
+
|
374
|
+
def _wait_for_signal
|
375
|
+
@mutex.synchronize {
|
376
|
+
begin
|
377
|
+
# wait on the condition variable only if we have NOT been signaled
|
378
|
+
unless @signaled
|
379
|
+
@waiting = true
|
380
|
+
@cv.wait(@mutex)
|
381
|
+
@waiting = false
|
382
|
+
end
|
383
|
+
ensure
|
384
|
+
@signaled = false
|
385
|
+
end
|
386
|
+
}
|
387
|
+
ensure
|
388
|
+
@waiting = false
|
389
|
+
end
|
390
|
+
end # class PeriodicFlusher
|
391
|
+
# :startdoc:
|
392
|
+
|
172
393
|
end # module Buffering
|
173
394
|
end # module Logging::Appenders
|
174
395
|
|
data/lib/logging/appenders/io.rb
CHANGED
@@ -7,6 +7,12 @@ module Logging::Appenders
|
|
7
7
|
class IO < ::Logging::Appender
|
8
8
|
include Buffering
|
9
9
|
|
10
|
+
# The method that will be used to close the IO stream. Defaults to :close
|
11
|
+
# but can be :close_read, :close_write or nil. When nil, the IO stream
|
12
|
+
# will not be closed when the appender's close method is called.
|
13
|
+
#
|
14
|
+
attr_accessor :close_method
|
15
|
+
|
10
16
|
# call-seq:
|
11
17
|
# IO.new( name, io )
|
12
18
|
# IO.new( name, io, :layout => layout )
|
@@ -21,9 +27,10 @@ module Logging::Appenders
|
|
21
27
|
|
22
28
|
@io = io
|
23
29
|
@io.sync = true if io.respond_to? :sync= # syswrite complains if the IO stream is buffered
|
30
|
+
@close_method = :close
|
24
31
|
|
25
|
-
configure_buffering(opts)
|
26
32
|
super(name, opts)
|
33
|
+
configure_buffering(opts)
|
27
34
|
end
|
28
35
|
|
29
36
|
# call-seq:
|
@@ -37,8 +44,11 @@ module Logging::Appenders
|
|
37
44
|
def close( *args )
|
38
45
|
return self if @io.nil?
|
39
46
|
super
|
47
|
+
|
40
48
|
io, @io = @io, nil
|
41
|
-
|
49
|
+
unless [STDIN, STDERR, STDOUT].include?(io)
|
50
|
+
io.send(@close_method) if @close_method and io.respond_to? @close_method
|
51
|
+
end
|
42
52
|
rescue IOError => err
|
43
53
|
ensure
|
44
54
|
return self
|
@@ -22,11 +22,29 @@ module Logging::Appenders
|
|
22
22
|
super(name, @sio, opts)
|
23
23
|
end
|
24
24
|
|
25
|
+
# Reopen the underlying StringIO instance. If the instance is currently
|
26
|
+
# closed then it will be opened. If the instance is currently open then it
|
27
|
+
# will be closed and immediately opened.
|
28
|
+
#
|
29
|
+
def reopen
|
30
|
+
@mutex.synchronize {
|
31
|
+
if defined? @io and @io
|
32
|
+
flush
|
33
|
+
@io.close rescue nil
|
34
|
+
end
|
35
|
+
@io = @sio = StringIO.new
|
36
|
+
@sio.extend IoToS
|
37
|
+
@pos = 0
|
38
|
+
}
|
39
|
+
super
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
25
43
|
# Clears the internal StringIO instance. All log messages are removed
|
26
44
|
# from the buffer.
|
27
45
|
#
|
28
46
|
def clear
|
29
|
-
|
47
|
+
@mutex.synchronize {
|
30
48
|
@pos = 0
|
31
49
|
@sio.seek 0
|
32
50
|
@sio.truncate 0
|
data/lib/logging/logger.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
module RSpec
|
3
|
+
module LoggingHelper
|
4
|
+
|
5
|
+
# Capture log messages from the Logging framework and make them
|
6
|
+
# available via a @log_output instance variable. The @log_output
|
7
|
+
# supports a readline method to access the log messags.
|
8
|
+
#
|
9
|
+
def capture_log_messages( opts = {} )
|
10
|
+
from = opts.getopt(:from, 'root')
|
11
|
+
to = opts.getopt(:to, '__rspec__')
|
12
|
+
exclusive = opts.getopt(:exclusive, true)
|
13
|
+
|
14
|
+
appender = Logging::Appenders[to] || Logging::Appenders::StringIo.new(to)
|
15
|
+
logger = Logging::Logger[from]
|
16
|
+
if exclusive
|
17
|
+
logger.appenders = appender
|
18
|
+
else
|
19
|
+
logger.add_appenders(appender)
|
20
|
+
end
|
21
|
+
|
22
|
+
before(:all) do
|
23
|
+
@log_output = Logging::Appenders[to]
|
24
|
+
end
|
25
|
+
|
26
|
+
before(:each) do
|
27
|
+
@log_output.reset
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end # module LoggingHelper
|
32
|
+
end # module RSpec
|
33
|
+
|
34
|
+
if defined? RSpec::Core::Configuration
|
35
|
+
class RSpec::Core::Configuration
|
36
|
+
include RSpec::LoggingHelper
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
data/lib/spec/logging_helper.rb
CHANGED
@@ -1,34 +1,10 @@
|
|
1
1
|
|
2
|
-
|
3
|
-
|
2
|
+
require File.expand_path('../../rspec/logging_helper', __FILE__)
|
3
|
+
Spec::LoggingHelper = RSpec::LoggingHelper
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
from = opts.getopt(:from, 'root')
|
11
|
-
to = opts.getopt(:to, '__rspec__')
|
12
|
-
exclusive = opts.getopt(:exclusive, true)
|
5
|
+
if defined? Spec::Runner::Configuration
|
6
|
+
class Spec::Runner::Configuration
|
7
|
+
include Spec::LoggingHelper
|
8
|
+
end
|
9
|
+
end
|
13
10
|
|
14
|
-
appender = Logging::Appenders[to] || Logging::Appenders::StringIo.new(to)
|
15
|
-
logger = Logging::Logger[from]
|
16
|
-
if exclusive
|
17
|
-
logger.appenders = appender
|
18
|
-
else
|
19
|
-
logger.add_appenders(appender)
|
20
|
-
end
|
21
|
-
|
22
|
-
before(:all) do
|
23
|
-
@log_output = Logging::Appenders[to]
|
24
|
-
end
|
25
|
-
|
26
|
-
before(:each) do
|
27
|
-
@log_output.reset
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
end # module LoggingHelper
|
32
|
-
end # module Spec
|
33
|
-
|
34
|
-
# EOF
|
@@ -0,0 +1,140 @@
|
|
1
|
+
|
2
|
+
require File.expand_path('../setup', File.dirname(__FILE__))
|
3
|
+
|
4
|
+
module TestLogging
|
5
|
+
module TestAppenders
|
6
|
+
|
7
|
+
class TestPeriodicFlushing < Test::Unit::TestCase
|
8
|
+
include LoggingTestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
super
|
12
|
+
@appender = Logging.appenders.string_io(
|
13
|
+
'test_appender', :flush_period => 2
|
14
|
+
)
|
15
|
+
@appender.clear
|
16
|
+
@sio = @appender.sio
|
17
|
+
@levels = Logging::LEVELS
|
18
|
+
begin readline rescue EOFError end
|
19
|
+
Thread.pass # give the flusher thread a moment to start
|
20
|
+
end
|
21
|
+
|
22
|
+
def teardown
|
23
|
+
@appender.close
|
24
|
+
@appender = nil
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_flush_period_set
|
29
|
+
assert_equal 2, @appender.flush_period
|
30
|
+
assert_equal Logging::Appenders::Buffering::DEFAULT_BUFFER_SIZE, @appender.auto_flushing
|
31
|
+
|
32
|
+
@appender.flush_period = '01:30:45'
|
33
|
+
assert_equal 5445, @appender.flush_period
|
34
|
+
|
35
|
+
@appender.flush_period = '245'
|
36
|
+
assert_equal 245, @appender.flush_period
|
37
|
+
|
38
|
+
@appender.auto_flushing = true
|
39
|
+
assert_equal Logging::Appenders::Buffering::DEFAULT_BUFFER_SIZE, @appender.auto_flushing
|
40
|
+
|
41
|
+
@appender.auto_flushing = 200
|
42
|
+
assert_equal 200, @appender.auto_flushing
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_periodic_flusher_running
|
46
|
+
flusher = @appender.instance_variable_get(:@periodic_flusher)
|
47
|
+
|
48
|
+
assert_instance_of Logging::Appenders::Buffering::PeriodicFlusher, flusher
|
49
|
+
assert flusher.waiting?, 'the periodic flusher should be waiting for a signal'
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_append
|
53
|
+
event = Logging::LogEvent.new('TestLogger', @levels['warn'],
|
54
|
+
[1, 2, 3, 4], false)
|
55
|
+
@appender.append event
|
56
|
+
@appender.append event
|
57
|
+
event.level = @levels['debug']
|
58
|
+
event.data = 'the big log message'
|
59
|
+
@appender.append event
|
60
|
+
|
61
|
+
assert_nil(readline)
|
62
|
+
sleep 3
|
63
|
+
|
64
|
+
assert_equal " WARN TestLogger : <Array> #{[1, 2, 3, 4]}\n", readline
|
65
|
+
assert_equal " WARN TestLogger : <Array> #{[1, 2, 3, 4]}\n", readline
|
66
|
+
assert_equal "DEBUG TestLogger : the big log message\n", readline
|
67
|
+
assert_nil(readline)
|
68
|
+
|
69
|
+
@appender.close
|
70
|
+
assert_raise(RuntimeError) {@appender.append event}
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_flush_on_close
|
74
|
+
assert_equal false, @sio.closed?
|
75
|
+
assert_equal false, @appender.closed?
|
76
|
+
|
77
|
+
event = Logging::LogEvent.new('TestLogger', @levels['warn'],
|
78
|
+
[1, 2, 3, 4], false)
|
79
|
+
|
80
|
+
@appender.flush_period = "24:00:00"
|
81
|
+
@appender.append event
|
82
|
+
event.level = @levels['debug']
|
83
|
+
event.data = 'the big log message'
|
84
|
+
@appender.append event
|
85
|
+
|
86
|
+
assert_nil(readline)
|
87
|
+
|
88
|
+
@appender.close_method = :close_write
|
89
|
+
@appender.close
|
90
|
+
assert_equal false, @sio.closed?
|
91
|
+
assert_equal true, @appender.closed?
|
92
|
+
|
93
|
+
assert_equal " WARN TestLogger : <Array> #{[1, 2, 3, 4]}\n", readline
|
94
|
+
assert_equal "DEBUG TestLogger : the big log message\n", readline
|
95
|
+
assert_nil(readline)
|
96
|
+
|
97
|
+
@sio.close
|
98
|
+
assert_equal true, @sio.closed?
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_auto_flushing
|
102
|
+
@appender.auto_flushing = 3
|
103
|
+
|
104
|
+
event = Logging::LogEvent.new('TestLogger', @levels['warn'],
|
105
|
+
[1, 2, 3, 4], false)
|
106
|
+
|
107
|
+
@appender.append event
|
108
|
+
@appender.append event
|
109
|
+
event.level = @levels['debug']
|
110
|
+
event.data = 'the big log message'
|
111
|
+
@appender.append event
|
112
|
+
event.level = @levels['info']
|
113
|
+
event.data = 'just FYI'
|
114
|
+
@appender.append event
|
115
|
+
event.level = @levels['warn']
|
116
|
+
event.data = 'this is your last warning!'
|
117
|
+
@appender.append event
|
118
|
+
|
119
|
+
assert_equal " WARN TestLogger : <Array> #{[1, 2, 3, 4]}\n", readline
|
120
|
+
assert_equal " WARN TestLogger : <Array> #{[1, 2, 3, 4]}\n", readline
|
121
|
+
assert_equal "DEBUG TestLogger : the big log message\n", readline
|
122
|
+
|
123
|
+
assert_nil(readline)
|
124
|
+
sleep 3
|
125
|
+
|
126
|
+
assert_equal " INFO TestLogger : just FYI\n", readline
|
127
|
+
assert_equal " WARN TestLogger : this is your last warning!\n", readline
|
128
|
+
assert_nil(readline)
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
def readline
|
133
|
+
@appender.readline
|
134
|
+
end
|
135
|
+
|
136
|
+
end # class TestPeriodicFlushing
|
137
|
+
|
138
|
+
end # module TestAppenders
|
139
|
+
end # module TestLogging
|
140
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
require File.expand_path('../setup', File.dirname(__FILE__))
|
3
|
+
|
4
|
+
module TestLogging
|
5
|
+
module TestAppenders
|
6
|
+
|
7
|
+
class TestStringIO < Test::Unit::TestCase
|
8
|
+
include LoggingTestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
super
|
12
|
+
|
13
|
+
@appender = Logging.appenders.string_io('test_appender')
|
14
|
+
@sio = @appender.sio
|
15
|
+
@levels = Logging::LEVELS
|
16
|
+
end
|
17
|
+
|
18
|
+
def teardown
|
19
|
+
@appender.close
|
20
|
+
@appender = nil
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_reopen
|
25
|
+
assert_equal @sio.object_id, @appender.sio.object_id
|
26
|
+
|
27
|
+
@appender.reopen
|
28
|
+
assert @sio.closed?, 'StringIO instance is closed'
|
29
|
+
assert_not_equal @sio.object_id, @appender.sio.object_id
|
30
|
+
end
|
31
|
+
|
32
|
+
end # class TestStringIO
|
33
|
+
|
34
|
+
end # module TestAppenders
|
35
|
+
end # module TestLogging
|
36
|
+
|
data/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.6.0
|
metadata
CHANGED
@@ -1,117 +1,86 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: logging
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 5
|
9
|
-
- 2
|
10
|
-
version: 1.5.2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.6.0
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Tim Pease
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-08-22 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
22
15
|
name: little-plugger
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &2161856200 !ruby/object:Gem::Requirement
|
25
17
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 23
|
30
|
-
segments:
|
31
|
-
- 1
|
32
|
-
- 1
|
33
|
-
- 2
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
34
21
|
version: 1.1.2
|
35
22
|
type: :runtime
|
36
|
-
version_requirements: *id001
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: flexmock
|
39
23
|
prerelease: false
|
40
|
-
|
24
|
+
version_requirements: *2161856200
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: flexmock
|
27
|
+
requirement: &2161855660 !ruby/object:Gem::Requirement
|
41
28
|
none: false
|
42
|
-
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
|
46
|
-
segments:
|
47
|
-
- 0
|
48
|
-
- 8
|
49
|
-
- 11
|
50
|
-
version: 0.8.11
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.9.0
|
51
33
|
type: :development
|
52
|
-
version_requirements: *id002
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: bones-git
|
55
34
|
prerelease: false
|
56
|
-
|
35
|
+
version_requirements: *2161855660
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: bones-git
|
38
|
+
requirement: &2161855040 !ruby/object:Gem::Requirement
|
57
39
|
none: false
|
58
|
-
requirements:
|
59
|
-
- -
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
hash: 23
|
62
|
-
segments:
|
63
|
-
- 1
|
64
|
-
- 2
|
65
|
-
- 4
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
66
43
|
version: 1.2.4
|
67
44
|
type: :development
|
68
|
-
version_requirements: *id003
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: bones-rcov
|
71
45
|
prerelease: false
|
72
|
-
|
46
|
+
version_requirements: *2161855040
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: bones-rcov
|
49
|
+
requirement: &2161854480 !ruby/object:Gem::Requirement
|
73
50
|
none: false
|
74
|
-
requirements:
|
75
|
-
- -
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
hash: 21
|
78
|
-
segments:
|
79
|
-
- 1
|
80
|
-
- 0
|
81
|
-
- 1
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
82
54
|
version: 1.0.1
|
83
55
|
type: :development
|
84
|
-
version_requirements: *id004
|
85
|
-
- !ruby/object:Gem::Dependency
|
86
|
-
name: bones
|
87
56
|
prerelease: false
|
88
|
-
|
57
|
+
version_requirements: *2161854480
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: bones
|
60
|
+
requirement: &2161853900 !ruby/object:Gem::Requirement
|
89
61
|
none: false
|
90
|
-
requirements:
|
91
|
-
- -
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
hash: 27
|
94
|
-
segments:
|
95
|
-
- 3
|
96
|
-
- 7
|
97
|
-
- 0
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
98
65
|
version: 3.7.0
|
99
66
|
type: :development
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2161853900
|
69
|
+
description: ! 'Logging is a flexible logging library for use in Ruby programs based
|
70
|
+
on the
|
71
|
+
|
72
|
+
design of Java''s log4j library. It features a hierarchical logging system,
|
73
|
+
|
104
74
|
custom level names, multiple output destinations per log event, custom
|
105
|
-
|
75
|
+
|
76
|
+
formatting, and more.'
|
106
77
|
email: tim.pease@gmail.com
|
107
78
|
executables: []
|
108
|
-
|
109
79
|
extensions: []
|
110
|
-
|
111
|
-
extra_rdoc_files:
|
80
|
+
extra_rdoc_files:
|
112
81
|
- History.txt
|
113
82
|
- README.rdoc
|
114
|
-
files:
|
83
|
+
files:
|
115
84
|
- History.txt
|
116
85
|
- README.rdoc
|
117
86
|
- Rakefile
|
@@ -158,6 +127,7 @@ files:
|
|
158
127
|
- lib/logging/root_logger.rb
|
159
128
|
- lib/logging/stats.rb
|
160
129
|
- lib/logging/utils.rb
|
130
|
+
- lib/rspec/logging_helper.rb
|
161
131
|
- lib/spec/logging_helper.rb
|
162
132
|
- test/appenders/test_buffered_io.rb
|
163
133
|
- test/appenders/test_console.rb
|
@@ -165,7 +135,9 @@ files:
|
|
165
135
|
- test/appenders/test_file.rb
|
166
136
|
- test/appenders/test_growl.rb
|
167
137
|
- test/appenders/test_io.rb
|
138
|
+
- test/appenders/test_periodic_flushing.rb
|
168
139
|
- test/appenders/test_rolling_file.rb
|
140
|
+
- test/appenders/test_string_io.rb
|
169
141
|
- test/appenders/test_syslog.rb
|
170
142
|
- test/benchmark.rb
|
171
143
|
- test/config/test_configurator.rb
|
@@ -189,49 +161,42 @@ files:
|
|
189
161
|
- test/test_stats.rb
|
190
162
|
- test/test_utils.rb
|
191
163
|
- version.txt
|
192
|
-
has_rdoc: true
|
193
164
|
homepage: http://rubygems.org/gems/logging
|
194
165
|
licenses: []
|
195
|
-
|
196
166
|
post_install_message:
|
197
|
-
rdoc_options:
|
167
|
+
rdoc_options:
|
198
168
|
- --main
|
199
169
|
- README.rdoc
|
200
|
-
require_paths:
|
170
|
+
require_paths:
|
201
171
|
- lib
|
202
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
172
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
203
173
|
none: false
|
204
|
-
requirements:
|
205
|
-
- -
|
206
|
-
- !ruby/object:Gem::Version
|
207
|
-
|
208
|
-
|
209
|
-
- 0
|
210
|
-
version: "0"
|
211
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ! '>='
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
212
179
|
none: false
|
213
|
-
requirements:
|
214
|
-
- -
|
215
|
-
- !ruby/object:Gem::Version
|
216
|
-
|
217
|
-
segments:
|
218
|
-
- 0
|
219
|
-
version: "0"
|
180
|
+
requirements:
|
181
|
+
- - ! '>='
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '0'
|
220
184
|
requirements: []
|
221
|
-
|
222
185
|
rubyforge_project: logging
|
223
|
-
rubygems_version: 1.
|
186
|
+
rubygems_version: 1.8.6
|
224
187
|
signing_key:
|
225
188
|
specification_version: 3
|
226
189
|
summary: A flexible and extendable logging library for Ruby
|
227
|
-
test_files:
|
190
|
+
test_files:
|
228
191
|
- test/appenders/test_buffered_io.rb
|
229
192
|
- test/appenders/test_console.rb
|
230
193
|
- test/appenders/test_email.rb
|
231
194
|
- test/appenders/test_file.rb
|
232
195
|
- test/appenders/test_growl.rb
|
233
196
|
- test/appenders/test_io.rb
|
197
|
+
- test/appenders/test_periodic_flushing.rb
|
234
198
|
- test/appenders/test_rolling_file.rb
|
199
|
+
- test/appenders/test_string_io.rb
|
235
200
|
- test/appenders/test_syslog.rb
|
236
201
|
- test/config/test_configurator.rb
|
237
202
|
- test/config/test_yaml_configurator.rb
|