2 # Inspired by the buffered logger idea by Ezra
14 MAX_BUFFER_SIZE
= 1000
16 # Set to false to disable the silencer
17 cattr_accessor
:silencer
20 # Silences the logger for the duration of the block.
21 def silence(temporary_level
= ERROR
)
24 old_logger_level
, self.level
= level
, temporary_level
27 self.level
= old_logger_level
35 attr_reader
:auto_flushing
37 def initialize(log
, level
= DEBUG
)
43 if log
.respond_to
?(:write)
45 elsif File
.exist
?(log
)
46 @log = open(log
, (File
::WRONLY | File
::APPEND))
49 FileUtils
.mkdir_p(File
.dirname(log
))
50 @log = open(log
, (File
::WRONLY | File
::APPEND | File
::CREAT))
52 @log.write("# Logfile created on %s" % [Time
.now
.to_s
])
56 def add(severity
, message
= nil, progname
= nil, &block
)
57 return if @level > severity
58 message
= (message
|| (block
&& block
.call
) || progname
).to_s
59 # If a newline is necessary then create a new message ending with a newline.
60 # Ensures that the original message is not mutated.
61 message
= "#{message}\n" unless message
[-1] == ?\n
67 for severity
in Severity
.constants
68 class_eval
<<-EOT, __FILE__, __LINE__
69 def #{severity.downcase}(message = nil, progname = nil, &block)
70 add(#{severity}, message, progname, &block)
73 def #{severity.downcase}?
79 # Set the auto-flush period. Set to true to flush after every log message,
80 # to an integer to flush every N messages, or to false, nil, or zero to
81 # never auto-flush. If you turn auto-flushing off, be sure to regularly
82 # flush the log yourself -- it will eat up memory until you do.
83 def auto_flushing
=(period
)
87 when false, nil, 0; MAX_BUFFER_SIZE
89 else raise ArgumentError
, "Unrecognized auto_flushing period: #{period.inspect}"
98 @log.write(old_buffer
.join
)
105 @log.close
if @log.respond_to
?(:close)
111 flush
if buffer
.size
>= @auto_flushing
115 @buffer[Thread
.current
] ||= []
119 @buffer.delete(Thread
.current
)