Class: Lumberjack::Formatter

Inherits:
Object
  • Object
show all
Defined in:
lib/lumberjack/formatter.rb,
lib/lumberjack/formatter/id_formatter.rb,
lib/lumberjack/formatter/tagged_message.rb,
lib/lumberjack/formatter/round_formatter.rb,
lib/lumberjack/formatter/strip_formatter.rb,
lib/lumberjack/formatter/object_formatter.rb,
lib/lumberjack/formatter/redact_formatter.rb,
lib/lumberjack/formatter/string_formatter.rb,
lib/lumberjack/formatter/inspect_formatter.rb,
lib/lumberjack/formatter/multiply_formatter.rb,
lib/lumberjack/formatter/truncate_formatter.rb,
lib/lumberjack/formatter/date_time_formatter.rb,
lib/lumberjack/formatter/exception_formatter.rb,
lib/lumberjack/formatter/structured_formatter.rb,
lib/lumberjack/formatter/pretty_print_formatter.rb

Overview

This class controls the conversion of log entry messages into a loggable format. This allows you to log any object you want and have the logging system deal with converting it into a string.

Formats are added to a Formatter by associating them with a class using the add method. Formats are any object that responds to the call method.

By default, all object will be converted to strings using their inspect method except for Strings and Exceptions. Strings are not converted and Exceptions are converted using the ExceptionFormatter.

Enumerable objects (including Hash and Array) will call the formatter recursively for each element.

Direct Known Subclasses

TaggedLoggerSupport::Formatter

Defined Under Namespace

Classes: DateTimeFormatter, ExceptionFormatter, IdFormatter, InspectFormatter, MultiplyFormatter, ObjectFormatter, PrettyPrintFormatter, RedactFormatter, RoundFormatter, StringFormatter, StripFormatter, StructuredFormatter, TaggedMessage, TruncateFormatter

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeFormatter

Returns a new instance of Formatter.



41
42
43
44
45
46
47
48
49
# File 'lib/lumberjack/formatter.rb', line 41

def initialize
  @class_formatters = {}
  @module_formatters = {}
  structured_formatter = StructuredFormatter.new(self)
  add([String, Numeric, TrueClass, FalseClass], :object)
  add(Object, InspectFormatter.new)
  add(Exception, :exception)
  add(Enumerable, structured_formatter)
end

Class Method Details

.emptyLumberjack::Formatter

Returns a new empty formatter with no mapping. For historical reasons, a formatter is initialized with mappings to help output objects as strings. This will return one without the default mappings.

Returns:



36
37
38
# File 'lib/lumberjack/formatter.rb', line 36

def empty
  new.clear
end

Instance Method Details

#add(klass, formatter = nil, *args) {|obj| ... } ⇒ self

Add a formatter for a class. The formatter can be specified as either an object that responds to the call method or as a symbol representing one of the predefined formatters, or as a block to the method call.

The predefined formatters are:

- :date_time
- :exception
- :id
- :inspect
- :object
- :pretty_print
- :string
- :strip
- :structured
- :truncate

You can add multiple classes at once by passing an array of classes.

You can also pass class names as strings instead of the classes themselves. This can help avoid loading dependency issues. This applies only to classes; modules cannot be passed in as strings.

Examples:


# Use a predefined formatter
formatter.add(MyClass, :pretty_print)

# Pass in a formatter object
formatter.add(MyClass, Lumberjack::Formatter::PrettyPrintFormatter.new)

# Use a block
formatter.add(MyClass){|obj| obj.humanize}

# Add statements can be chained together
formatter.add(MyClass, :pretty_print).add(YourClass){|obj| obj.humanize}

Parameters:

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

    The class or module to add a formatter for.

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

    The formatter to use for the class. If a symbol is passed in, it will be used to load one of the predefined formatters. If a class is passed in, it will be initialized with the args passed in. Otherwise, the object will be used as the formatter and must respond to call method.

  • args (Array)

    Arguments to pass to the formatter when it is initialized.

Yields:

  • (obj)

    A block that will be used as the formatter for the class.

Yield Parameters:

  • obj (Object)

    The object to format.

Yield Returns:

  • (String)

    The formatted string.

