Module: Logging::Appenders::Buffering

Included in:
IO
Defined in:
lib/logging/appenders/buffering.rb

Overview

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.

Defined Under Namespace

Classes: AsyncFlusher

Constant Summary collapse

DEFAULT_BUFFER_SIZE =

Default buffer size

500

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#asyncObject Also known as: async?

When set, the buffer will be flushed using an asynchronous Thread. That is, the main program thread will not be blocked during writes.


32
33
34
# File 'lib/logging/appenders/buffering.rb', line 32

def async
  @async
end

#auto_flushingObject

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


24
25
26
# File 'lib/logging/appenders/buffering.rb', line 24

def auto_flushing
  @auto_flushing
end

#bufferObject (readonly)

The buffer holding the log messages


20
21
22
# File 'lib/logging/appenders/buffering.rb', line 20

def buffer
  @buffer
end

#flush_periodObject

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


28
29
30
# File 'lib/logging/appenders/buffering.rb', line 28

def flush_period
  @flush_period
end

#write_sizeObject

Messages will be written in chunks. This controls the number of messages to pull from the buffer for each write operation. The default is to pull all messages from the buffer at once.


37
38
39
# File 'lib/logging/appenders/buffering.rb', line 37

def write_size
  @write_size
end

Instance Method Details

#clear!Object

Clear the underlying buffer of all log events. These events will not be appended to the logging destination; they will be lost.


102
103
104
# File 'lib/logging/appenders/buffering.rb', line 102

def clear!
  @mutex.synchronize { @buffer.clear }
end

#close(*args) ⇒ Object

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


55
56
57
58
59
60
61
62
63
64
65
# File 'lib/logging/appenders/buffering.rb', line 55

def close( *args )
  flush

  if @async_flusher
    @async_flusher.stop
    @async_flusher = nil
    Thread.pass
  end

  super(*args)
end

#flushObject

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


78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/logging/appenders/buffering.rb', line 78

def flush
  return self if @buffer.empty?

  ary = nil
  @mutex.synchronize {
    ary = @buffer.dup
    @buffer.clear
  }

  if ary.length <= write_size
    str = ary.join
    canonical_write str unless str.empty?
  else
    ary.each_slice(write_size) do |a|
      str = a.join
      canonical_write str unless str.empty?
    end
  end

  self
end

#flush_period?Boolean

Returns `true` if an asynchronous flush period has been defined for the appender.

Returns:

  • (Boolean)

223
224
225
# File 'lib/logging/appenders/buffering.rb', line 223

def flush_period?
  !@flush_period.nil?
end

#immediate_at=(level) ⇒ Object

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"

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/logging/appenders/buffering.rb', line 122

def immediate_at=( level )
  @immediate.clear

  # get the immediate levels -- no buffering occurs at these levels, and
  # a log message is written to the logging destination immediately
  immediate_at =
    case level
    when String; level.split(',').map {|x| x.strip}
    when Array; level
    else Array(level) end

  immediate_at.each do |lvl|
    num = ::Logging.level_num(lvl)
    next if num.nil?
    @immediate[num] = true
  end
end

#initialize(*args, &block) ⇒ Object

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


42
43
44
45
46
47
48
49
50
# File 'lib/logging/appenders/buffering.rb', line 42

def initialize( *args, &block )
  @buffer = []
  @immediate = []
  @auto_flushing = 1
  @async = false
  @flush_period = @async_flusher = nil

  super(*args, &block)
end

#reopenObject

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


71
72
73
74
# File 'lib/logging/appenders/buffering.rb', line 71

def reopen
  _setup_async_flusher
  super
end