newrelic_rpm 9.11.0 → 9.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +112 -0
  3. data/README.md +16 -20
  4. data/lib/new_relic/agent/agent_logger.rb +1 -0
  5. data/lib/new_relic/agent/configuration/default_source.rb +136 -5
  6. data/lib/new_relic/agent/configuration/manager.rb +8 -0
  7. data/lib/new_relic/agent/database/obfuscator.rb +1 -0
  8. data/lib/new_relic/agent/instrumentation/active_merchant.rb +0 -13
  9. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +14 -0
  10. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +0 -19
  11. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +1 -1
  12. data/lib/new_relic/agent/instrumentation/excon.rb +0 -16
  13. data/lib/new_relic/agent/instrumentation/grape.rb +3 -1
  14. data/lib/new_relic/agent/instrumentation/logstasher/chain.rb +21 -0
  15. data/lib/new_relic/agent/instrumentation/logstasher/instrumentation.rb +24 -0
  16. data/lib/new_relic/agent/instrumentation/logstasher/prepend.rb +13 -0
  17. data/lib/new_relic/agent/instrumentation/logstasher.rb +27 -0
  18. data/lib/new_relic/agent/instrumentation/opensearch/chain.rb +21 -0
  19. data/lib/new_relic/agent/instrumentation/opensearch/instrumentation.rb +66 -0
  20. data/lib/new_relic/agent/instrumentation/opensearch/prepend.rb +13 -0
  21. data/lib/new_relic/agent/instrumentation/opensearch.rb +25 -0
  22. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +3 -0
  23. data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +9 -5
  24. data/lib/new_relic/agent/instrumentation/redis/cluster_middleware.rb +26 -0
  25. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +14 -11
  26. data/lib/new_relic/agent/instrumentation/redis/middleware.rb +3 -0
  27. data/lib/new_relic/agent/instrumentation/redis.rb +11 -4
  28. data/lib/new_relic/agent/instrumentation/sidekiq.rb +0 -14
  29. data/lib/new_relic/agent/instrumentation/sinatra.rb +0 -13
  30. data/lib/new_relic/agent/local_log_decorator.rb +8 -1
  31. data/lib/new_relic/agent/log_event_aggregator.rb +91 -26
  32. data/lib/new_relic/agent/serverless_handler.rb +241 -12
  33. data/lib/new_relic/agent/serverless_handler_event_sources.json +155 -0
  34. data/lib/new_relic/agent/serverless_handler_event_sources.rb +49 -0
  35. data/lib/new_relic/agent/system_info.rb +14 -0
  36. data/lib/new_relic/agent/transaction/trace_context.rb +1 -1
  37. data/lib/new_relic/control/frameworks/grape.rb +14 -0
  38. data/lib/new_relic/control/frameworks/padrino.rb +14 -0
  39. data/lib/new_relic/control/frameworks/rails4.rb +4 -2
  40. data/lib/new_relic/control/instance_methods.rb +1 -0
  41. data/lib/new_relic/control/private_instance_methods.rb +4 -0
  42. data/lib/new_relic/control/security_interface.rb +57 -0
  43. data/lib/new_relic/control.rb +1 -1
  44. data/lib/new_relic/environment_report.rb +6 -2
  45. data/lib/new_relic/language_support.rb +7 -1
  46. data/lib/new_relic/local_environment.rb +1 -4
  47. data/lib/new_relic/rack/browser_monitoring.rb +11 -7
  48. data/lib/new_relic/version.rb +1 -1
  49. data/lib/tasks/config.rake +5 -2
  50. data/lib/tasks/helpers/config.html.erb +1 -1
  51. data/lib/tasks/helpers/format.rb +1 -1
  52. data/lib/tasks/helpers/newrelicyml.rb +76 -13
  53. data/lib/tasks/instrumentation_generator/instrumentation.thor +1 -0
  54. data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +3 -3
  55. data/newrelic.yml +209 -137
  56. data/test/agent_helper.rb +9 -0
  57. metadata +16 -2
@@ -102,7 +102,7 @@ module NewRelic::Agent::Instrumentation
102
102
  end
103
103
 
104
104
  def nr_cluster_name
105
- return @nr_cluster_name if @nr_cluster_name
105
+ return @nr_cluster_name if defined?(@nr_cluster_name)
106
106
  return if nr_hosts.empty?
107
107
 
108
108
  NewRelic::Agent.disable_all_tracing do
@@ -33,22 +33,6 @@ DependencyDetection.defer do
33
33
  end
34
34
  end
35
35
 
