Froze rails gems
[depot.git] / vendor / rails / activesupport / lib / active_support / buffered_logger.rb
1 module ActiveSupport
2 # Inspired by the buffered logger idea by Ezra
3 class BufferedLogger
4 module Severity
5 DEBUG = 0
6 INFO = 1
7 WARN = 2
8 ERROR = 3
9 FATAL = 4
10 UNKNOWN = 5
11 end
12 include Severity
13
14 MAX_BUFFER_SIZE = 1000
15
16 # Set to false to disable the silencer
17 cattr_accessor :silencer
18 self.silencer = true
19
20 # Silences the logger for the duration of the block.
21 def silence(temporary_level = ERROR)
22 if silencer
23 begin
24 old_logger_level, self.level = level, temporary_level
25 yield self
26 ensure
27 self.level = old_logger_level
28 end
29 else
30 yield self
31 end
32 end
33
34 attr_accessor :level
35 attr_reader :auto_flushing
36
37 def initialize(log, level = DEBUG)
38 @level = level
39 @buffer = {}
40 @auto_flushing = 1
41 @guard = Mutex.new
42
43 if log.respond_to?(:write)
44 @log = log
45 elsif File.exist?(log)
46 @log = open(log, (File::WRONLY | File::APPEND))
47 @log.sync = true
48 else
49 FileUtils.mkdir_p(File.dirname(log))
50 @log = open(log, (File::WRONLY | File::APPEND | File::CREAT))
51 @log.sync = true
52 @log.write("# Logfile created on %s" % [Time.now.to_s])
53 end
54 end
55
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
62 buffer << message
63 auto_flush
64 message
65 end
66
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)
71 end
72
73 def #{severity.downcase}?
74 #{severity} >= @level
75 end
76 EOT
77 end
78
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)
84 @auto_flushing =
85 case period
86 when true; 1
87 when false, nil, 0; MAX_BUFFER_SIZE
88 when Integer; period
89 else raise ArgumentError, "Unrecognized auto_flushing period: #{period.inspect}"
90 end
91 end
92
93 def flush
94 @guard.synchronize do
95 unless buffer.empty?
96 old_buffer = buffer
97 clear_buffer
98 @log.write(old_buffer.join)
99 end
100 end
101 end
102
103 def close
104 flush
105 @log.close if @log.respond_to?(:close)
106 @log = nil
107 end
108
109 protected
110 def auto_flush
111 flush if buffer.size >= @auto_flushing
112 end
113
114 def buffer
115 @buffer[Thread.current] ||= []
116 end
117
118 def clear_buffer
119 @buffer.delete(Thread.current)
120 end
121 end
122 end