~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/activesupport/lib/active_support/buffered_logger.rb

  • Committer: Richard Lee (Canonical)
  • Date: 2010-10-15 15:17:58 UTC
  • mfrom: (190.1.3 use-case-mapper)
  • Revision ID: richard.lee@canonical.com-20101015151758-wcvmfxrexsongf9d
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
    ##
17
 
    # :singleton-method:
18
 
    # Set to false to disable the silencer
19
 
    cattr_accessor :silencer
20
 
    self.silencer = true
21
 
 
22
 
    # Silences the logger for the duration of the block.
23
 
    def silence(temporary_level = ERROR)
24
 
      if silencer
25
 
        begin
26
 
          old_logger_level, self.level = level, temporary_level
27
 
          yield self
28
 
        ensure
29
 
          self.level = old_logger_level
30
 
        end
31
 
      else
32
 
        yield self
33
 
      end
34
 
    end
35
 
 
36
 
    attr_accessor :level
37
 
    attr_reader :auto_flushing
38
 
 
39
 
    def initialize(log, level = DEBUG)
40
 
      @level         = level
41
 
      @buffer        = {}
42
 
      @auto_flushing = 1
43
 
      @guard = Mutex.new
44
 
 
45
 
      if log.respond_to?(:write)
46
 
        @log = log
47
 
      elsif File.exist?(log)
48
 
        @log = open(log, (File::WRONLY | File::APPEND))
49
 
        @log.sync = true
50
 
      else
51
 
        FileUtils.mkdir_p(File.dirname(log))
52
 
        @log = open(log, (File::WRONLY | File::APPEND | File::CREAT))
53
 
        @log.sync = true
54
 
        @log.write("# Logfile created on %s" % [Time.now.to_s])
55
 
      end
56
 
    end
57
 
 
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
64
 
      buffer << message
65
 
      auto_flush
66
 
      message
67
 
    end
68
 
 
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)
73
 
        end                                                              # end
74
 
                                                                         #
75
 
        def #{severity.downcase}?                                        # def debug?
76
 
          #{severity} >= @level                                          #   DEBUG >= @level
77
 
        end                                                              # end
78
 
      EOT
79
 
    end
80
 
 
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)
86
 
      @auto_flushing =
87
 
        case period
88
 
        when true;                1
89
 
        when false, nil, 0;       MAX_BUFFER_SIZE
90
 
        when Integer;             period
91
 
        else raise ArgumentError, "Unrecognized auto_flushing period: #{period.inspect}"
92
 
        end
93
 
    end
94
 
 
95
 
    def flush
96
 
      @guard.synchronize do
97
 
        unless buffer.empty?
98
 
          old_buffer = buffer
99
 
          @log.write(old_buffer.join)
100
 
        end
101
 
 
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.
104
 
        clear_buffer
105
 
      end
106
 
    end
107
 
 
108
 
    def close
109
 
      flush
110
 
      @log.close if @log.respond_to?(:close)
111
 
      @log = nil
112
 
    end
113
 
 
114
 
    protected
115
 
      def auto_flush
116
 
        flush if buffer.size >= @auto_flushing
117
 
      end
118
 
 
119
 
      def buffer
120
 
        @buffer[Thread.current] ||= []
121
 
      end
122
 
 
123
 
      def clear_buffer
124
 
        @buffer.delete(Thread.current)
125
 
      end
126
 
  end
127
 
end