Class: SemanticLogger::Formatters::NewRelicLogs

Inherits:
Raw
  • Object
show all
Defined in:
lib/semantic_logger/formatters/new_relic_logs.rb

Overview

Formatter for reporting to NewRelic’s Logger

New Relic gracefully handles (and flattens) any JSON-based logs We construct the JSON and pass it to New Relic for further processing.

Reference

Instance Attribute Summary

Attributes inherited from Raw

#hash, #time_key

Attributes inherited from Base

#filter, #name

Instance Method Summary collapse

Methods inherited from Raw

#application, #duration, #environment, #exception, #file_name_and_line, #host, #level, #message, #metric, #name, #named_tags, #payload, #pid, #tags, #thread_name, #time

Methods inherited from Base

#backtrace, #fast_tag, #level, #level=, #log, #measure, #named_tags, #pop_tags, #push_tags, #should_log?, #silence, #tagged, #tags

Constructor Details

#initialize(**args) ⇒ NewRelicLogs

Returns a new instance of NewRelicLogs.



39
40
41
42
43
44
# File 'lib/semantic_logger/formatters/new_relic_logs.rb', line 39

def initialize(**args)
  args.delete(:time_key)
  args.delete(:time_format)

  super(time_key: :timestamp, time_format: :ms, **args)
end

Instance Method Details

#call(log, logger) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/semantic_logger/formatters/new_relic_logs.rb', line 46

def call(log, logger)
  hash = super

  result = {
    **,
    message:       hash[:message].to_s,
    tags:          hash[:tags],
    metric:        hash[:metric],
    metric_amount: hash[:metric_amount],
    environment:   hash[:environment],
    application:   hash[:application],
    payload:       hash[:payload],
    timestamp:     hash[:timestamp].to_i,
    logger:        {
      name: log.name
    },
    thread:        {
      name: log.thread_name.to_s
    }
  }.compact

  if hash[:duration_ms] || hash[:duration]
    result[:duration] = {
      ms:    hash[:duration_ms],
      human: hash[:duration]
    }.compact
  end

  if hash[:exception]
    result[:error] = {
      message: hash[:exception][:message],
      class:   hash[:exception][:name],
      stack:   hash[:exception][:stack_trace].join("\n")
    }
  end

  if hash[:file]
    result[:file] = {
      name: hash[:file]
    }
  end

  if hash[:line]
    result[:line] = {
      number: hash[:line].to_s
    }
  end

  # NOTE: Any named tags are merged directly into the result
  # unless there are conflicts with other keys. In that
  # case we clearly log this in the NR log entry so it can
  # be easily alerted on.
  if hash[:named_tags].is_a?(Hash)
    result_keys = result.keys.to_set
    named_tag_conflicts = []

    hash[:named_tags].each do |key, value|
      if result_keys.include?(key)
        named_tag_conflicts << key
      else
        result[key] = value
      end
    end

    result[:named_tag_conflicts] = named_tag_conflicts unless named_tag_conflicts.empty?
  end

  result
end