36
- executes do
37
- next unless Gem::Version.new(Excon::VERSION) < Gem::Version.new('0.56.0')
38
-
39
- deprecation_msg = 'Instrumentation for Excon versions below 0.56.0 is deprecated.' \
40
- 'They will stop being monitored in version 9.0.0. ' \
41
- 'Please upgrade your Excon version to continue receiving full support. '
42
-
43
- NewRelic::Agent.logger.log_once(
44
- :warn,
45
- :deprecated_excon_version,
46
- deprecation_msg
47
- )
48
-
49
- NewRelic::Agent.record_metric('Supportability/Deprecated/Excon', 1)
50
- end
51
-
52
36
  def install_excon_instrumentation(excon_version)
53
37
  require 'new_relic/agent/distributed_tracing/cross_app_tracing'
54
38
  require 'new_relic/agent/http_clients/excon_wrappers'
@@ -19,7 +19,9 @@ DependencyDetection.defer do
19
19
 
20
20
  depends_on do
21
21
  begin
22
- if defined?(Bundler) && Bundler.rubygems.all_specs.map(&:name).include?('newrelic-grape')
22
+ if defined?(Bundler) &&
23
+ ((Gem::Version.new(Bundler::VERSION) >= Gem::Version.new('2.0.0') && Bundler.rubygems.installed_specs.map(&:name).include?('newrelic-grape')) ||
24
+ Bundler.rubygems.all_specs.map(&:name).include?('newrelic-grape'))
23
25
  NewRelic::Agent.logger.info('Not installing New Relic supported Grape instrumentation because the third party newrelic-grape gem is present')
24
26
  false
25
27
  else
