Class: Lumberjack::EntryFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/lumberjack/entry_formatter.rb

Overview

EntryFormatter provides a unified interface for formatting complete log entries by combining message formatting and attribute formatting into a single, coordinated system.

This class serves as the central formatting coordinator in the Lumberjack logging pipeline, bringing together two specialized formatters:

  1. Message Formatter (Formatter) - Formats the main log message content

  2. Attribute Formatter (AttributeFormatter) - Formats key-value attribute pairs

Examples:

Complete entry formatting setup

entry_formatter = Lumberjack::EntryFormatter.build do |formatter|
  # Formatter will be used in both log messages and attributes
  formatter.format_class(ActiveRecord::Base, :id)

  # Message specific formatters
  formatter.format_message(Exception, :exception)
  formatter.format_message(Time, :date_time, "%Y-%m-%d %H:%M:%S")

  # Attribute specific formatters
  formatter.format_attributes(Time, :date_time, "%Y-%m-%d")
  formatter.format_attribute_name("password") { |value| "[REDACTED]" }
  formatter.format_attribute_name("user_id", :id)
  formatter.default_attribute_format { |value| value.to_s.strip }
end

Using with a logger

logger = Lumberjack::Logger.new(STDOUT, formatter: entry_formatter)
logger.info("User login", user: user_object, timestamp: Time.now)
# Both the message and attributes are formatted according to the rules

See Also:

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(message_formatter: nil, attribute_formatter: nil) ⇒ EntryFormatter

Create a new entry formatter with the specified message and attribute formatters.

Parameters:

  • message_formatter (Lumberjack::Formatter, Symbol, nil) (defaults to: nil)

    The message formatter to use:

    • Formatter instance: Used directly

    • :default or nil: Creates a new Formatter with default mappings

    • :none: Creates an empty Formatter with no default mappings

  • attribute_formatter (Lumberjack::AttributeFormatter, nil) (defaults to: nil)

    The attribute formatter to use. If nil, no attribute formatting will be performed unless configured later.



78
79
80
81
# File 'lib/lumberjack/entry_formatter.rb', line 78

def initialize(message_formatter: nil, attribute_formatter: nil)
  self.message_formatter = message_formatter
  self.attribute_formatter = attribute_formatter
end

Instance Attribute Details

#attribute_formatterLumberjack::AttributeFormatter

The attribute formatter used to format log entry attributes.

Returns:



43
44
45
# File 'lib/lumberjack/entry_formatter.rb', line 43

def attribute_formatter
  @attribute_formatter
end

#message_formatterLumberjack::Formatter

The message formatter used to format log message content.

Returns:



39
40
41
# File 'lib/lumberjack/entry_formatter.rb', line 39

def message_formatter
  @message_formatter
end

Class Method Details

.build(message_formatter: nil, attribute_formatter: nil) {|formatter| ... } ⇒ Lumberjack::EntryFormatter

Build a new entry formatter using a configuration block. The block receives the new formatter as a parameter, allowing you to configure it with various configuration methods.

Examples:

formatter = Lumberjack::EntryFormatter.build do |config|
  config.add(User, :id)  # Message formatting
  config.add(Time, :date_time, "%Y-%m-%d")

  config.add_attribute("password") { "[REDACTED]" } # ensure passwords are not logged
  config.add_attribute_class(Exception) { |e| {error: e.class.name, message: e.message} }
end

Parameters:

  • message_formatter (Lumberjack::Formatter, Symbol, nil) (defaults to: nil)

    The message formatter to use. Can be a Formatter instance, :default for standard formatter, :none for empty formatter, or nil.

  • attribute_formatter (Lumberjack::AttributeFormatter, nil) (defaults to: nil)

    The attribute formatter to use.

Yields:

  • (formatter)

    A block that configures the entry formatter.

Returns:



63
64
65
66
67
# File 'lib/lumberjack/entry_formatter.rb', line 63

def build(message_formatter: nil, attribute_formatter: nil, &block)
  formatter = new(message_formatter: message_formatter, attribute_formatter: attribute_formatter)
  block&.call(formatter)
  formatter
end

Instance Method Details

#call(severity, timestamp, progname, msg) ⇒ String?

Compatibility method for Ruby’s standard Logger::Formatter interface. This delegates to the message formatter’s call method for basic Logger compatibility.

Parameters:

  • severity (Integer, String, Symbol)

    The log severity (passed to message formatter).

  • timestamp (Time)

    The log timestamp (passed to message formatter).

  • progname (String)

    The program name (passed to message formatter).

  • msg (Object)

    The message object to format (passed to message formatter).

Returns:

  • (String, nil)

    The formatted message string, or nil if no message formatter.

