class NewRelic::Agent::Logging::DecoratingFormatter

This class can be used as the formatter for an existing logger. It decorates log messages with trace and entity metadata, and formats each log messages as a JSON object.

It can be added to a Rails application like this:

require 'newrelic_rpm'

Rails.application.configure do
  config.log_formatter = ::NewRelic::Agent::Logging::DecoratingFormatter.new
end

@api public

Constants

CLOSING_BRACE
COLON
COMMA
ELEMENTS
LOG_LEVEL_ELEMENT
LOG_LEVEL_KEY
LOG_NAME_KEY
MESSAGE_ELEMENT
MESSAGE_KEY
NEWLINE
PROG_NAME_ELEMENT
QUOTE
REPLACEMENT_CHAR
TIMESTAMP_KEY

Public Class Methods

new() click to toggle source
# File lib/new_relic/agent/logging.rb, line 42
def initialize
  Agent.config.register_callback(:app_name) do
    @app_name = nil
  end
end

Public Instance Methods

call(severity, time, progname, msg) click to toggle source
# File lib/new_relic/agent/logging.rb, line 48
def call(severity, time, progname, msg)
  message = +'{'
  ELEMENTS.each do |element|
    args = case element
           when MESSAGE_ELEMENT then [message, msg]
           when LOG_LEVEL_ELEMENT then [message, severity]
           when PROG_NAME_ELEMENT then [message, progname]
           else [message]
    end

    send("add_#{element}", *args)
  end
  message << COMMA
  message << QUOTE << TIMESTAMP_KEY << QUOTE << COLON << (time.to_f * 1000).round.to_s
  message << CLOSING_BRACE << NEWLINE
end
clear_tags!() click to toggle source
# File lib/new_relic/agent/logging.rb, line 65
def clear_tags!
  # No-op; just avoiding issues with act-fluent-logger-rails
end

Private Instance Methods

add_app_name(message) click to toggle source
# File lib/new_relic/agent/logging.rb, line 71
def add_app_name(message)
  return unless app_name

  add_key_value(message, ENTITY_NAME_KEY, app_name)
  message << COMMA
end
add_entity_guid(message) click to toggle source
# File lib/new_relic/agent/logging.rb, line 87
def add_entity_guid(message)
  return unless entity_guid = Agent.config[:entity_guid]

  message << COMMA
  add_key_value(message, ENTITY_GUID_KEY, entity_guid)
end
add_entity_type(message) click to toggle source
# File lib/new_relic/agent/logging.rb, line 78
def add_entity_type(message)
  add_key_value(message, ENTITY_TYPE_KEY, ENTITY_TYPE)
  message << COMMA
end
add_hostname(message) click to toggle source
# File lib/new_relic/agent/logging.rb, line 83
def add_hostname(message)
  add_key_value(message, HOSTNAME_KEY, Hostname.get)
end
add_key_value(message, key, value) click to toggle source
# File lib/new_relic/agent/logging.rb, line 129
def add_key_value(message, key, value)
  message << QUOTE << key << QUOTE << COLON << QUOTE << value << QUOTE
end
add_log_level(message, severity) click to toggle source
# File lib/new_relic/agent/logging.rb, line 114
def add_log_level(message, severity)
  add_key_value(message, LOG_LEVEL_KEY, severity)
end
add_message(message, msg) click to toggle source
# File lib/new_relic/agent/logging.rb, line 108
def add_message(message, msg)
  message << COMMA
  message << QUOTE << MESSAGE_KEY << QUOTE << COLON << escape(msg)
  message << COMMA
end
add_prog_name(message, progname) click to toggle source
# File lib/new_relic/agent/logging.rb, line 118
def add_prog_name(message, progname)
  return unless progname

  message << COMMA
  add_key_value(message, LOG_NAME_KEY, progname)
end
add_span_id(message) click to toggle source
# File lib/new_relic/agent/logging.rb, line 101
def add_span_id(message)
  return unless span_id = Tracer.span_id

  message << COMMA
  add_key_value(message, SPAN_ID_KEY, span_id)
end
add_trace_id(message) click to toggle source
# File lib/new_relic/agent/logging.rb, line 94
def add_trace_id(message)
  return unless trace_id = Tracer.trace_id

  message << COMMA
  add_key_value(message, TRACE_ID_KEY, trace_id)
end
app_name() click to toggle source
# File lib/new_relic/agent/logging.rb, line 125
def app_name
  @app_name ||= Agent.config[:app_name][0]
end
escape(message) click to toggle source
# File lib/new_relic/agent/logging.rb, line 133
def escape(message)
  message = message.to_s unless message.is_a?(String)
  unless message.encoding == Encoding::UTF_8 && message.valid_encoding?
    message = message.encode(
      Encoding::UTF_8,
      invalid: :replace,
      undef: :replace,
      replace: REPLACEMENT_CHAR
    )
  end
  message.to_json
end