@@ -0,0 +1,21 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module LogStasher::Chain
7
+ def self.instrument!
8
+ ::LogStasher.singleton_class.class_eval do
9
+ include NewRelic::Agent::Instrumentation::LogStasher
10
+
11
+ alias_method(:build_logstash_event_without_new_relic, :build_logstash_event)
12
+
13
+ def build_logstash_event(*args)
14
+ build_logstash_event_with_new_relic(*args) do
15
+ build_logstash_event_without_new_relic(*args)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module LogStasher
7
+ INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
8
+
9
+ def self.enabled?
10
+ NewRelic::Agent.config[:'instrumentation.logstasher'] != 'disabled'
11
+ end
12
+
13
+ def build_logstash_event_with_new_relic(*args)
14
+ logstasher_event = yield
15
+ log = logstasher_event.instance_variable_get(:@data)
16
+
17
+ ::NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
18
+ ::NewRelic::Agent.agent.log_event_aggregator.record_logstasher_event(log)
19
+ ::NewRelic::Agent::LocalLogDecorator.decorate(log)
20
+
21
+ logstasher_event
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module LogStasher::Prepend
7
+ include NewRelic::Agent::Instrumentation::LogStasher
8
+
9
+ def build_logstash_event(*args)
10
+ build_logstash_event_with_new_relic(*args) { super }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require_relative 'logstasher/instrumentation'
6
+ require_relative 'logstasher/chain'
7
+ require_relative 'logstasher/prepend'
8
+
9
+ DependencyDetection.defer do
10
+ named :logstasher
11
+
12
+ depends_on do
13
+ defined?(LogStasher) &&
14
+ Gem::Version.new(LogStasher::VERSION) >= Gem::Version.new('1.0.0') &&
15
+ NewRelic::Agent.config[:'application_logging.enabled']
16
+ end
17
+
18
+ executes do
19
+ NewRelic::Agent.logger.info('Installing LogStasher instrumentation')
20
+
21
+ if use_prepend?
22
+ prepend_instrument LogStasher.singleton_class, NewRelic::Agent::Instrumentation::LogStasher::Prepend
23
+ else
24
+ chain_instrument NewRelic::Agent::Instrumentation::LogStasher::Chain
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module OpenSearch::Chain
7
+ def self.instrument!
8
+ ::OpenSearch::Transport::Client.class_eval do
9
+ include NewRelic::Agent::Instrumentation::OpenSearch
10
+
11
+ alias_method(:perform_request_without_tracing, :perform_request)
12
+
13
+ def perform_request(*args)
14
+ perform_request_with_tracing(*args) do
15
+ perform_request_without_tracing(*args)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,66 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module OpenSearch
7
+ PRODUCT_NAME = 'OpenSearch'
8
+ OPERATION = 'perform_request'
9
+ OPERATION_PATTERN = %r{/lib/opensearch/api/(?!.+#{OPERATION})}
10
+ INSTANCE_METHOD_PATTERN = /:in (?:`|')(?:.+#)?([^']+)'\z/
11
+ INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
12
+
13
+ def perform_request_with_tracing(_method, _path, params = NewRelic::EMPTY_HASH, body = nil, _headers = nil, _opts = nil, &_block)
14
+ return yield unless NewRelic::Agent::Tracer.tracing_enabled?
15
+
16
+ segment = NewRelic::Agent::Tracer.start_datastore_segment(
17
+ product: PRODUCT_NAME,
18
+ operation: nr_operation || OPERATION,
19
+ host: nr_hosts[:host],
20
+ port_path_or_id: nr_hosts[:port],
21
+ database_name: nr_cluster_name
22
+ )
23
+ begin
24
+ NewRelic::Agent::Tracer.capture_segment_error(segment) { yield }
25
+ ensure
26
+ if segment
27
+ segment.notice_nosql_statement(nr_reported_query(body || params))
28
+ segment.finish
29
+ end
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ # See Elasticsearch instrumentation for explanation on Ruby 3.4 changes to match instance method
36
+ def nr_operation
37
+ location = caller_locations.detect { |loc| loc.to_s.match?(OPERATION_PATTERN) }
38
+ return unless location && location.to_s =~ INSTANCE_METHOD_PATTERN
39
+
40
+ Regexp.last_match(1)
41
+ end
42
+
43
+ def nr_reported_query(query)
44
+ return unless NewRelic::Agent.config[:'opensearch.capture_queries']
45
+ return query unless NewRelic::Agent.config[:'opensearch.obfuscate_queries']
46
+
47
+ NewRelic::Agent::Datastores::NosqlObfuscator.obfuscate_statement(query)
48
+ end
49
+
50
+ def nr_cluster_name
51
+ return @nr_cluster_name if defined?(@nr_cluster_name)
52
+ return if nr_hosts.empty?
53
+
54
+ NewRelic::Agent.disable_all_tracing do
55
+ @nr_cluster_name ||= perform_request('GET', '/').body['cluster_name']
56
+ end
57
+ rescue StandardError => e
58
+ NewRelic::Agent.logger.error('Failed to get cluster name for OpenSearch', e)
59
+ nil
60
+ end
61
+
62
+ def nr_hosts
63
+ @nr_hosts ||= (transport.hosts.first || NewRelic::EMPTY_HASH)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,13 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module OpenSearch::Prepend
7
+ include NewRelic::Agent::Instrumentation::OpenSearch
8
+
9
+ def perform_request(*args)
10
+ perform_request_with_tracing(*args) { super }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require_relative 'opensearch/instrumentation'
6
+ require_relative 'opensearch/chain'
7
+ require_relative 'opensearch/prepend'
8
+
9
+ DependencyDetection.defer do
10
+ named :opensearch
11
+
12
+ depends_on do
13
+ defined?(OpenSearch)
14
+ end
15
+
16
+ executes do
17
+ NewRelic::Agent.logger.info('Installing opensearch-ruby instrumentation')
18
+
19
+ if use_prepend?
20
+ prepend_instrument OpenSearch::Transport::Client, NewRelic::Agent::Instrumentation::OpenSearch::Prepend
21
+ else
22
+ chain_instrument NewRelic::Agent::Instrumentation::OpenSearch::Chain
23
+ end
24
+ end
25
+ end
@@ -13,6 +13,7 @@ module NewRelic
13
13
  attr_accessor :_nr_deferred_detection_ran
14
14
  end
15
15
  builder_class._nr_deferred_detection_ran = false
16
+ NewRelic::Control::SecurityInterface.instance.wait = true
16
17
  end
17
18
 
18
19
  def deferred_dependency_check
@@ -21,6 +22,8 @@ module NewRelic
21
22
  NewRelic::Agent.logger.info('Doing deferred dependency-detection before Rack startup')
22
23
  DependencyDetection.detect!
23
24
  self.class._nr_deferred_detection_ran = true
25
+ NewRelic::Control::SecurityInterface.instance.wait = false
26
+ NewRelic::Control::SecurityInterface.instance.init_agent
24
27
  end
25
28
 
26
29
  def check_for_late_instrumentation(app)
@@ -32,15 +32,19 @@ DependencyDetection.defer do
32
32
  NewRelic::Agent::Instrumentation::ActionControllerSubscriber \
33
33
  .subscribe(/^process_action.action_controller$/)
34
34
 
35
- subs = %w[send_file
35
+ subs = %w[exist_fragment?
36
+ expire_fragment
37
+ halted_callback
38
+ read_fragment
39
+ redirect_to
36
40
  send_data
41
+ send_file
37
42
  send_stream
38
- redirect_to
39
- halted_callback
40
- unpermitted_parameters]
43
+ write_fragment
44
+ unpermitted_parameters].map { |s| Regexp.escape(s) }
41
45
 
42
46
  # have to double escape period because its going from string -> regex
43
47
  NewRelic::Agent::Instrumentation::ActionControllerOtherSubscriber \
44
- .subscribe(Regexp.new("^(#{subs.join('|')})\\.action_controller$"))
48
+ .subscribe(Regexp.new("^(?:#{subs.join('|')})\\.action_controller$"))
45
49
  end
46
50
  end
@@ -0,0 +1,26 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module RedisClient
7
+ module ClusterMiddleware
8
+ include NewRelic::Agent::Instrumentation::Redis
9
+
10
+ # Until we decide to move our Redis instrumentation entirely off patches
11
+ # keep the middleware instrumentation for the call and connect methods
12
+ # limited to the redis-clustering instrumentation.
13
+ #
14
+ # Redis's middleware option does not capture errors as high in the stack
15
+ # as our patches. Leaving the patches for call and connect on the main
16
+ # Redis gem limits the feature disparity our customers experience.
17
+ def call(*args, &block)
18
+ call_with_tracing(args[0]) { super }
19
+ end
20
+
21
+ def connect(*args, &block)
22
+ connect_with_tracing { super }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -9,14 +9,14 @@ module NewRelic::Agent::Instrumentation
9
9
  INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
10
10
 
11
11
  def connect_with_tracing
12
- with_tracing(Constants::CONNECT, database: db) { yield }
12
+ with_tracing(Constants::CONNECT, database: _nr_db) { yield }
13
13
  end
14
14
 
15
15
  def call_with_tracing(command, &block)
16
16
  operation = command[0]
17
17
  statement = ::NewRelic::Agent::Datastores::Redis.format_command(command)
18
18
 
19
- with_tracing(operation, statement: statement, database: db) { yield }
19
+ with_tracing(operation, statement: statement, database: _nr_db) { yield }
20
20
  end
21
21
 
22
22
  # Used for Redis 4.x and 3.x
@@ -24,22 +24,15 @@ module NewRelic::Agent::Instrumentation
24
24
  operation = pipeline.is_a?(::Redis::Pipeline::Multi) ? Constants::MULTI_OPERATION : Constants::PIPELINE_OPERATION
25
25
  statement = ::NewRelic::Agent::Datastores::Redis.format_pipeline_commands(pipeline.commands)
26
26
 
27
- with_tracing(operation, statement: statement, database: db) { yield }
27
+ with_tracing(operation, statement: statement, database: _nr_db) { yield }
28
28
  end
29
29
 
30
30
  # Used for Redis 5.x+
31
31
  def call_pipelined_with_tracing(pipeline)
32
- db = begin
33
- _nr_redis_client_config.db
34
- rescue StandardError => e
35
- NewRelic::Agent.logger.error("Failed to determine configured Redis db value: #{e.class} - #{e.message}")
36
- nil
37
- end
38
-
39
32
  operation = pipeline.flatten.include?('MULTI') ? Constants::MULTI_OPERATION : Constants::PIPELINE_OPERATION
40
33
  statement = ::NewRelic::Agent::Datastores::Redis.format_pipeline_commands(pipeline)
41
34
 
42
- with_tracing(operation, statement: statement, database: db) { yield }
35
+ with_tracing(operation, statement: statement, database: _nr_db) { yield }
43
36
  end
44
37
 
45
38
  private
@@ -94,5 +87,15 @@ module NewRelic::Agent::Instrumentation
94
87
  config
95
88
  end
96
89
  end
90
+
91
+ def _nr_db
92
+ # db is a method on the Redis client in versions < 5.x
93
+ return db if respond_to?(:db)
94
+ # db is accessible through the RedisClient::Config object in versions > 5.x
95
+ return _nr_redis_client_config.db if _nr_redis_client_config.respond_to?(:db)
96
+ rescue StandardError => e
97
+ NewRelic::Agent.logger.debug("Failed to determine configured Redis db value: #{e.class} - #{e.message}")
98
+ nil
99
+ end
97
100
  end
98
101
  end
@@ -6,6 +6,9 @@ module NewRelic::Agent::Instrumentation
6
6
  module RedisClient
7
7
  module Middleware
8
8
  # This module is used to instrument Redis 5.x+
9
+ #
10
+ # It only instruments call_pipelined because connect and call are accessed
11
+ # too late in the stack to capture all errors
9
12
  include NewRelic::Agent::Instrumentation::Redis
10
13
 
11
14
  def call_pipelined(*args, &block)
@@ -10,6 +10,7 @@ require_relative 'redis/chain'
10
10
  require_relative 'redis/constants'
11
11
  require_relative 'redis/prepend'
12
12
  require_relative 'redis/middleware'
13
+ require_relative 'redis/cluster_middleware'
13
14
 
14
15
  DependencyDetection.defer do
15
16
  # Why not :redis? newrelic-redis used that name, so avoid conflicting
@@ -33,12 +34,18 @@ DependencyDetection.defer do
33
34
  NewRelic::Agent.logger.info('Installing Redis Instrumentation')
34
35
  if NewRelic::Agent::Instrumentation::Redis::Constants::HAS_REDIS_CLIENT
35
36
  RedisClient.register(NewRelic::Agent::Instrumentation::RedisClient::Middleware)
37
+
38
+ if defined?(Redis::Cluster::Client)
39
+ RedisClient.register(NewRelic::Agent::Instrumentation::RedisClient::ClusterMiddleware)
40
+ end
36
41
  end
37
42
 
38
- if use_prepend?
39
- prepend_instrument Redis::Client, NewRelic::Agent::Instrumentation::Redis::Prepend
40
- else
41
- chain_instrument NewRelic::Agent::Instrumentation::Redis::Chain
43
+ unless defined?(Redis::Cluster::Client)
44
+ if use_prepend?
45
+ prepend_instrument Redis::Client, NewRelic::Agent::Instrumentation::Redis::Prepend
46
+ else
47
+ chain_instrument NewRelic::Agent::Instrumentation::Redis::Chain
48
+ end
42
49
  end
43
50
  end
44
51
  end
@@ -41,18 +41,4 @@ DependencyDetection.defer do
41
41
  end
42
42
  end
43
43
  end
44
-
45
- executes do
46
- next unless Gem::Version.new(Sidekiq::VERSION) < Gem::Version.new('5.0.0')
47
-
48
- deprecation_msg = 'Instrumentation for Sidekiq versions below 5.0.0 is deprecated ' \
49
- 'and will be dropped entirely in a future major New Relic Ruby agent release.' \
50
- 'Please upgrade your Sidekiq version to continue receiving full support. '
51
-
52
- NewRelic::Agent.logger.log_once(
53
- :warn,
54
- :deprecated_sidekiq_version,
55
- deprecation_msg
56
- )
57
- end
58
44
  end
@@ -42,17 +42,4 @@ DependencyDetection.defer do
42
42
  chain_instrument NewRelic::Agent::Instrumentation::Sinatra::Build::Chain
43
43
  end
44
44
  end
45
-
46
- executes do
47
- next unless Gem::Version.new(Sinatra::VERSION) < Gem::Version.new('2.0.0')
48
-
49
- deprecation_msg = 'The Ruby agent is dropping support for Sinatra versions below 2.0.0 ' \
50
- 'in version 9.0.0. Please upgrade your Sinatra version to continue receiving full compatibility. ' \
51
-
52
- NewRelic::Agent.logger.log_once(
53
- :warn,
54
- :deprecated_sinatra_version,
55
- deprecation_msg
56
- )
57
- end
58
45
  end
@@ -12,6 +12,12 @@ module NewRelic
12
12
  return message unless decorating_enabled?
13
13
 
14
14
  metadata = NewRelic::Agent.linking_metadata
15
+
16
+ if message.is_a?(Hash)
17
+ message.merge!(metadata) unless message.frozen?
18
+ return
19
+ end
20
+
15
21
  formatted_metadata = " NR-LINKING|#{metadata[ENTITY_GUID_KEY]}|#{metadata[HOSTNAME_KEY]}|" \
16
22
  "#{metadata[TRACE_ID_KEY]}|#{metadata[SPAN_ID_KEY]}|" \
17
23
  "#{escape_entity_name(metadata[ENTITY_NAME_KEY])}|"
@@ -23,7 +29,8 @@ module NewRelic
23
29
 
24
30
  def decorating_enabled?
25
31
  NewRelic::Agent.config[:'application_logging.enabled'] &&
26
- NewRelic::Agent::Instrumentation::Logger.enabled? &&
32
+ (NewRelic::Agent::Instrumentation::Logger.enabled? ||
33
+ NewRelic::Agent::Instrumentation::LogStasher.enabled?) &&
27
34
  NewRelic::Agent.config[:'application_logging.local_decorating.enabled']
28
35
  end
29
36