Class: Safis::Logging::SimpleFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/safis/logging/simple_formatter.rb

Overview

A simple log formatter.

This formatter generates logging output in the following format:

SEVERITY: [component HH:MM:SS] Log message [ISO-8601 Datetime]

If the log event had details associated with it, the details value is inspected and printed to the following line. Exceptions are logged with their full backtrace.

A Few Examples

Simple log event

WARN: [Object 19:57:24] The world shall be ours! ...in due time. [2009-07-01T19:57:24.818687-07:00]

Log event with details

INFO: [Villany::DoomLaser 04:32:27] Doom laser locked on target. [2009-07-02T04:32:27.775913-07:00]
  #<Villany::DoomLaser:0x13ee44 @power_level=11, @target=[40.689606, -74.044901]>

Log event with an exception as details

FATAL: [Villany::SharkTankTrapDoor 20:24:38] The trap door failed to open. Execute the nearest henchman immediately! [2009-07-01T20:24:38.747175-07:00]
  TrapDoorFailure: The magma vents are blocked.
    /villany/power_source/geothermal.rb:27:in `reroute_magma_flow'
    /villany/power_source/geothermal.rb:53:in `check_power_levels'
    ...

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(output = STDOUT) ⇒ SimpleFormatter

Creates a new SimpleFormatter.

Parameters:

  • output (optional, #write) (defaults to: STDOUT)

    An IO-like object to write our formatted logging output to.



49
50
51
# File 'lib/safis/logging/simple_formatter.rb', line 49

def initialize(output = STDOUT)
  @output = output
end

Class Method Details

.format_event(event) ⇒ String

Formats an event.

An event is an array with values in the following order:

  • severity

  • component name

  • timestamp

  • message

  • event details (optional - usually an exception)

Parameters:

  • event (Array)

    The event to log.

Returns:

  • (String)

    The formatted event.



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/safis/logging/simple_formatter.rb', line 115

def self.format_event(event)
  result = ''
  
  severity   = event[0].to_s.upcase
  component  = event[1]
  short_time = event[2].strftime('%H:%M:%S')
  iso_time   = event[2].iso8601
  message    = event[3]
  details    = event[4]
  
  result << "#{severity}: [#{component} #{short_time}] #{message} [#{iso_time}]\n"
  
  if ( not details.nil? ) then
    # Does it look like an exception?
    if ( details.respond_to? :backtrace ) then
      result << '  ' + details.message + "\n"
      
      # and the backtrace
      details.backtrace.each do |line|
        result << '    ' + line + "\n"
      end
      
    # Nope, just inspect it
    else
      result << '  ' + details.inspect + "\n"
    end
  end
  
  return result
end

Instance Method Details

#log_event(event, filter = true) ⇒ SimpleFormatter

Formats and outputs an event.

An event is an array with values in the following order:

  • severity

  • component name

  • timestamp

  • message

  • event details (optional - usually an exception)

Parameters:

  • event (Array)

    The event to log.

  • filter (Boolean) (defaults to: true)

    This is ignored by SimpleFormatter. It does not filter events.

Returns:



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/safis/logging/simple_formatter.rb', line 66

def log_event(event, filter = true)
  begin
    formatted_event = self.class.format_event(event)
    
  # The logging facilities shouldn't generate exceptions themselves if we can help it.
  rescue Exception => err
    formatted_event  = "We failed to format a log event!  Event details:\n"
    formatted_event << event.inspect + "\n"
    formatted_event << "Exception: #{err.message}\n"
    err.backtrace.each do |line|
      formatted_event << line + "\n"
    end
  end
  
  # Write the entry as a single transaction
  begin
    @output.write(formatted_event)
    
  rescue Exception => err
    # Generate an event for this exception (SPAMMY!)
    write_failure = self.class.format_event([
      :error,
      self.class.name,
      Time.now,
      "Unable to write a formatted log event to #{@output.inspect}!",
      err
    ])
    STDERR.write(write_failure)
    
    # Write the original error
    STDOUT.write(result)
  end
  
  # For those who love to chain
  self
end