Returns:

  • (self)

    Returns itself so that add statements can be chained together.



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/lumberjack/formatter.rb', line 97

def add(klass, formatter = nil, *args, &block)
  formatter ||= block
  if formatter.nil?
    remove(klass)
  else
    formatter_class_name = nil
    if formatter.is_a?(Symbol)
      formatter_class_name = "#{formatter.to_s.gsub(/(^|_)([a-z])/) { |m| $~[2].upcase }}Formatter"
    elsif formatter.is_a?(String)
      formatter_class_name = formatter
    end
    if formatter_class_name
      formatter = Formatter.const_get(formatter_class_name)
    end

    if formatter.is_a?(Class)
      formatter = formatter.new(*args)
    end

    Array(klass).each do |k|
      if k.instance_of?(Module)
        @module_formatters[k] = formatter
      else
        k = k.name if k.is_a?(Class)
        @class_formatters[k] = formatter
      end
    end
  end
  self
end

#call(severity, timestamp, progname, msg) ⇒ Object

Compatibility with the Logger::Formatter signature. This method will just convert the message object to a string and ignores the other parameters.

Parameters:

  • severity (Integer, String, Symbol)

    The severity of the message.

  • timestamp (Time)

    The time the message was logged.

  • progname (String)

    The name of the program logging the message.

  • msg (Object)

    The message object to format.



193
194
195
196
197
# File 'lib/lumberjack/formatter.rb', line 193

def call(severity, timestamp, progname, msg)
  formatted_message = format(msg)
  formatted_message = formatted_message.message if formatted_message.is_a?(TaggedMessage)
  "#{formatted_message}#{Lumberjack::LINE_SEPARATOR}"
end

#clearself

Remove all formatters including the default formatter. Can be chained to add method calls.

Returns:

  • (self)

    Returns itself so that clear statements can be chained together.



153
154
155
156
157
# File 'lib/lumberjack/formatter.rb', line 153

def clear
  @class_formatters.clear
  @module_formatters.clear
  self
end

#empty?Boolean

Return true if their are no registered formatters.

Returns:

  • (Boolean)

    true if there are no registered formatters, false otherwise.



162
163
164
# File 'lib/lumberjack/formatter.rb', line 162

def empty?
  @class_formatters.empty? && @module_formatters.empty?
end

#format(message) ⇒ Object

Format a message object by applying all formatters attached to it.

Parameters:

  • message (Object)

    The message object to format.

Returns:

  • (Object)

    The formatted object.



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/lumberjack/formatter.rb', line 170

def format(message)
  formatter = formatter_for(message.class)
  if formatter&.respond_to?(:call)
    begin
      formatter.call(message)
    rescue SystemStackError, StandardError => e
      error_message = e.class.name
      error_message = "#{error_message} #{e.message}" if e.message && e.message != ""
      warn("<Error formatting #{message.class.name}: #{error_message}>")
      "<Error formatting #{message.class.name}: #{error_message}>"
    end
  else
    message
  end
end

#formatter_for(klass) ⇒ Object

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.

Find the formatter for a class by looking it up using the class hierarchy.



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/lumberjack/formatter.rb', line 202

def formatter_for(klass)
  return nil if empty?

  check_modules = true
  until klass.nil?
    formatter = @class_formatters[klass.name]
    return formatter if formatter

    if check_modules
      _, formatter = @module_formatters.detect { |mod, f| klass.include?(mod) }
      check_modules = false
      return formatter if formatter
    end

    klass = klass.superclass
  end
end

#remove(klass) ⇒ self

Remove the formatter associated with a class. Remove statements can be chained together.

You can remove multiple classes at once by passing an array of classes.

You can also pass class names as strings instead of the classes themselves. This can help avoid loading dependency issues. This applies only to classes; modules cannot be passed in as strings.

Parameters:

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

    The class or module to remove the formatters for.

Returns:

  • (self)

    Returns itself so that remove statements can be chained together.



138
139
140
141
142
143
144
145
146
147
148
# File 'lib/lumberjack/formatter.rb', line 138

def remove(klass)
  Array(klass).each do |k|
    if k.instance_of?(Module)
      @module_formatters.delete(k)
    else
      k = k.name if k.is_a?(Class)
      @class_formatters.delete(k)
    end
  end
  self
end