Class: NewRelic::Agent::LogEventAggregator

Inherits:
EventAggregator show all
Defined in:
lib/new_relic/agent/log_event_aggregator.rb

Constant Summary collapse

LEVEL_KEY =

Per-message keys

'level'.freeze
MESSAGE_KEY =
'message'.freeze
TIMESTAMP_KEY =
'timestamp'.freeze
PRIORITY_KEY =
'priority'.freeze
LINES =

Metric keys

'Logging/lines'.freeze
DROPPED_METRIC =
'Logging/Forwarding/Dropped'.freeze
SEEN_METRIC =
'Supportability/Logging/Forwarding/Seen'.freeze
SENT_METRIC =
'Supportability/Logging/Forwarding/Sent'.freeze
OVERALL_SUPPORTABILITY_FORMAT =
'Supportability/Logging/Ruby/Logger/%s'.freeze
METRICS_SUPPORTABILITY_FORMAT =
'Supportability/Logging/Metrics/Ruby/%s'.freeze
FORWARDING_SUPPORTABILITY_FORMAT =
'Supportability/Logging/Forwarding/Ruby/%s'.freeze
DECORATING_SUPPORTABILITY_FORMAT =
'Supportability/Logging/LocalDecorating/Ruby/%s'.freeze
MAX_BYTES =

32 * 1024 bytes (32 kibibytes)

32768
OVERALL_ENABLED_KEY =

Config keys

:'application_logging.enabled'
METRICS_ENABLED_KEY =
:'application_logging.metrics.enabled'
FORWARDING_ENABLED_KEY =
:'application_logging.forwarding.enabled'
DECORATING_ENABLED_KEY =
:'application_logging.local_decorating.enabled'
LOG_LEVEL_KEY =
:'application_logging.forwarding.log_level'
CUSTOM_ATTRIBUTES_KEY =
:'application_logging.forwarding.custom_attributes'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from EventAggregator

#after_initialize, buffer_class, capacity_key, enabled_fn, enabled_keys, #has_metadata?, #merge!, named

Constructor Details

#initialize(events) ⇒ LogEventAggregator

Returns a new instance of LogEventAggregator.



45
46
47
48
49
50
51
52
53
54
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 45

def initialize(events)
  super(events)
  @counter_lock = Mutex.new
  @seen = 0
  @seen_by_severity = Hash.new(0)
  @high_security = NewRelic::Agent.config[:high_security]
  @instrumentation_logger_enabled = NewRelic::Agent::Instrumentation::Logger.enabled?
  @attributes = NewRelic::Agent::LogEventAttributes.new
  register_for_done_configuring(events)
end

Instance Attribute Details

#attributesObject (readonly)

Returns the value of attribute attributes.



43
44
45
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 43

def attributes
  @attributes
end

Class Method Details

.payload_to_melt_format(data) ⇒ Object

Because our transmission format (MELT) is different than historical agent payloads, extract the munging here to keep the service focused on the general harvest + transmit instead of the format.

Payload shape matches the publicly documented MELT format. docs.newrelic.com/docs/logs/log-api/introduction-log-api

We have to keep the aggregated payloads in a separate shape, though, to work with the priority sampling buffers



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 137

def self.payload_to_melt_format(data)
  common_attributes = LinkingMetadata.({})

  # To save on unnecessary data transmission, trim the entity.type
  # sent by classic logs-in-context
  common_attributes.delete(ENTITY_TYPE_KEY)

  common_attributes.merge!(NewRelic::Agent.agent.log_event_aggregator.attributes.custom_attributes)

  _, items = data
  payload = [{
    common: {attributes: common_attributes},
    logs: items.map(&:last)
  }]

  return [payload, items.size]
end

Instance Method Details

#add_custom_attributes(custom_attributes) ⇒ Object



124
125
126
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 124

def add_custom_attributes(custom_attributes)
  attributes.add_custom_attributes(custom_attributes)
end

#capacityObject



56
57
58
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 56

def capacity
  @buffer.capacity
end

#create_event(priority, formatted_message, severity) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 107

def create_event(priority, formatted_message, severity)
  formatted_message = truncate_message(formatted_message)

  event = LinkingMetadata.({
    LEVEL_KEY => severity,
    MESSAGE_KEY => formatted_message,
    TIMESTAMP_KEY => Process.clock_gettime(Process::CLOCK_REALTIME) * 1000
  })

  [
    {
      PrioritySampledBuffer::PRIORITY_KEY => priority
    },
    event
  ]
end

#enabled?Boolean

Returns:

  • (Boolean)


169
170
171
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 169

def enabled?
  @enabled && @instrumentation_logger_enabled
end

#harvest!Object



155
156
157
158
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 155

def harvest!
  record_customer_metrics()
  super
end

#record(formatted_message, severity) ⇒ Object



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
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 60

def record(formatted_message, severity)
  return unless enabled?

  severity = 'UNKNOWN' if severity.nil? || severity.empty?

  if NewRelic::Agent.config[METRICS_ENABLED_KEY]
    @counter_lock.synchronize do
      @seen += 1
      @seen_by_severity[severity] += 1
    end
  end

  return if severity_too_low?(severity)
  return if formatted_message.nil? || formatted_message.empty?
  return unless NewRelic::Agent.config[FORWARDING_ENABLED_KEY]
  return if @high_security

  txn = NewRelic::Agent::Transaction.tl_current
  priority = LogPriority.priority_for(txn)

  if txn
    return txn.add_log_event(create_event(priority, formatted_message, severity))
  else
    return @lock.synchronize do
      @buffer.append(priority: priority) do
        create_event(priority, formatted_message, severity)
      end
    end
  end
rescue
  nil
end

#record_batch(txn, logs) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 93

def record_batch(txn, logs)
  # Ensure we have the same shared priority
  priority = LogPriority.priority_for(txn)
  logs.each do |log|
    log.first[PRIORITY_KEY] = priority
  end

  @lock.synchronize do
    logs.each do |log|
      @buffer.append(event: log)
    end
  end
end

#reset!Object



160
161
162
163
164
165
166
167
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 160

def reset!
  @counter_lock.synchronize do
    @seen = 0
    @seen_by_severity.clear
  end

  super
end