See Also:



312
313
314
# File 'lib/lumberjack/entry_formatter.rb', line 312

def call(severity, timestamp, progname, msg)
  message_formatter&.call(severity, timestamp, progname, msg)
end

#default_attribute_format(formatter = nil, *args) {|value| ... } ⇒ Lumberjack::EntryFormatter

Set the default attribute formatter to apply to any attributes that do not have a specific formatter defined.

Parameters:

  • formatter (Symbol, Class, #call, nil) (defaults to: nil)

    The default formatter to use. If nil, removes any existing default formatter.

  • args (Array)

    Arguments to pass to the formatter constructor (when formatter is a Class).

Yields:

  • (value)

    Block-based formatter that receives the attribute value.

Returns:

See Also:



213
214
215
216
# File 'lib/lumberjack/entry_formatter.rb', line 213

def default_attribute_format(formatter = nil, *args, &block)
  @attribute_formatter.default(formatter, *args, &block)
  self
end

#format(message, attributes) ⇒ Array<Object, Hash>

Format a complete log entry by applying both message and attribute formatting. This is the main method that coordinates the formatting of both the message content and any associated attributes.

Parameters:

  • message (Object, Proc, nil)

    The log message to format. Can be any object, a Proc that returns the message, or nil.

  • attributes (Hash, nil)

    The log entry attributes to format.

Returns:

  • (Array<Object, Hash>)

    A two-element array containing [formatted_message, formatted_attributes].



284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/lumberjack/entry_formatter.rb', line 284

def format(message, attributes)
  message = message.call if message.is_a?(Proc)
  message = message_formatter.format(message) if message_formatter.respond_to?(:format)

  message_attributes = nil
  if message.is_a?(MessageAttributes)
    message_attributes = message.attributes
    message = message.message
  end
  message_attributes = Utils.flatten_attributes(message_attributes) if message_attributes

  attributes = merge_attributes(attributes, message_attributes) if message_attributes
  attributes = AttributesHelper.expand_runtime_values(attributes)
  attributes = attribute_formatter.format(attributes) if attributes && attribute_formatter

  [message, attributes]
end

#format_attribute_name(names, formatter = nil, *args) {|value| ... } ⇒ Lumberjack::EntryFormatter

Add a formatter for the named attribute.

Parameters:

  • names (String, Symbol, Array<String, Symbol>)

    The attribute names to format.

  • formatter (Symbol, Class, #call, nil) (defaults to: nil)

    The formatter to use

  • args (Array)

    Arguments to pass to the formatter constructor (when formatter is a Class).

Yields:

  • (value)

    Block-based formatter that receives the attribute value.

Returns:

See Also:



184
185
186
187
# File 'lib/lumberjack/entry_formatter.rb', line 184

def format_attribute_name(names, formatter = nil, *args, &block)
  @attribute_formatter.add_attribute(names, formatter, *args, &block)
  self
end

#format_attributes(classes_or_names, formatter = nil, *args) {|value| ... } ⇒ Lumberjack::EntryFormatter

Add a formatter for the specified class or module when it appears as an attribute value.

Parameters:

  • classes_or_names (String, Module, Array<String, Module>)

    Class names or modules.

  • formatter (Symbol, Class, #call, nil) (defaults to: nil)

    The formatter to use

  • args (Array)

    Arguments to pass to the formatter constructor (when formatter is a Class).

Yields:

  • (value)

    Block-based formatter that receives the attribute value.

Returns:

See Also:



198
199
200
201
# File 'lib/lumberjack/entry_formatter.rb', line 198

def format_attributes(classes_or_names, formatter = nil, *args, &block)
  @attribute_formatter.add_class(classes_or_names, formatter, *args, &block)
  self
end

#format_class(classes_or_names, formatter = nil, *args) {|obj| ... } ⇒ Lumberjack::EntryFormatter

Add a formatter for specific classes or modules. This method adds the formatter for both log messages and attributes.

Examples:

Adding formatters

formatter.format_class(User, :id)  # Use ID formatter for User objects
formatter.format_class(Array) { |vals| vals.join(", ") }  # Handle arrays
formatter.format_class(Time, :date_time, "%Y-%m-%d")  # Custom time format only

Parameters:

  • classes_or_names (Class, Module, String, Array<Class, Module, String>)

    The class(es) to format.

  • formatter (Symbol, Class, #call, nil) (defaults to: nil)

    The formatter to use.

  • args (Array)

    Arguments to pass to the formatter constructor (when formatter is a Class).

Yields:

  • (obj)

    Block-based formatter that receives the object to format.

Returns:

See Also:



123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/lumberjack/entry_formatter.rb', line 123

def format_class(classes_or_names, formatter = nil, *args, &block)
  Array(classes_or_names).each do |class_or_name|
    unless @message_formatter.include?(class_or_name)
      @message_formatter.add(class_or_name, formatter, *args, &block)
    end

    unless @attribute_formatter.include_class?(class_or_name)
      @attribute_formatter.add_class(class_or_name, formatter, *args, &block)
    end
  end

  self
end

#format_message(classes_or_names, formatter = nil, *args) {|obj| ... } ⇒ Lumberjack::EntryFormatter

Add a message formatter for specific classes or modules.

Parameters:

  • classes_or_names (String, Module, Array<String, Module>)

    Class names or modules.

  • formatter (Symbol, Class, #call, nil) (defaults to: nil)

    The formatter to use

  • args (Array)

    Arguments to pass to the formatter constructor (when formatter is a Class).

Yields:

  • (obj)

    Block-based formatter that receives the object to format.

Returns:

See Also:



159
160
161
162
# File 'lib/lumberjack/entry_formatter.rb', line 159

def format_message(classes_or_names, formatter = nil, *args, &block)
  @message_formatter.add(classes_or_names, formatter, *args, &block)
  self
end

#include(formatter) ⇒ self

Extend this formatter by adding the formats defined in the provided formatter into this one.

Parameters:

Returns:

  • (self)

    Returns self for method chaining.



244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/lumberjack/entry_formatter.rb', line 244

def include(formatter)
  unless formatter.is_a?(Lumberjack::EntryFormatter)
    raise ArgumentError.new("formatter must be a Lumberjack::EntryFormatter")
  end

  @message_formatter ||= Lumberjack::Formatter.new
  @message_formatter.include(formatter.message_formatter)

  @attribute_formatter ||= Lumberjack::AttributeFormatter.new
  @attribute_formatter.include(formatter.attribute_formatter)

  self
end

#prepend(formatter) ⇒ self

Extend this formatter by adding the formats defined in the provided formatter into this one. Formats defined in this formatter will take precedence and not be overridden.

Parameters:

Returns:

  • (self)

    Returns self for method chaining.



263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/lumberjack/entry_formatter.rb', line 263

def prepend(formatter)
  unless formatter.is_a?(Lumberjack::EntryFormatter)
    raise ArgumentError.new("formatter must be a Lumberjack::EntryFormatter")
  end

  @message_formatter ||= Lumberjack::Formatter.new
  @message_formatter.prepend(formatter.message_formatter)

  @attribute_formatter ||= Lumberjack::AttributeFormatter.new
  @attribute_formatter.prepend(formatter.attribute_formatter)

  self
end

#remove_attribute_class(classes_or_names) ⇒ Lumberjack::EntryFormatter

Remove an attribute formatter for the specified classes or modules.

Parameters:

  • classes_or_names (String, Module, Array<String, Module>)

    Class names or modules.

Returns:

See Also:



235
236
237
238
# File 'lib/lumberjack/entry_formatter.rb', line 235

def remove_attribute_class(classes_or_names)
  @attribute_formatter.remove_class(classes_or_names)
  self
end

#remove_attribute_name(names) ⇒ Lumberjack::EntryFormatter

Remove an attribute formatter for the specified attribute names.

Parameters:

  • names (String, Symbol, Array<String, Symbol>)

    The attribute names to remove formatters for.

Returns:

See Also:



224
225
226
227
# File 'lib/lumberjack/entry_formatter.rb', line 224

def remove_attribute_name(names)
  @attribute_formatter.remove_attribute(names)
  self
end

#remove_class(classes_or_names) ⇒ Lumberjack::EntryFormatter

Remove a formatter for specific classes or modules. This method removes the formatter for both log messages and attributes.

Parameters:

  • classes_or_names (Class, Module, String, Array<Class, Module, String>)

    The class(es) to remove formatters for.

Returns:

See Also:



144
145
146
147
148
# File 'lib/lumberjack/entry_formatter.rb', line 144

def remove_class(classes_or_names)
  @message_formatter.remove(classes_or_names)
  @attribute_formatter.remove_class(classes_or_names)
  self
end

#remove_message_formatter(classes_or_names) ⇒ Lumberjack::EntryFormatter

Remove a message formatter for specific classes or modules.

Parameters:

  • classes_or_names (String, Module, Array<String, Module>)

    Class names or modules.

Returns:

See Also:



170
171
172
173
# File 'lib/lumberjack/entry_formatter.rb', line 170

def remove_message_formatter(classes_or_names)
  @message_formatter.remove(classes_or_names)
  self
end