lib/semantic_logger/formatters/logfmt.rb in semantic_logger-4.8.2 vs lib/semantic_logger/formatters/logfmt.rb in semantic_logger-4.9.0

- old
+ new

@@ -1,9 +1,24 @@ require "json" module SemanticLogger module Formatters + # Produces logfmt formatted messages + # + # The following fields are extracted from the raw log and included in the formatted message: + # :timestamp, :level, :name, :message, :duration, :tags, :named_tags + # + # E.g. + # timestamp="2020-07-20T08:32:05.375276Z" level=info name="DefaultTest" base="breakfast" spaces="second breakfast" double_quotes="\"elevensies\"" single_quotes="'lunch'" tag="success" + # + # All timestamps are ISO8601 formatteed + # All user supplied values are escaped and surrounded by double quotes to avoid ambiguious message delimeters + # `tags` are treated as keys with boolean values. Tag names are not formatted or validated, ensure you use valid logfmt format for tag names. + # `named_tags` are flattened are merged into the top level message field. Any conflicting fields are overridden. + # `payload` values take precedence over `tags` and `named_tags`. Any conflicting fields are overridden. + # + # Futher Reading https://brandur.org/logfmt class Logfmt < Raw def initialize(time_format: :iso_8601, time_key: :timestamp, **args) super(time_format: time_format, time_key: time_key, **args) end @@ -14,17 +29,26 @@ end private def raw_to_logfmt - @parsed = @raw.slice(:timestamp, :level, :name, :message, :duration).merge tag: "success" + @parsed = @raw.slice(time_key, :level, :name, :message, :duration).merge(tag: "success") + handle_tags handle_payload handle_exception flatten_log end + def handle_tags + tags = @raw.fetch(:tags){ [] } + .each_with_object({}){ |tag, accum| accum[tag] = true } + + @parsed = @parsed.merge(tags) + .merge(@raw.fetch(:named_tags){ {} }) + end + def handle_payload return unless @raw.key? :payload @parsed = @parsed.merge(@raw[:payload]) end @@ -36,19 +60,13 @@ @parsed = @parsed.merge(@raw[:exception]) end def flatten_log flattened = @parsed.map do |key, value| - "#{key}=#{parse_value(value)}" + "#{key}=#{value.to_json}" end flattened.join(" ") - end - - def parse_value(value) - return value.to_json if value.instance_of? String - - value end end end end