Class: Lumberjack::Device::Writer

Inherits:
Lumberjack::Device show all
Defined in:
lib/lumberjack/device/writer.rb

Overview

A versatile logging device that writes formatted log entries to IO streams. This device serves as the foundation for most output-based logging, converting LogEntry objects into formatted strings using configurable templates and writing them to any IO-compatible stream.

The Writer device supports extensive customization through templates, encoding options, stream management, and error handling. It can write to files, console output, network streams, or any object that implements the IO interface.

Templates can be either string-based (compiled into Template objects) or callable objects (Procs, lambdas) for maximum flexibility. The device handles character encoding, whitespace normalization, and provides robust error recovery when stream operations fail.

See Also:

Direct Known Subclasses

LogFile

Constant Summary collapse

EDGE_WHITESPACE_PATTERN =
/\A\s|[ \t\f\v][\r\n]*\z/

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Lumberjack::Device

open_device, #reopen

Constructor Details

#initialize(stream, options = {}) ⇒ Writer

Initialize a new Writer device with configurable formatting and stream options. The device supports multiple template types, encoding control, and stream behavior configuration for flexible output handling.

Parameters:

  • stream (IO, #write)

    The target stream for log output. Can be any object that responds to write(), including File objects, STDOUT/STDERR, StringIO, network streams, or custom IO-like objects

  • options (Hash) (defaults to: {})

    Configuration options for the writer device

Options Hash (options):

  • :template (String, Proc, nil)

    The formatting template for log entries.

    • String: Compiled into a Template object (default: “[:time :severity :progname(:pid)] :message”)

    • Proc: Called with LogEntry, should return formatted string

    • nil: Uses default template

  • :standard_logger_formatter (Logger::Formatter)

    Use a Ruby Logger formatter for compatibility with existing logging code

  • :additional_lines (String, nil)

    Template for formatting additional lines in multi-line messages (default: “n :message”)

  • :time_format (String, Symbol)

    Format for timestamps in templates. Accepts strftime patterns or :milliseconds/:microseconds shortcuts

  • :attribute_format (String)

    Printf-style format for attributes with exactly two %s placeholders for name and value (default: “[%s:%s]”)

  • :autoflush (Boolean) — default: true

    Whether to automatically flush the stream after each write for immediate output

  • :binmode (Boolean) — default: false

    Whether to treat the stream as binary, skipping UTF-8 encoding conversion

  • :colorize (Boolean) — default: false

    Whether to colorize log output



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/lumberjack/device/writer.rb', line 55

def initialize(stream, options = {})
  @stream = stream
  @stream.sync = true if @stream.respond_to?(:sync=) && options[:autoflush] != false

  @binmode = options[:binmode]

  if options[:standard_logger_formatter]
    @template = Template::StandardFormatterTemplate.new(options[:standard_logger_formatter])
  else
    template = options[:template]

    template = TemplateRegistry.template(template, options) if template.is_a?(Symbol)

    @template = if template.respond_to?(:call)
      template
    else
      Template.new(
        template,
        additional_lines: options[:additional_lines],
        time_format: options[:time_format],
        attribute_format: options[:attribute_format],
        colorize: options[:colorize]
      )
    end
  end
end

Instance Attribute Details

#streamIO

The underlying stream object that is being written to.

Returns:

  • (IO)

    The current stream object



167
168
169
# File 'lib/lumberjack/device/writer.rb', line 167

def stream
  @stream
end

Instance Method Details

#closevoid

This method returns an undefined value.

Close the underlying stream and release any associated resources. This method ensures all buffered data is flushed before closing the stream, providing clean shutdown behavior for file handles and network connections.



109
110
111
112
# File 'lib/lumberjack/device/writer.rb', line 109

def close
  flush
  stream.close
end

#datetime_formatString?

Get the current datetime format from the template if supported. Returns the format string used for timestamp formatting in log entries.

Returns:

  • (String, nil)

    The datetime format string if the template supports it, or nil if the template doesn’t provide datetime formatting



128
129
130
# File 'lib/lumberjack/device/writer.rb', line 128

def datetime_format
  @template.datetime_format if @template.respond_to?(:datetime_format)
end

#datetime_format=(format) ⇒ void

This method returns an undefined value.

Set the datetime format on the template if supported. This allows dynamic reconfiguration of timestamp formatting without recreating the device.

Parameters:

  • format (String)

    The datetime format string (strftime pattern) to apply to the template for timestamp formatting



138
139
140
141
142
# File 'lib/lumberjack/device/writer.rb', line 138

def datetime_format=(format)
  if @template.respond_to?(:datetime_format=)
    @template.datetime_format = format
  end
end

#devIO

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Access the underlying IO stream for direct manipulation or compatibility with code expecting Logger device interface. This method provides the raw stream object for advanced use cases.

Returns:

  • (IO)

    The underlying stream object used for output



150
151
152
# File 'lib/lumberjack/device/writer.rb', line 150

def dev
  stream
end

#flushvoid

This method returns an undefined value.

Flush the underlying stream to ensure all buffered data is written to the destination. This method is safe to call on streams that don’t support flushing, making it suitable for various IO types.



119
120
121
# File 'lib/lumberjack/device/writer.rb', line 119

def flush
  stream.flush if stream.respond_to?(:flush)
end

#pathString?

Get the file system path of the underlying stream if available. This method is useful for monitoring, log rotation, or any operations that need to work with the actual file path.

Returns:

  • (String, nil)

    The file system path if the stream is file-based, or nil for non-file streams (STDOUT, StringIO, network streams, etc.)



160
161
162
# File 'lib/lumberjack/device/writer.rb', line 160

def path
  stream.path if stream.respond_to?(:path)
end

#write(entry) ⇒ void

This method returns an undefined value.

Write a log entry to the stream with automatic formatting and error handling. The entry is converted to a string using the configured template, processed for encoding and whitespace, and written to the stream with robust error recovery.

Parameters:

  • entry (LogEntry, String)

    The log entry to write. LogEntry objects are formatted using the template, while strings are written directly after encoding and whitespace processing



90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/lumberjack/device/writer.rb', line 90

def write(entry)
  string = (entry.is_a?(LogEntry) ? @template.call(entry) : entry)
  return if string.nil?

  if !@binmode && string.encoding != Encoding::UTF_8
    string = string.encode("UTF-8", invalid: :replace, undef: :replace)
  end

  string = string.strip if string.match?(EDGE_WHITESPACE_PATTERN)
  return if string.length == 0 || string == Lumberjack::LINE_SEPARATOR

  write_to_stream(string)
end