class Loga::Formatters::GELFFormatter

Constants

DEFAULT_TYPE
GELF_VERSION
SYSLOG_LEVEL_MAPPING

Public Class Methods

new(opts) click to toggle source
# File lib/loga/formatters/gelf_formatter.rb, line 20
def initialize(opts)
  @service_name    = opts.fetch(:service_name)
  @service_version = opts.fetch(:service_version)
  @host            = opts.fetch(:host)
end

Public Instance Methods

call(severity, time, _progname, message) click to toggle source
# File lib/loga/formatters/gelf_formatter.rb, line 26
def call(severity, time, _progname, message)
  event = build_event(time, message)
  payload = format_additional_fields(event.data)

  payload[:short_message] = event.message
  payload[:timestamp]     = compute_timestamp(event.timestamp)
  payload[:host]          = @host
  payload[:level]         = compute_level(severity)
  payload[:version]       = GELF_VERSION

  "#{payload.to_json}\n"
end

Private Instance Methods

build_event(time, message) click to toggle source
# File lib/loga/formatters/gelf_formatter.rb, line 41
def build_event(time, message)
  event = case message
          when Loga::Event
            message
          else
            Loga::Event.new(message: message)
          end

  event.timestamp ||= time
  # Overwrite sidekiq_context data anything manually specified
  event.data = sidekiq_context.merge!(event.data || {})
  event.data.tap do |hash|
    hash.merge! compute_exception(event.exception)
    hash.merge! compute_type(event.type)
    # Overwrite hash with Loga's additional fields
    hash.merge! loga_additional_fields
  end
  event
end
compute_exception(exception) click to toggle source
# File lib/loga/formatters/gelf_formatter.rb, line 81
def compute_exception(exception)
  return {} unless exception
  {
    exception: {
      klass:     exception.class.to_s,
      message:   exception.message,
      backtrace: exception.backtrace.first(10).join("\n"),
    },
  }
end
compute_level(severity) click to toggle source
# File lib/loga/formatters/gelf_formatter.rb, line 65
def compute_level(severity)
  SYSLOG_LEVEL_MAPPING[severity]
end
compute_timestamp(timestamp) click to toggle source
# File lib/loga/formatters/gelf_formatter.rb, line 61
def compute_timestamp(timestamp)
  (timestamp.to_f * 1000).floor / 1000.0
end
compute_type(type) click to toggle source
# File lib/loga/formatters/gelf_formatter.rb, line 92
def compute_type(type)
  type ? { type: type } : {}
end
format_additional_fields(fields) click to toggle source
# File lib/loga/formatters/gelf_formatter.rb, line 69
def format_additional_fields(fields)
  fields.each_with_object({}) do |(main_key, values), hash|
    if values.is_a?(Hash)
      values.each do |sub_key, sub_values|
        hash["_#{main_key}.#{sub_key}"] = sub_values
      end
    else
      hash["_#{main_key}"] = values
    end
  end
end
loga_additional_fields() click to toggle source
# File lib/loga/formatters/gelf_formatter.rb, line 96
def loga_additional_fields
  {
    service: {
      name:    @service_name,
      version: @service_version,
    },
    tags: current_tags.join(' '),
  }
end
sidekiq_context() click to toggle source
# File lib/loga/formatters/gelf_formatter.rb, line 106
def sidekiq_context
  return {} unless defined?(::Sidekiq::Context)

  c = ::Sidekiq::Context.current

  # The context usually holds :class and :jid. :elapsed is added when the job ends
  data = c.dup
  if data.key?(:elapsed)
    data[:duration] = data[:elapsed].to_f
    data.delete(:elapsed)
  end
  data
end