Logging::Appenders::Buffering

The Buffering module is used to implement buffering of the log messages in a given appender. The size of the buffer can be specified, and the buffer can be configured to auto-flush at a given threshold. The threshold can be a single message or a very large number of messages.

Log messages of a certain level can cause the buffer to be flushed immediately. If an error occurs, all previous messages and the error message will be written immediately to the logging destination if the buffer is configured to do so.

Constants

DEFAULT_BUFFER_SIZE

Default buffer size

Attributes

buffer[R]

The buffer holding the log messages

auto_flushing[R]

The auto-flushing setting. When the buffer reaches this size, all messages will be be flushed automatically.

flush_period[R]

When set, the buffer will be flushed at regular intervals defined by the flush_period.

Public Class Methods

new( *args, &block ) click to toggle source

Setup the message buffer and other variables for automatically and periodically flushing the buffer.

    # File lib/logging/appenders/buffering.rb, line 37
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

Public Instance Methods

auto_flushing=( period ) click to toggle source

Configure the auto-flushing threshold. Auto-flushing is used to flush the contents of the logging buffer to the logging destination automatically when the buffer reaches a certain threshold.

By default, the auto-flushing will be configured to flush after each log message.

The allowed settings are as follows:

  N      : flush after every N messages (N is an integer)
  true   : flush after each log message
  false  OR
  nil    OR
  0      : only flush when the buffer is full (500 messages)

If the default buffer size of 500 is too small, then you can manually configure it to be as large as you want. This will consume more memory.

  auto_flushing = 42_000
     # File lib/logging/appenders/buffering.rb, line 140
140:     def auto_flushing=( period )
141:       @auto_flushing =
142:         case period
143:         when true;             1
144:         when false, nil, 0;    DEFAULT_BUFFER_SIZE
145:         when Integer;          period
146:         when String;           Integer(period)
147:         else
148:           raise ArgumentError,
149:                 "unrecognized auto_flushing period: #{period.inspect}"
150:         end
151: 
152:       if @auto_flushing <= 0
153:         raise ArgumentError,
154:           "auto_flushing period must be greater than zero: #{period.inspect}"
155:       end
156: 
157:       @auto_flushing = DEFAULT_BUFFER_SIZE if @flush_period and @auto_flushing <= 1
158:     end
close( *args ) click to toggle source

Close the message buffer by flushing all log events to the appender. If a periodic flusher thread is running, shut it down and allow it to exit.

    # File lib/logging/appenders/buffering.rb, line 49
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
flush() click to toggle source

Call flush to force an appender to write out any buffered log events. Similar to IO#flush, so use in a similar fashion.

    # File lib/logging/appenders/buffering.rb, line 73
73:     def flush
74:       return self if @buffer.empty?
75: 
76:       str = nil
77:       sync {
78:         str = @buffer.join
79:         @buffer.clear
80:       }
81: 
82:       canonical_write str unless str.empty?
83:       self
84:     end
flush_period=( period ) click to toggle source

Configure periodic flushing of the message buffer. Periodic flushing is used to flush the contents of the logging buffer at some regular interval. Periodic flushing is disabled by default.

When enabling periodic flushing the flush period should be set using one of the following formats: “HH:MM:SS” or seconds as an numeric or string.

  "01:00:00"  : every hour
  "00:05:00"  : every 5 minutes
  "00:00:30"  : every 30 seconds
  60          : every 60 seconds (1 minute)
  "120"       : every 120 seconds (2 minutes)

For the periodic flusher to work properly, the auto-flushing threshold will be set to the default value of 500. The auto-flushing threshold can be changed, but it must be greater than 1.

To disable the periodic flusher simply set the flush period to nil. The auto-flushing threshold will not be changed; it must be disabled manually if so desired.

     # File lib/logging/appenders/buffering.rb, line 181
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
immediate_at=( level ) click to toggle source

Configure the levels that will trigger an immediate flush of the logging buffer. When a log event of the given level is seen, the buffer will be flushed immediately. Only the levels explicitly given in this assignment will flush the buffer; if an “error” message is configured to immediately flush the buffer, a “fatal” message will not even though it is a higher level. Both must be explicitly passed to this assignment.

