lib/logging/layouts/parseable.rb in logging-1.7.2 vs lib/logging/layouts/parseable.rb in logging-1.8.0
- old
+ new
@@ -62,16 +62,16 @@
# the name of the item, and the value is what you would expect it to be.
# Therefore, for the default set of times log message would appear as
# follows:
#
# ---
- # timestamp: 2009-04-17 16:15:42
+ # timestamp: 2009-04-17T16:15:42
# level: INFO
# logger: Foo::Bar
# message: this is a log message
# ---
- # timestamp: 2009-04-17 16:15:43
+ # timestamp: 2009-04-17T16:15:43
# level: ERROR
# logger: Foo
# message: <RuntimeError> Oooops!!
#
# The output order of the fields is not guaranteed to be the same as the
@@ -82,32 +82,34 @@
# will be formatted as an object (in the JSON sense of the word) on it's
# own line in the log output. Therefore, to parse the output you must read
# it line by line and parse the individual objects. Taking the same
# example above the JSON output would be:
#
- # {"timestamp":"2009-04-17 16:15:42","level":"INFO","logger":"Foo::Bar","message":"this is a log message"}
- # {"timestamp":"2009-04-17 16:15:43","level":"ERROR","logger":"Foo","message":"<RuntimeError> Oooops!!"}
+ # {"timestamp":"2009-04-17T16:15:42","level":"INFO","logger":"Foo::Bar","message":"this is a log message"}
+ # {"timestamp":"2009-04-17T16:15:43","level":"ERROR","logger":"Foo","message":"<RuntimeError> Oooops!!"}
#
# The output order of the fields is guaranteed to be the same as the order
# specified in the _items_ list.
#
class Parseable < ::Logging::Layout
# :stopdoc:
# Arguments to sprintf keyed to directive letters
DIRECTIVE_TABLE = {
- 'logger' => 'event.logger',
- 'timestamp' => 'event.time',
- 'level' => '::Logging::LNAMES[event.level]',
- 'message' => 'format_obj(event.data)',
- 'file' => 'event.file',
- 'line' => 'event.line',
- 'method' => 'event.method',
- 'pid' => 'Process.pid',
- 'millis' => 'Integer((event.time-@created_at)*1000)',
- 'thread_id' => 'Thread.current.object_id',
- 'thread' => 'Thread.current[:name]'
+ 'logger' => 'event.logger'.freeze,
+ 'timestamp' => 'iso8601_format(event.time)'.freeze,
+ 'level' => '::Logging::LNAMES[event.level]'.freeze,
+ 'message' => 'format_obj(event.data)'.freeze,
+ 'file' => 'event.file'.freeze,
+ 'line' => 'event.line'.freeze,
+ 'method' => 'event.method'.freeze,
+ 'pid' => 'Process.pid'.freeze,
+ 'millis' => 'Integer((event.time-@created_at)*1000)'.freeze,
+ 'thread_id' => 'Thread.current.object_id'.freeze,
+ 'thread' => 'Thread.current[:name]'.freeze,
+ 'mdc' => 'Logging::MappedDiagnosticContext.context'.freeze,
+ 'ndc' => 'Logging::NestedDiagnosticContext.context'.freeze
}
# call-seq:
# Pattern.create_yaml_format_methods( layout )
#
@@ -132,18 +134,16 @@
# This method will create the +format+ method in the given Parseable
# _layout_ based on the configured items for the layout instance.
#
def self.create_json_format_method( layout )
code = "undef :format if method_defined? :format\n"
- code << "def format( event )\n\"{"
+ code << "def format( event )\nh = {\n"
- args = []
code << layout.items.map {|name|
- args << "format_as_json(#{Parseable::DIRECTIVE_TABLE[name]})"
- "\\\"#{name}\\\":%s"
- }.join(',')
- code << "}\\n\" % [#{args.join(', ')}]\nend"
+ "'#{name}' => #{Parseable::DIRECTIVE_TABLE[name]}"
+ }.join(",\n")
+ code << "\n}\nMultiJson.encode(h) << \"\\n\"\nend\n"
(class << layout; self end).class_eval(code, __FILE__, __LINE__)
end
# :startdoc:
@@ -199,20 +199,35 @@
raise ArgumentError, "unknown item - #{name.inspect}" unless valid.include? name
end
create_format_method
end
- private
-
- # Take the given _value_ and format it into a JSON compatible string.
+ # Public: Take a given object and convert it into a format suitable for
+ # inclusion as a log message. The conversion allows the object to be more
+ # easily expressed in YAML or JSON form.
#
- def format_as_json( value )
- case value
- when String, Integer, Float; value.inspect
- when nil; 'null'
- when Time; %Q{"#{iso8601_format(value)}"}
- else %Q{"#{value.inspect}"} end
+ # If the object is an Exception, then this method will return a Hash
+ # containing the exception class name, message, and backtrace (if any).
+ #
+ # obj - The Object to format
+ #
+ # Returns the formatted Object.
+ #
+ def format_obj( obj )
+ case obj
+ when Exception
+ h = { :class => obj.class.name,
+ :message => obj.message }
+ h[:backtrace] = obj.backtrace if @backtrace && !obj.backtrace.nil?
+ h
+ when Time
+ iso8601_format(obj)
+ else
+ obj
+ end
end
+
+ private
# Call the appropriate class level create format method based on the
# style of this parseable layout.
#
def create_format_method