Class: NewRelic::Agent::LogEventAggregator
Constant Summary
collapse
- LEVEL_KEY =
'level'.freeze
- MESSAGE_KEY =
'message'.freeze
- TIMESTAMP_KEY =
'timestamp'.freeze
- PRIORITY_KEY =
'priority'.freeze
- LINES =
'Logging/lines'.freeze
- DROPPED_METRIC =
'Logging/Forwarding/Dropped'.freeze
- SEEN_METRIC =
'Supportability/Logging/Forwarding/Seen'.freeze
- SENT_METRIC =
'Supportability/Logging/Forwarding/Sent'.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
- LABELS_SUPPORTABILITY_FORMAT =
'Supportability/Logging/Labels/Ruby/%s'.freeze
- SUPPORTED_LOGGING_LIBRARIES =
%w[Logger LogStasher Logging SemanticLogger RailsEventLogger].freeze
- MAX_BYTES =
32 * 1024 bytes (32 kibibytes)
32768
- SKIP_SEMANTIC_LOGGER_VARS =
%w[@level @level_index @message @time @payload].freeze
- SKIP_RAILS_EVENT_KEYS =
%w[message level].freeze
- OVERALL_ENABLED_KEY =
:'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'
- LABELS_ENABLED_KEY =
:'application_logging.forwarding.labels.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
-
.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.
Instance Method Summary
collapse
-
#add_custom_attributes(custom_attributes) ⇒ Object
-
#add_event_metadata(formatted_message, severity) ⇒ Object
-
#add_logging_event_attributes(event, log, mdc_data) ⇒ Object
-
#add_logstasher_event_attributes(event, log) ⇒ Object
-
#add_mdc_data_to_event(event, mdc_data) ⇒ Object
-
#add_semantic_logger_event_attributes(event, log) ⇒ Object
-
#capacity ⇒ Object
-
#create_event(priority, formatted_message, severity) ⇒ Object
-
#create_logging_event(priority, severity, log, mdc_data) ⇒ Object
-
#create_logstasher_event(priority, severity, log) ⇒ Object
-
#create_prioritized_event(priority, event) ⇒ Object
-
#create_semantic_logger_event(priority, severity, log) ⇒ Object
-
#determine_severity(log) ⇒ Object
-
#harvest! ⇒ Object
-
#increment_event_counters(severity) ⇒ Object
-
#initialize(events) ⇒ LogEventAggregator
constructor
A new instance of LogEventAggregator.
-
#labels ⇒ Object
-
#logger_enabled? ⇒ Boolean
-
#logging_enabled? ⇒ Boolean
-
#logstasher_enabled? ⇒ Boolean
-
#monitoring_conditions_met?(severity) ⇒ Boolean
-
#rails_event_logger_enabled? ⇒ Boolean
-
#record(formatted_message, severity) ⇒ Object
-
#record_batch(txn, logs) ⇒ Object
-
#record_logging_event(log, mdc_data) ⇒ Object
-
#record_logstasher_event(log) ⇒ Object
-
#record_rails_event(event) ⇒ Object
-
#record_semantic_logger(log) ⇒ Object
-
#reset! ⇒ Object
-
#semantic_logger_enabled? ⇒ Boolean
#after_initialize, buffer_class, capacity_key, #enabled?, enabled_fn, enabled_keys, #has_metadata?, #merge!, named
Constructor Details
Returns a new instance of LogEventAggregator.
Instance Attribute Details
#attributes ⇒ Object
Returns the value of attribute attributes.
47
48
49
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 47
def attributes
@attributes
end
|
Class Method Details
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
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 319
def self.payload_to_melt_format(data)
common_attributes = LinkingMetadata.append_service_linking_metadata({})
common_attributes.delete(ENTITY_TYPE_KEY)
aggregator = NewRelic::Agent.agent.log_event_aggregator
common_attributes.merge!(aggregator.attributes.custom_attributes)
common_attributes.merge!(aggregator.labels)
_, 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
302
303
304
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 302
def add_custom_attributes(custom_attributes)
attributes.add_custom_attributes(custom_attributes)
end
|
218
219
220
221
222
223
224
225
226
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 218
def add_event_metadata(formatted_message, severity)
metadata = {
LEVEL_KEY => severity,
TIMESTAMP_KEY => Process.clock_gettime(Process::CLOCK_REALTIME) * 1000
}
metadata[MESSAGE_KEY] = formatted_message unless formatted_message.nil?
LinkingMetadata.append_trace_linking_metadata(metadata)
end
|
#add_logging_event_attributes(event, log, mdc_data) ⇒ Object
270
271
272
273
274
275
276
277
278
279
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 270
def add_logging_event_attributes(event, log, mdc_data)
event['level_number'] = log.level event['file'] = log.file unless log.file.empty?
event['line'] = log.line unless (log.line.respond_to?(:empty?) && log.line.empty?) || log.line.nil?
event['method_name'] = log.method_name unless log.method_name.nil? || log.method_name.empty?
event['logger'] = log.logger unless log.logger.empty?
add_mdc_data_to_event(event, mdc_data) if !mdc_data.empty?
event
end
|
#add_logstasher_event_attributes(event, log) ⇒ Object
252
253
254
255
256
257
258
259
260
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 252
def add_logstasher_event_attributes(event, log)
log_copy = log.dup
log_copy.delete('message')
log_copy.delete('level')
log_copy.delete('@timestamp')
event['attributes'] = log_copy
end
|
#add_mdc_data_to_event(event, mdc_data) ⇒ Object
294
295
296
297
298
299
300
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 294
def add_mdc_data_to_event(event, mdc_data)
mdc_data.each do |key, value|
event["context.mdc.#{key}"] = value
end
rescue => e
NewRelic::Agent.logger.debug("Failed to add Logging MDC data to event: #{e.message}")
end
|
#add_semantic_logger_event_attributes(event, log) ⇒ Object
289
290
291
292
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 289
def add_semantic_logger_event_attributes(event, log)
add_payload_attributes(event, log)
add_semantic_logger_instance_variables(event, log)
end
|
#capacity ⇒ Object
61
62
63
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 61
def capacity
@buffer.capacity
end
|
#create_event(priority, formatted_message, severity) ⇒ Object
237
238
239
240
241
242
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 237
def create_event(priority, formatted_message, severity)
formatted_message = truncate_message(formatted_message)
event = add_event_metadata(formatted_message, severity)
create_prioritized_event(priority, event)
end
|
#create_logging_event(priority, severity, log, mdc_data) ⇒ Object
262
263
264
265
266
267
268
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 262
def create_logging_event(priority, severity, log, mdc_data)
formatted_message = truncate_message(log.data)
event = add_event_metadata(formatted_message, severity)
add_logging_event_attributes(event, log, mdc_data)
create_prioritized_event(priority, event)
end
|
#create_logstasher_event(priority, severity, log) ⇒ Object
244
245
246
247
248
249
250
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 244
def create_logstasher_event(priority, severity, log)
formatted_message = log['message'] ? truncate_message(log['message']) : nil
event = add_event_metadata(formatted_message, severity)
add_logstasher_event_attributes(event, log)
create_prioritized_event(priority, event)
end
|
#create_prioritized_event(priority, event) ⇒ Object
228
229
230
231
232
233
234
235
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 228
def create_prioritized_event(priority, event)
[
{
PrioritySampledBuffer::PRIORITY_KEY => priority
},
event
]
end
|
#create_semantic_logger_event(priority, severity, log) ⇒ Object
281
282
283
284
285
286
287
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 281
def create_semantic_logger_event(priority, severity, log)
formatted_message = truncate_message(log.message)
event = add_event_metadata(formatted_message, severity)
add_semantic_logger_event_attributes(event, log)
create_prioritized_event(priority, event)
end
|
#determine_severity(log) ⇒ Object
188
189
190
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 188
def determine_severity(log)
log['level'] ? log['level'].to_s.upcase : 'UNKNOWN'
end
|
#harvest! ⇒ Object
338
339
340
341
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 338
def harvest!
record_customer_metrics()
super
end
|
#increment_event_counters(severity) ⇒ Object
192
193
194
195
196
197
198
199
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 192
def increment_event_counters(severity)
return unless NewRelic::Agent.config[METRICS_ENABLED_KEY]
@counter_lock.synchronize do
@seen += 1
@seen_by_severity[severity] += 1
end
end
|
#labels ⇒ Object
306
307
308
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 306
def labels
@labels ||= create_labels
end
|
#logger_enabled? ⇒ Boolean
352
353
354
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 352
def logger_enabled?
application_logging_and_instrumentation_enabled?(@instrumentation_logger_enabled)
end
|
#logging_enabled? ⇒ Boolean
#logstasher_enabled? ⇒ Boolean
#monitoring_conditions_met?(severity) ⇒ Boolean
184
185
186
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 184
def monitoring_conditions_met?(severity)
!severity_too_low?(severity) && NewRelic::Agent.config[FORWARDING_ENABLED_KEY] && !@high_security
end
|
#rails_event_logger_enabled? ⇒ Boolean
#record(formatted_message, severity) ⇒ Object
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 65
def record(formatted_message, severity)
return unless logger_enabled?
severity = 'UNKNOWN' if severity.nil? || severity.empty?
increment_event_counters(severity)
return if formatted_message.nil? || formatted_message.empty?
return unless monitoring_conditions_met?(severity)
txn = NewRelic::Agent::Transaction.tl_current
priority = LogPriority.priority_for(txn)
return txn.add_log_event(create_event(priority, formatted_message, severity)) if txn
@lock.synchronize do
@buffer.append(priority: priority) do
create_event(priority, formatted_message, severity)
end
end
rescue
nil
end
|
#record_batch(txn, logs) ⇒ Object
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 201
def record_batch(txn, logs)
priority = LogPriority.priority_for(txn)
txn_attrs = txn.log_attributes&.custom_attributes
logs.each do |log|
log.first[PRIORITY_KEY] = priority
log.last.merge!(txn_attrs) if txn_attrs && !txn_attrs.empty?
end
@lock.synchronize do
logs.each do |log|
@buffer.append(event: log)
end
end
end
|
#record_logging_event(log, mdc_data) ⇒ Object
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 114
def record_logging_event(log, mdc_data)
return unless logging_enabled?
return if log.data.nil? || log.data.empty?
severity = ::Logging::LNAMES[log.level] || 'UNKNOWN'
increment_event_counters(severity)
return unless monitoring_conditions_met?(severity)
txn = NewRelic::Agent::Transaction.tl_current
priority = LogPriority.priority_for(txn)
return txn.add_log_event(create_logging_event(priority, severity, log, mdc_data)) if txn
@lock.synchronize do
@buffer.append(priority: priority) do
create_logging_event(priority, severity, log, mdc_data)
end
end
rescue
nil
end
|
#record_logstasher_event(log) ⇒ Object
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
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 88
def record_logstasher_event(log)
return unless logstasher_enabled?
return if log.key?('message') && (log['message'].nil? || log['message'].empty?)
severity = determine_severity(log)
increment_event_counters(severity)
return unless monitoring_conditions_met?(severity)
txn = NewRelic::Agent::Transaction.tl_current
priority = LogPriority.priority_for(txn)
return txn.add_log_event(create_logstasher_event(priority, severity, log)) if txn
@lock.synchronize do
@buffer.append(priority: priority) do
create_logstasher_event(priority, severity, log)
end
end
rescue
nil
end
|
#record_rails_event(event) ⇒ Object
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 160
def record_rails_event(event)
return unless rails_event_logger_enabled?
payload = event[:payload] || {}
severity = determine_rails_event_severity(payload)
increment_event_counters(severity)
return unless monitoring_conditions_met?(severity)
txn = NewRelic::Agent::Transaction.tl_current
priority = LogPriority.priority_for(txn)
return txn.add_log_event(create_rails_event_log(priority, severity, event)) if txn
@lock.synchronize do
@buffer.append(priority: priority) do
create_rails_event_log(priority, severity, event)
end
end
rescue
nil
end
|
#record_semantic_logger(log) ⇒ Object
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 137
def record_semantic_logger(log)
return unless semantic_logger_enabled?
return if log.message.nil? || log.message.empty?
severity = log.level.to_s.upcase
increment_event_counters(severity)
return unless monitoring_conditions_met?(severity)
txn = NewRelic::Agent::Transaction.tl_current
priority = LogPriority.priority_for(txn)
return txn.add_log_event(create_semantic_logger_event(priority, severity, log)) if txn
@lock.synchronize do
@buffer.append(priority: priority) do
create_semantic_logger_event(priority, severity, log)
end
end
rescue
nil
end
|
#reset! ⇒ Object
343
344
345
346
347
348
349
350
|
# File 'lib/new_relic/agent/log_event_aggregator.rb', line 343
def reset!
@counter_lock.synchronize do
@seen = 0
@seen_by_severity.clear
end
super
end
|
#semantic_logger_enabled? ⇒ Boolean