class Lumberjack::Device::Writer

If it is implemented, it will be called before every flush inside a mutex lock.
Subclasses can implement a before_flush method if they have logic to execute before flushing the log.
and written to the stream in a batch when the buffer is full or when flush is called.
This logging device writes log entries as strings to an IO stream. By default, messages will be buffered

def buffer_size=(value)

Returns:
  • (void) -

Parameters:
  • value (Integer) -- The size of the buffer in bytes.
def buffer_size=(value)
  @buffer_size = value
  flush
end

def close

Returns:
  • (void) -
def close
  flush
  stream.close
end

def datetime_format

Returns:
  • (String) - The datetime format.
def datetime_format
  @template.datetime_format if @template.respond_to?(:datetime_format)
end

def datetime_format=(format)

Returns:
  • (void) -

Parameters:
  • format (String) -- The datetime format.
def datetime_format=(format)
  if @template.respond_to?(:datetime_format=)
    @template.datetime_format = format
  end
end

def flush

Returns:
  • (void) -
def flush
  lines = nil
  @lock.synchronize do
    before_flush if respond_to?(:before_flush, true)
    lines = @buffer.pop!
  end
  write_to_stream(lines) if lines
end

def initialize(stream, options = {})

Parameters:
  • options (Hash) -- The options for the device.
  • stream (IO) -- The stream to write log entries to.
def initialize(stream, options = {})
  @lock = Mutex.new
  @stream = stream
  @stream.sync = true if @stream.respond_to?(:sync=)
  @buffer = Buffer.new
  @buffer_size = (options[:buffer_size] || 0)
  template = (options[:template] || DEFAULT_FIRST_LINE_TEMPLATE)
  if template.respond_to?(:call)
    @template = template
  else
    additional_lines = (options[:additional_lines] || DEFAULT_ADDITIONAL_LINES_TEMPLATE)
    @template = Template.new(template, additional_lines: additional_lines, time_format: options[:time_format])
  end
end

def write(entry)

Returns:
  • (void) -

Parameters:
  • entry (LogEntry, String) -- The entry to write to the stream.
def write(entry)
  string = (entry.is_a?(LogEntry) ? @template.call(entry) : entry)
  return if string.nil?
  string = string.strip
  return if string.length == 0
  unless string.encoding == Encoding::UTF_8
    string = string.encode("UTF-8", invalid: :replace, undef: :replace)
  end
  if buffer_size > 1
    @lock.synchronize do
      @buffer << string
    end
    flush if @buffer.size >= buffer_size
  else
    flush if respond_to?(:before_flush, true)
    write_to_stream(string)
  end
end

def write_to_stream(lines)

def write_to_stream(lines)
  return if lines.empty?
  lines = lines.first if lines.is_a?(Array) && lines.size == 1
  out = nil
  out = if lines.is_a?(Array)
    "#{lines.join(Lumberjack::LINE_SEPARATOR)}#{Lumberjack::LINE_SEPARATOR}"
  else
    "#{lines}#{Lumberjack::LINE_SEPARATOR}"
  end
  begin
    begin
      stream.write(out)
    rescue IOError => e
      # This condition can happen if another thread closed the stream in the `before_flush` call.
      # Synchronizing will handle the race condition, but since it's an exceptional case we don't
      # want to lock the thread on every stream write call.
      @lock.synchronize do
        if stream.closed?
          raise e
        else
          stream.write(out)
        end
      end
    end
    begin
      stream.flush
    rescue
      nil
    end
  rescue => e
    $stderr.write("#{e.class.name}: #{e.message}#{" at " + e.backtrace.first if e.backtrace}")
    $stderr.write(out)
    $stderr.flush
  end
end