-
Notifications
You must be signed in to change notification settings - Fork 600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Logstasher instrumentation #2559
Merged
Merged
Changes from 52 commits
Commits
Show all changes
56 commits
Select commit
Hold shift + click to select a range
867f4c1
Instrumentation skeleton
hannahramadan 82f1f43
Merge branch 'dev' into logstasher_instrumentation
hannahramadan ec7de88
Merge branch 'dev' into logstasher_instrumentation
hannahramadan 5531741
log decorator: support hashes
fallwith 2485d79
log decorator: return early for frozen hashes
fallwith b1f3f0b
Merge pull request #2729 from newrelic/mark_williams
hannahramadan b302925
Add instrumenting methods
hannahramadan 36f0a05
Instrumentation updates
hannahramadan 693a991
Rubocop: spacing
hannahramadan d0ad2d2
Add tests
hannahramadan 5cc4d09
Rubocop
hannahramadan b0816c6
Update lib/new_relic/agent/instrumentation/logstasher/instrumentation.rb
hannahramadan f00a319
Test updates
hannahramadan acda525
test and instrumentation udpates
hannahramadan 4827fec
test updates
hannahramadan 032e67d
Test updates
hannahramadan e0b714b
Merge branch 'dev' into logstasher_instrumentation
hannahramadan f8542b2
Rubocop
hannahramadan fce3e68
Envfile update
hannahramadan 9ccd046
require ostruct
hannahramadan 8b88ba6
Add changelog and version gate
hannahramadan 6ad0e5f
Test updates
hannahramadan c3f3089
rubocop beep beep
hannahramadan ba44298
More tests
hannahramadan 072e97c
metrics enabled test
hannahramadan 20304b0
message change
hannahramadan df672a7
test updates
hannahramadan c8a7d04
test: record nil on kaboom
hannahramadan df447d6
beep beep rubocop
hannahramadan 7462d5e
Apply suggestions from code review
hannahramadan de96a74
Apply suggestions from code review
hannahramadan 4fabc5b
Create shared methods
hannahramadan 229c7d1
Monitoring conditions?
hannahramadan 278c972
Update pin
hannahramadan 45e6bc4
Always capitalize severity level
hannahramadan f689fb7
Don't send empty strings
hannahramadan 84c64b3
Spruce up attributes test
hannahramadan 3546a3c
Upcase severity levels
hannahramadan 6eef9a6
Fix name
hannahramadan 32036e5
Update linking metadata tests
hannahramadan 559ecd4
Small cleanups
hannahramadan 02d09b3
Use initialize value
hannahramadan 29a78c0
Use singletone class
hannahramadan 18ca504
revert initialize changes
hannahramadan 1ab9aa2
remove required file
hannahramadan 1a70059
Use *args
hannahramadan 3168617
All keys are strings
hannahramadan 6dc33a4
revert to_s
hannahramadan fecf021
up ruby version
hannahramadan 07353c7
Trigger ci run
hannahramadan 752c1f2
Merge branch 'dev' into logstasher_instrumentation
hannahramadan c8e2d8e
Update CHANGELOG.md
hannahramadan 9e2fa2d
Add comment
hannahramadan 015d13b
Apply suggestions from code review
hannahramadan 068acc3
add envfile comment
hannahramadan cf27f6c
Use less than 7.1
hannahramadan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# This file is distributed under New Relic's license terms. | ||
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. | ||
# frozen_string_literal: true | ||
|
||
require_relative 'logstasher/instrumentation' | ||
require_relative 'logstasher/chain' | ||
require_relative 'logstasher/prepend' | ||
|
||
DependencyDetection.defer do | ||
named :logstasher | ||
|
||
depends_on do | ||
defined?(LogStasher) && | ||
Gem::Version.new(LogStasher::VERSION) >= Gem::Version.new('1.0.0') && | ||
NewRelic::Agent.config[:'application_logging.enabled'] | ||
end | ||
|
||
executes do | ||
NewRelic::Agent.logger.info('Installing LogStasher instrumentation') | ||
|
||
if use_prepend? | ||
prepend_instrument LogStasher.singleton_class, NewRelic::Agent::Instrumentation::LogStasher::Prepend | ||
else | ||
chain_instrument NewRelic::Agent::Instrumentation::LogStasher::Chain | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# This file is distributed under New Relic's license terms. | ||
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. | ||
# frozen_string_literal: true | ||
|
||
module NewRelic::Agent::Instrumentation | ||
module LogStasher::Chain | ||
def self.instrument! | ||
::LogStasher.singleton_class.class_eval do | ||
include NewRelic::Agent::Instrumentation::LogStasher | ||
|
||
alias_method(:build_logstash_event_without_new_relic, :build_logstash_event) | ||
|
||
def build_logstash_event(*args) | ||
build_logstash_event_with_new_relic(*args) do | ||
build_logstash_event_without_new_relic(*args) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
24 changes: 24 additions & 0 deletions
24
lib/new_relic/agent/instrumentation/logstasher/instrumentation.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# This file is distributed under New Relic's license terms. | ||
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. | ||
# frozen_string_literal: true | ||
|
||
module NewRelic::Agent::Instrumentation | ||
module LogStasher | ||
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name) | ||
|
||
def self.enabled? | ||
NewRelic::Agent.config[:'instrumentation.logstasher'] != 'disabled' | ||
end | ||
|
||
def build_logstash_event_with_new_relic(*args) | ||
logstasher_event = yield | ||
log = logstasher_event.instance_variable_get(:@data) | ||
|
||
::NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME) | ||
::NewRelic::Agent.agent.log_event_aggregator.record_logstasher_event(log) | ||
::NewRelic::Agent::LocalLogDecorator.decorate(log) | ||
|
||
logstasher_event | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# This file is distributed under New Relic's license terms. | ||
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. | ||
# frozen_string_literal: true | ||
|
||
module NewRelic::Agent::Instrumentation | ||
module LogStasher::Prepend | ||
include NewRelic::Agent::Instrumentation::LogStasher | ||
|
||
def build_logstash_event(*args) | ||
build_logstash_event_with_new_relic(*args) { super } | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,8 @@ class LogEventAggregator < EventAggregator | |
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 | ||
LOGGER_SUPPORTABILITY_FORMAT = 'Supportability/Logging/Ruby/Logger/%s'.freeze | ||
LOGSTASHER_SUPPORTABILITY_FORMAT = 'Supportability/Logging/Ruby/LogStasher/%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 | ||
|
@@ -58,38 +59,68 @@ def capacity | |
end | ||
|
||
def record(formatted_message, severity) | ||
return unless enabled? | ||
return unless logger_enabled? | ||
|
||
severity = 'UNKNOWN' if severity.nil? || severity.empty? | ||
increment_event_counters(severity) | ||
|
||
if NewRelic::Agent.config[METRICS_ENABLED_KEY] | ||
@counter_lock.synchronize do | ||
@seen += 1 | ||
@seen_by_severity[severity] += 1 | ||
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 | ||
|
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This block of code lives in a new method, |
||
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) | ||
|
||
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 | ||
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 | ||
|
||
def monitoring_conditions_met?(severity) | ||
!severity_too_low?(severity) && NewRelic::Agent.config[FORWARDING_ENABLED_KEY] && !@high_security | ||
end | ||
|
||
def determine_severity(log) | ||
log['level'] ? log['level'].to_s.upcase : 'UNKNOWN' | ||
end | ||
|
||
def increment_event_counters(severity) | ||
if NewRelic::Agent.config[METRICS_ENABLED_KEY] | ||
@counter_lock.synchronize do | ||
@seen += 1 | ||
@seen_by_severity[severity] += 1 | ||
end | ||
end | ||
hannahramadan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
end | ||
|
||
def record_batch(txn, logs) | ||
# Ensure we have the same shared priority | ||
priority = LogPriority.priority_for(txn) | ||
|
@@ -104,15 +135,17 @@ def record_batch(txn, logs) | |
end | ||
end | ||
|
||
def create_event(priority, formatted_message, severity) | ||
formatted_message = truncate_message(formatted_message) | ||
|
||
event = LinkingMetadata.append_trace_linking_metadata({ | ||
def add_event_metadata(formatted_message, severity) | ||
metadata = { | ||
LEVEL_KEY => severity, | ||
MESSAGE_KEY => formatted_message, | ||
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 | ||
|
||
def create_prioritized_event(priority, event) | ||
[ | ||
{ | ||
PrioritySampledBuffer::PRIORITY_KEY => priority | ||
|
@@ -121,6 +154,31 @@ def create_event(priority, formatted_message, severity) | |
] | ||
end | ||
|
||
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 | ||
|
||
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 | ||
|
||
def add_logstasher_event_attributes(event, log) | ||
log_copy = log.dup | ||
# Delete previously reported attributes | ||
log_copy.delete('message') | ||
log_copy.delete('level') | ||
log_copy.delete('@timestamp') | ||
|
||
event['attributes'] = log_copy | ||
end | ||
|
||
def add_custom_attributes(custom_attributes) | ||
attributes.add_custom_attributes(custom_attributes) | ||
end | ||
|
@@ -166,19 +224,23 @@ def reset! | |
super | ||
end | ||
|
||
def enabled? | ||
def logger_enabled? | ||
@enabled && @instrumentation_logger_enabled | ||
end | ||
|
||
def logstasher_enabled? | ||
@enabled && NewRelic::Agent::Instrumentation::LogStasher.enabled? | ||
fallwith marked this conversation as resolved.
Show resolved
Hide resolved
|
||
end | ||
|
||
private | ||
|
||
# We record once-per-connect metrics for enabled/disabled state at the | ||
# point we consider the configuration stable (i.e. once we've gotten SSC) | ||
def register_for_done_configuring(events) | ||
events.subscribe(:server_source_configuration_added) do | ||
@high_security = NewRelic::Agent.config[:high_security] | ||
|
||
record_configuration_metric(OVERALL_SUPPORTABILITY_FORMAT, OVERALL_ENABLED_KEY) | ||
record_configuration_metric(LOGGER_SUPPORTABILITY_FORMAT, OVERALL_ENABLED_KEY) | ||
record_configuration_metric(LOGSTASHER_SUPPORTABILITY_FORMAT, OVERALL_ENABLED_KEY) | ||
record_configuration_metric(METRICS_SUPPORTABILITY_FORMAT, METRICS_ENABLED_KEY) | ||
record_configuration_metric(FORWARDING_SUPPORTABILITY_FORMAT, FORWARDING_ENABLED_KEY) | ||
record_configuration_metric(DECORATING_SUPPORTABILITY_FORMAT, DECORATING_ENABLED_KEY) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# This file is distributed under New Relic's license terms. | ||
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. | ||
# frozen_string_literal: true | ||
|
||
instrumentation_methods :chain, :prepend | ||
|
||
logstasher_versions = [ | ||
[nil, 2.7] | ||
] | ||
|
||
def gem_list(logstasher_versions = nil) | ||
<<~RB | ||
gem 'logstasher'#{logstasher_versions} | ||
gem 'activesupport', '~> 7.0.0' | ||
fallwith marked this conversation as resolved.
Show resolved
Hide resolved
|
||
RB | ||
end | ||
|
||
create_gemfiles(logstasher_versions) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
--- | ||
development: | ||
error_collector: | ||
enabled: true | ||
apdex_t: 0.5 | ||
monitor_mode: true | ||
license_key: bootstrap_newrelic_admin_license_key_000 | ||
instrumentation: | ||
logstasher: <%= $instrumentation_method %> | ||
app_name: test | ||
log_level: debug | ||
host: 127.0.0.1 | ||
api_host: 127.0.0.1 | ||
transaction_trace: | ||
record_sql: obfuscated | ||
enabled: true | ||
stack_trace_threshold: 0.5 | ||
transaction_threshold: 1.0 | ||
capture_params: false | ||
application_logging: | ||
forwarding: | ||
enabled: true |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few blocks of code were shared by
create_event
andcreate_logstasher_event
. This is an example of a block of code moved into a new method (increment_event_counters
is the name for this)