You can pass in a single level name or number, an array of level names or numbers, or a string containing a comma separated list of level names or numbers.

  immediate_at = :error
  immediate_at = [:error, :fatal]
  immediate_at = "warn, error"
     # File lib/logging/appenders/buffering.rb, line 102
102:     def immediate_at=( level )
103:       @immediate.clear
104: 
105:       # get the immediate levels -- no buffering occurs at these levels, and
106:       # a log message is written to the logging destination immediately
107:       immediate_at =
108:         case level
109:         when String; level.split(',').map {|x| x.strip}
110:         when Array; level
111:         else Array(level) end
112: 
113:       immediate_at.each do |lvl|
114:         num = ::Logging.level_num(lvl)
115:         next if num.nil?
116:         @immediate[num] = true
117:       end
118:     end
reopen() click to toggle source

Reopen the connection to the underlying logging destination. In addition if the appender is configured for periodic flushing, then the flushing thread will be stopped and restarted.

    # File lib/logging/appenders/buffering.rb, line 65
65:     def reopen
66:       _setup_periodic_flusher
67:       super
68:     end

Protected Instance Methods

configure_buffering( opts ) click to toggle source

Configure the buffering using the arguments found in the give options hash. This method must be called in order to use the message buffer. The supported options are “immediate_at“ and “auto_flushing“. Please refer to the documentation for those methods to see the allowed options.

     # File lib/logging/appenders/buffering.rb, line 205
205:     def configure_buffering( opts )
206:       ::Logging.init unless ::Logging.initialized?
207: 
208:       self.immediate_at = opts.getopt(:immediate_at, '')
209:       self.auto_flushing = opts.getopt(:auto_flushing, true)
210:       self.flush_period = opts.getopt(:flush_period, nil)
211:     end
immediate?( event ) click to toggle source

Returns true if the event level matches one of the configured immediate logging levels. Otherwise returns false.

     # File lib/logging/appenders/buffering.rb, line 216
216:     def immediate?( event )
217:       return false unless event.respond_to? :level
218:       @immediate[event.level]
219:     end

Private Instance Methods

_parse_hours_minutes_seconds( str ) click to toggle source

Attempt to parse an hours/minutes/seconds value from the string and return an integer number of seconds.

  _parse_hours_minutes_seconds("14:12:42")  #=> 51162
  _parse_hours_minutes_seconds("foo")       #=> nil
     # File lib/logging/appenders/buffering.rb, line 257
257:     def _parse_hours_minutes_seconds( str )
258:       m = /^\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
_parse_numeric( str ) click to toggle source

Convert the string into a numeric value. If the string does not represent a valid Integer or Float then nil is returned.

  _parse_numeric("10")   #=> 10
  _parse_numeric("1.0")  #=> 1.0
  _parse_numeric("foo")  #=> nil
     # File lib/logging/appenders/buffering.rb, line 271
271:     def _parse_numeric( str )
272:       Integer(str) rescue (Float(str) rescue nil)
273:     end
_setup_periodic_flusher() click to toggle source

Using the flush_period, create a new PeriodicFlusher attached to this appender. If the flush_period is nil, then no action will be taken. If a PeriodicFlusher already exists, it will be stopped and a new one will be created.

     # File lib/logging/appenders/buffering.rb, line 280
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
write( event ) click to toggle source

Writes the given event to the logging destination. The event can be either a LogEvent or a String. If a LogEvent, then it will be formatted using the layout given to the appender when it was created.

The event will be formatted and then buffered until the “auto_flushing“ level has been reached. At this time the canonical_write method will be used to log all events stored in the buffer.

     # File lib/logging/appenders/buffering.rb, line 235
235:     def write( event )
236:       str = event.instance_of?(::Logging::LogEvent) ?
237:             layout.format(event) : event.to_s
238:       return if str.empty?
239: 
240:       if @auto_flushing == 1
241:         canonical_write(str)
242:       else
243:         sync { @buffer << str }
244:         @periodic_flusher.signal if @periodic_flusher
245:         flush if @buffer.length >= @auto_flushing || immediate?(event)
246:       end
247: 
248:       self
249:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.