2
# Inspired by the buffered logger idea by Ezra
14
MAX_BUFFER_SIZE = 1000
18
# Set to false to disable the silencer
19
cattr_accessor :silencer
22
# Silences the logger for the duration of the block.
23
def silence(temporary_level = ERROR)
26
old_logger_level, self.level = level, temporary_level
29
self.level = old_logger_level
37
attr_reader :auto_flushing
39
def initialize(log, level = DEBUG)
45
if log.respond_to?(:write)
47
elsif File.exist?(log)
48
@log = open(log, (File::WRONLY | File::APPEND))
51
FileUtils.mkdir_p(File.dirname(log))
52
@log = open(log, (File::WRONLY | File::APPEND | File::CREAT))
54
@log.write("# Logfile created on %s" % [Time.now.to_s])
58
def add(severity, message = nil, progname = nil, &block)
59
return if @level > severity
60
message = (message || (block && block.call) || progname).to_s
61
# If a newline is necessary then create a new message ending with a newline.
62
# Ensures that the original message is not mutated.
63
message = "#{message}\n" unless message[-1] == ?\n
69
for severity in Severity.constants
70
class_eval <<-EOT, __FILE__, __LINE__
71
def #{severity.downcase}(message = nil, progname = nil, &block) # def debug(message = nil, progname = nil, &block)
72
add(#{severity}, message, progname, &block) # add(DEBUG, message, progname, &block)
75
def #{severity.downcase}? # def debug?
76
#{severity} >= @level # DEBUG >= @level
81
# Set the auto-flush period. Set to true to flush after every log message,
82
# to an integer to flush every N messages, or to false, nil, or zero to
83
# never auto-flush. If you turn auto-flushing off, be sure to regularly
84
# flush the log yourself -- it will eat up memory until you do.
85
def auto_flushing=(period)
89
when false, nil, 0; MAX_BUFFER_SIZE
91
else raise ArgumentError, "Unrecognized auto_flushing period: #{period.inspect}"
99
@log.write(old_buffer.join)
102
# Important to do this even if buffer was empty or else @buffer will
103
# accumulate empty arrays for each request where nothing was logged.
110
@log.close if @log.respond_to?(:close)
116
flush if buffer.size >= @auto_flushing
120
@buffer[Thread.current] ||= []
124
@buffer.delete(Thread.current)