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