newrelic_rpm 9.14.0 → 9.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +101 -5
  3. data/CONTRIBUTING.md +2 -2
  4. data/lib/boot/strap.rb +4 -3
  5. data/lib/new_relic/agent/agent.rb +4 -0
  6. data/lib/new_relic/agent/agent_helpers/connect.rb +3 -0
  7. data/lib/new_relic/agent/agent_helpers/harvest.rb +3 -0
  8. data/lib/new_relic/agent/agent_helpers/shutdown.rb +3 -0
  9. data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +1 -0
  10. data/lib/new_relic/agent/agent_helpers/startup.rb +7 -0
  11. data/lib/new_relic/agent/aws.rb +6 -0
  12. data/lib/new_relic/agent/configuration/default_source.rb +258 -35
  13. data/lib/new_relic/agent/configuration/manager.rb +1 -1
  14. data/lib/new_relic/agent/configuration/yaml_source.rb +6 -1
  15. data/lib/new_relic/agent/database.rb +41 -1
  16. data/lib/new_relic/agent/distributed_tracing.rb +2 -2
  17. data/lib/new_relic/agent/health_check.rb +136 -0
  18. data/lib/new_relic/agent/instrumentation/active_record.rb +1 -8
  19. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +5 -1
  20. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +9 -16
  21. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger.rb +0 -2
  22. data/lib/new_relic/agent/instrumentation/active_support_logger.rb +0 -2
  23. data/lib/new_relic/agent/instrumentation/async_http.rb +1 -2
  24. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/chain.rb +21 -0
  25. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/instrumentation.rb +66 -0
  26. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/prepend.rb +15 -0
  27. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose.rb +22 -0
  28. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/chain.rb +21 -0
  29. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/instrumentation.rb +91 -0
  30. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/prepend.rb +15 -0
  31. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis.rb +22 -0
  32. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/chain.rb +33 -0
  33. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/instrumentation.rb +93 -0
  34. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/prepend.rb +23 -0
  35. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda.rb +23 -0
  36. data/lib/new_relic/agent/instrumentation/aws_sqs.rb +0 -2
  37. data/lib/new_relic/agent/instrumentation/bunny.rb +3 -4
  38. data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +0 -2
  39. data/lib/new_relic/agent/instrumentation/curb.rb +3 -4
  40. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +0 -4
  41. data/lib/new_relic/agent/instrumentation/dynamodb/instrumentation.rb +3 -4
  42. data/lib/new_relic/agent/instrumentation/dynamodb.rb +0 -2
  43. data/lib/new_relic/agent/instrumentation/elasticsearch.rb +0 -2
  44. data/lib/new_relic/agent/instrumentation/ethon.rb +0 -4
  45. data/lib/new_relic/agent/instrumentation/fiber.rb +0 -2
  46. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +0 -3
  47. data/lib/new_relic/agent/instrumentation/grape.rb +1 -3
  48. data/lib/new_relic/agent/instrumentation/httpclient.rb +0 -1
  49. data/lib/new_relic/agent/instrumentation/httprb.rb +0 -1
  50. data/lib/new_relic/agent/instrumentation/httpx.rb +0 -4
  51. data/lib/new_relic/agent/instrumentation/logger.rb +1 -3
  52. data/lib/new_relic/agent/instrumentation/logstasher.rb +0 -2
  53. data/lib/new_relic/agent/instrumentation/memcache.rb +0 -1
  54. data/lib/new_relic/agent/instrumentation/opensearch.rb +0 -2
  55. data/lib/new_relic/agent/instrumentation/padrino.rb +3 -3
  56. data/lib/new_relic/agent/instrumentation/rake.rb +0 -1
  57. data/lib/new_relic/agent/instrumentation/rdkafka/chain.rb +2 -1
  58. data/lib/new_relic/agent/instrumentation/rdkafka/prepend.rb +2 -1
  59. data/lib/new_relic/agent/instrumentation/rdkafka.rb +0 -2
  60. data/lib/new_relic/agent/instrumentation/redis.rb +0 -1
  61. data/lib/new_relic/agent/instrumentation/resque.rb +7 -5
  62. data/lib/new_relic/agent/instrumentation/roda.rb +4 -4
  63. data/lib/new_relic/agent/instrumentation/ruby_kafka/prepend.rb +14 -4
  64. data/lib/new_relic/agent/instrumentation/ruby_kafka.rb +0 -2
  65. data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +1 -1
  66. data/lib/new_relic/agent/instrumentation/sinatra.rb +3 -6
  67. data/lib/new_relic/agent/instrumentation/thread.rb +0 -2
  68. data/lib/new_relic/agent/instrumentation/tilt.rb +0 -4
  69. data/lib/new_relic/agent/instrumentation/typhoeus.rb +0 -1
  70. data/lib/new_relic/agent/instrumentation/view_component/instrumentation.rb +11 -8
  71. data/lib/new_relic/agent/instrumentation/view_component.rb +0 -2
  72. data/lib/new_relic/agent/local_log_decorator.rb +12 -2
  73. data/lib/new_relic/agent/log_event_aggregator.rb +28 -2
  74. data/lib/new_relic/agent/new_relic_service.rb +8 -2
  75. data/lib/new_relic/agent/span_event_primitive.rb +4 -2
  76. data/lib/new_relic/agent/threading/backtrace_node.rb +10 -1
  77. data/lib/new_relic/agent/transaction/message_broker_segment.rb +3 -0
  78. data/lib/new_relic/agent.rb +2 -2
  79. data/lib/new_relic/control/frameworks/rails4.rb +1 -5
  80. data/lib/new_relic/dependency_detection.rb +11 -13
  81. data/lib/new_relic/environment_report.rb +1 -5
  82. data/lib/new_relic/helper.rb +15 -0
  83. data/lib/new_relic/language_support.rb +1 -5
  84. data/lib/new_relic/version.rb +1 -1
  85. data/lib/sequel/extensions/new_relic_instrumentation.rb +1 -1
  86. data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +9 -6
  87. data/newrelic.yml +135 -54
  88. data/test/agent_helper.rb +8 -1
  89. metadata +16 -6
@@ -0,0 +1,23 @@
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
+ DependencyDetection.defer do
6
+ named :aws_sdk_lambda
7
+
8
+ depends_on do
9
+ defined?(Aws::Lambda::Client)
10
+ end
11
+
12
+ executes do
13
+ require_relative 'aws_sdk_lambda/instrumentation'
14
+
15
+ if use_prepend?
16
+ require_relative 'aws_sdk_lambda/prepend'
17
+ prepend_instrument Aws::Lambda::Client, NewRelic::Agent::Instrumentation::AwsSdkLambda::Prepend
18
+ else
19
+ require_relative 'aws_sdk_lambda/chain'
20
+ chain_instrument NewRelic::Agent::Instrumentation::AwsSdkLambda::Chain
21
+ end
22
+ end
23
+ end
@@ -14,8 +14,6 @@ DependencyDetection.defer do
14
14
  end
15
15
 
16
16
  executes do
17
- NewRelic::Agent.logger.info('Installing aws-sdk-sqs instrumentation')
18
-
19
17
  if use_prepend?
20
18
  prepend_instrument Aws::SQS::Client, NewRelic::Agent::Instrumentation::AwsSqs::Prepend
21
19
  else
@@ -14,7 +14,6 @@ DependencyDetection.defer do
14
14
  end
15
15
 
16
16
  executes do
17
- NewRelic::Agent.logger.info('Installing Bunny instrumentation')
18
17
  require 'new_relic/agent/distributed_tracing/cross_app_tracing'
19
18
  require 'new_relic/agent/messaging'
20
19
  require 'new_relic/agent/transaction/message_broker_segment'
@@ -22,9 +21,9 @@ DependencyDetection.defer do
22
21
 
23
22
  executes do
24
23
  if use_prepend?
25
- prepend_instrument Bunny::Exchange, NewRelic::Agent::Instrumentation::Bunny::Prepend::Exchange
26
- prepend_instrument Bunny::Queue, NewRelic::Agent::Instrumentation::Bunny::Prepend::Queue
27
- prepend_instrument Bunny::Consumer, NewRelic::Agent::Instrumentation::Bunny::Prepend::Consumer
24
+ prepend_instrument Bunny::Exchange, NewRelic::Agent::Instrumentation::Bunny::Prepend::Exchange, 'Bunny::Exchange'
25
+ prepend_instrument Bunny::Queue, NewRelic::Agent::Instrumentation::Bunny::Prepend::Queue, 'Bunny::Queue'
26
+ prepend_instrument Bunny::Consumer, NewRelic::Agent::Instrumentation::Bunny::Prepend::Consumer, 'Bunny::Consumer'
28
27
  else
29
28
  chain_instrument NewRelic::Agent::Instrumentation::Bunny::Chain
30
29
  end
@@ -16,8 +16,6 @@ DependencyDetection.defer do
16
16
  end
17
17
 
18
18
  executes do
19
- NewRelic::Agent.logger.info('Installing concurrent-ruby instrumentation')
20
-
21
19
  if use_prepend?
22
20
  prepend_instrument(Concurrent::ThreadPoolExecutor, NewRelic::Agent::Instrumentation::ConcurrentRuby::Prepend)
23
21
 
@@ -16,17 +16,16 @@ DependencyDetection.defer do
16
16
  end
17
17
 
18
18
  executes do
19
- NewRelic::Agent.logger.info('Installing Curb instrumentation')
20
19
  require 'new_relic/agent/distributed_tracing/cross_app_tracing'
21
20
  require 'new_relic/agent/http_clients/curb_wrappers'
22
21
  end
23
22
 
24
23
  executes do
25
24
  if use_prepend?
26
- prepend_instrument Curl::Easy, NewRelic::Agent::Instrumentation::Curb::Easy::Prepend
27
- prepend_instrument Curl::Multi, NewRelic::Agent::Instrumentation::Curb::Multi::Prepend
25
+ prepend_instrument Curl::Easy, NewRelic::Agent::Instrumentation::Curb::Easy::Prepend, 'Curb::Easy'
26
+ prepend_instrument Curl::Multi, NewRelic::Agent::Instrumentation::Curb::Multi::Prepend, 'Curb::Multi'
28
27
  else
29
- chain_instrument NewRelic::Agent::Instrumentation::Curb::Chain
28
+ chain_instrument NewRelic::Agent::Instrumentation::Curb::Chain, NewRelic::Agent::Instrumentation::Curb::Multi::INSTRUMENTATION_NAME
30
29
  end
31
30
  end
32
31
  end
@@ -82,10 +82,6 @@ DependencyDetection.defer do
82
82
  defined?(Delayed) && defined?(Delayed::Worker)
83
83
  end
84
84
 
85
- executes do
86
- NewRelic::Agent.logger.info('Installing DelayedJob instrumentation [part 1/2]')
87
- end
88
-
89
85
  executes do
90
86
  if use_prepend?
91
87
  prepend_instrument Delayed::Worker, NewRelic::Agent::Instrumentation::DelayedJob::Prepend
@@ -31,9 +31,8 @@ module NewRelic::Agent::Instrumentation
31
31
  collection: args[0][:table_name]
32
32
  )
33
33
 
34
- # TODO: Update this when it has been decided how to handle account id for ARN
35
- # arn = get_arn(args[0])
36
- # segment&.add_agent_attribute('cloud.resource_id', arn) if arn
34
+ arn = get_arn(args[0])
35
+ segment&.add_agent_attribute('cloud.resource_id', arn) if arn
37
36
 
38
37
  @nr_captured_request = nil # clear request just in case
39
38
  begin
@@ -57,7 +56,7 @@ module NewRelic::Agent::Instrumentation
57
56
  end
58
57
 
59
58
  def get_arn(params)
60
- return unless params[:table_name] && nr_account_id
59
+ return unless params[:table_name]
61
60
 
62
61
  NewRelic::Agent::Aws.create_arn(PRODUCT.downcase, "table/#{params[:table_name]}", config&.region, nr_account_id)
63
62
  end
@@ -14,8 +14,6 @@ DependencyDetection.defer do
14
14
  end
15
15
 
16
16
  executes do
17
- NewRelic::Agent.logger.info('Installing DynamoDB instrumentation')
18
-
19
17
  if use_prepend?
20
18
  prepend_instrument Aws::DynamoDB::Client, NewRelic::Agent::Instrumentation::DynamoDB::Prepend
21
19
  else
@@ -14,8 +14,6 @@ DependencyDetection.defer do
14
14
  end
15
15
 
16
16
  executes do
17
- NewRelic::Agent.logger.info('Installing Elasticsearch instrumentation')
18
-
19
17
  to_instrument = if Gem::Version.create(Elasticsearch::VERSION) < Gem::Version.create('8.0.0')
20
18
  Elasticsearch::Transport::Client
21
19
  else
@@ -21,10 +21,6 @@ DependencyDetection.defer do
21
21
  defined?(Ethon) && Gem::Version.new(Ethon::VERSION) >= Gem::Version.new('0.12.0')
22
22
  end
23
23
 
24
- executes do
25
- NewRelic::Agent.logger.info('Installing ethon instrumentation')
26
- end
27
-
28
24
  executes do
29
25
  if use_prepend?
30
26
  # NOTE: by default prepend_instrument will go with the module name that
@@ -14,8 +14,6 @@ DependencyDetection.defer do
14
14
  end
15
15
 
16
16
  executes do
17
- NewRelic::Agent.logger.info('Installing Fiber instrumentation')
18
-
19
17
  if use_prepend?
20
18
  prepend_instrument Fiber, NewRelic::Agent::Instrumentation::MonitoredFiber::Prepend
21
19
  else
@@ -56,10 +56,7 @@ module NewRelic::Agent::Instrumentation
56
56
 
57
57
  def name_transaction(route, class_name, version)
58
58
  txn_name = name_for_transaction(route, class_name, version)
59
- segment_name = "Middleware/Grape/#{class_name}/call"
60
59
  NewRelic::Agent::Transaction.set_default_transaction_name(txn_name, :grape)
61
- txn = NewRelic::Agent::Transaction.tl_current
62
- txn.segments.last.name = segment_name
63
60
  end
64
61
 
65
62
  def name_for_transaction(route, class_name, version)
@@ -19,9 +19,7 @@ DependencyDetection.defer do
19
19
 
20
20
  depends_on do
21
21
  begin
22
- if defined?(Bundler) &&
23
- ((Bundler.rubygems.respond_to?(:installed_specs) && Bundler.rubygems.installed_specs.map(&:name).include?('newrelic-grape')) ||
24
- Bundler.rubygems.all_specs.map(&:name).include?('newrelic-grape'))
22
+ if NewRelic::Helper.rubygems_specs.map(&:name).include?('newrelic-grape')
25
23
  NewRelic::Agent.logger.info('Not installing New Relic supported Grape instrumentation because the third party newrelic-grape gem is present')
26
24
  false
27
25
  else
@@ -23,7 +23,6 @@ DependencyDetection.defer do
23
23
  end
24
24
 
25
25
  executes do
26
- NewRelic::Agent.logger.info('Installing HTTPClient instrumentation')
27
26
  require 'new_relic/agent/distributed_tracing/cross_app_tracing'
28
27
  require 'new_relic/agent/http_clients/httpclient_wrappers'
29
28
  end
@@ -14,7 +14,6 @@ DependencyDetection.defer do
14
14
  end
15
15
 
16
16
  executes do
17
- NewRelic::Agent.logger.info('Installing http.rb Wrappers')
18
17
  require 'new_relic/agent/distributed_tracing/cross_app_tracing'
19
18
  require 'new_relic/agent/http_clients/http_rb_wrappers'
20
19
  end
@@ -13,10 +13,6 @@ DependencyDetection.defer do
13
13
  defined?(HTTPX) && Gem::Version.new(HTTPX::VERSION) >= Gem::Version.new('1.0.0')
14
14
  end
15
15
 
16
- executes do
17
- NewRelic::Agent.logger.info('Installing httpx instrumentation')
18
- end
19
-
20
16
  executes do
21
17
  if use_prepend?
22
18
  prepend_instrument HTTPX::Session, NewRelic::Agent::Instrumentation::HTTPX::Prepend
@@ -15,12 +15,10 @@ DependencyDetection.defer do
15
15
  end
16
16
 
17
17
  executes do
18
- NewRelic::Agent.logger.info('Installing Logger instrumentation')
19
-
20
18
  if use_prepend?
21
19
  prepend_instrument Logger, NewRelic::Agent::Instrumentation::Logger::Prepend
22
20
  else
23
- chain_instrument NewRelic::Agent::Instrumentation::Logger
21
+ chain_instrument NewRelic::Agent::Instrumentation::Logger, NewRelic::Agent::Instrumentation::Logger::INSTRUMENTATION_NAME
24
22
  end
25
23
  end
26
24
  end
@@ -16,8 +16,6 @@ DependencyDetection.defer do
16
16
  end
17
17
 
18
18
  executes do
19
- NewRelic::Agent.logger.info('Installing LogStasher instrumentation')
20
-
21
19
  if use_prepend?
22
20
  prepend_instrument LogStasher.singleton_class, NewRelic::Agent::Instrumentation::LogStasher::Prepend
23
21
  else
@@ -74,7 +74,6 @@ DependencyDetection.defer do
74
74
  depends_on { NewRelic::Agent::Instrumentation::Memcache::DalliCAS.should_instrument? }
75
75
 
76
76
  executes do
77
- NewRelic::Agent.logger.info('Installing Dalli CAS Client Memcache instrumentation')
78
77
  if use_prepend?
79
78
  prepend_module = NewRelic::Agent::Instrumentation::Memcache::Prepend
80
79
  prepend_module.dalli_cas_prependers do |client_class, instrumenting_module|
@@ -14,8 +14,6 @@ DependencyDetection.defer do
14
14
  end
15
15
 
16
16
  executes do
17
- NewRelic::Agent.logger.info('Installing opensearch-ruby instrumentation')
18
-
19
17
  if use_prepend?
20
18
  prepend_instrument OpenSearch::Transport::Client, NewRelic::Agent::Instrumentation::OpenSearch::Prepend
21
19
  else
@@ -22,11 +22,11 @@ DependencyDetection.defer do
22
22
  depends_on { defined?(Padrino) && defined?(Padrino::Routing::InstanceMethods) }
23
23
 
24
24
  executes do
25
- NewRelic::Agent.logger.info('Installing Padrino instrumentation')
25
+ supportability_name = NewRelic::Agent::Instrumentation::Padrino::INSTRUMENTATION_NAME
26
26
  if use_prepend?
27
- prepend_instrument Padrino::Application, NewRelic::Agent::Instrumentation::PadrinoTracer::Prepend
27
+ prepend_instrument Padrino::Application, NewRelic::Agent::Instrumentation::PadrinoTracer::Prepend, supportability_name
28
28
  else
29
- chain_instrument NewRelic::Agent::Instrumentation::PadrinoTracer::Chain
29
+ chain_instrument NewRelic::Agent::Instrumentation::PadrinoTracer::Chain, supportability_name
30
30
  end
31
31
  end
32
32
  end
@@ -17,7 +17,6 @@ DependencyDetection.defer do
17
17
  depends_on { NewRelic::Agent::Instrumentation::Rake.safe_from_third_party_gem? }
18
18
 
19
19
  executes do
20
- NewRelic::Agent.logger.info('Installing Rake instrumentation')
21
20
  NewRelic::Agent.logger.debug("Instrumenting Rake tasks: #{NewRelic::Agent.config[:'rake.tasks']}")
22
21
  end
23
22
 
@@ -40,7 +40,8 @@ module NewRelic::Agent::Instrumentation
40
40
  alias_method(:producer_without_new_relic, :producer)
41
41
  alias_method(:consumer_without_new_relic, :consumer)
42
42
 
43
- if Gem::Version.new(::Rdkafka::VERSION) >= Gem::Version.new('0.16.0')
43
+ if Gem::Version.new(::Rdkafka::VERSION) >= Gem::Version.new('0.16.0') ||
44
+ (Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0'))
44
45
  def producer(**kwargs)
45
46
  producer_without_new_relic(**kwargs).tap do |producer|
46
47
  set_nr_config(producer)
@@ -36,7 +36,8 @@ module NewRelic::Agent::Instrumentation
36
36
  module Prepend
37
37
  include NewRelic::Agent::Instrumentation::RdkafkaConfig
38
38
 
39
- if defined?(::Rdkafka) && Gem::Version.new(::Rdkafka::VERSION) >= Gem::Version.new('0.16.0')
39
+ if (defined?(::Rdkafka) && Gem::Version.new(::Rdkafka::VERSION) >= Gem::Version.new('0.16.0')) ||
40
+ (Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0'))
40
41
  def producer(**kwargs)
41
42
  super.tap do |producer|
42
43
  set_nr_config(producer)
@@ -10,8 +10,6 @@ DependencyDetection.defer do
10
10
  end
11
11
 
12
12
  executes do
13
- NewRelic::Agent.logger.info('Installing rdkafka instrumentation')
14
-
15
13
  require_relative 'rdkafka/instrumentation'
16
14
  require_relative 'rdkafka/chain'
17
15
  require_relative 'rdkafka/prepend'
@@ -31,7 +31,6 @@ DependencyDetection.defer do
31
31
  end
32
32
 
33
33
  executes do
34
- NewRelic::Agent.logger.info('Installing Redis Instrumentation')
35
34
  if NewRelic::Agent::Instrumentation::Redis::Constants::HAS_REDIS_CLIENT
36
35
  RedisClient.register(NewRelic::Agent::Instrumentation::RedisClient::Middleware)
37
36
 
@@ -19,11 +19,13 @@ DependencyDetection.defer do
19
19
  end
20
20
 
21
21
  executes do
22
- NewRelic::Agent.logger.info('Installing Resque instrumentation')
23
- end
24
-
25
- executes do
26
- if NewRelic::Agent.config[:'resque.use_ruby_dns'] && NewRelic::Agent.config[:dispatcher] == :resque
22
+ if NewRelic::Agent.config[:'resque.use_ruby_dns'] &&
23
+ NewRelic::Agent.config[:dispatcher] == :resque &&
24
+ # resolv-replace is no longer part of the language in Ruby 3.4.
25
+ # we don't believe this lib is still necessary for Ruby 3.4 users.
26
+ # however, if we receive customer feedback to the contrary, we can find
27
+ # an alternate approach.
28
+ Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.4')
27
29
  NewRelic::Agent.logger.info('Requiring resolv-replace')
28
30
  require 'resolv'
29
31
  require 'resolv-replace'
@@ -20,15 +20,15 @@ DependencyDetection.defer do
20
20
  require_relative '../../rack/agent_hooks'
21
21
  require_relative '../../rack/browser_monitoring'
22
22
 
23
- NewRelic::Agent.logger.info('Installing Roda instrumentation')
24
-
25
23
  if use_prepend?
26
24
  require_relative 'roda/prepend'
27
- prepend_instrument Roda.singleton_class, NewRelic::Agent::Instrumentation::Roda::Build::Prepend
25
+
26
+ supportability_name = NewRelic::Agent::Instrumentation::Roda::Tracer::INSTRUMENTATION_NAME
27
+ prepend_instrument Roda.singleton_class, NewRelic::Agent::Instrumentation::Roda::Build::Prepend, supportability_name
28
28
  prepend_instrument Roda, NewRelic::Agent::Instrumentation::Roda::Prepend
29
29
  else
30
30
  require_relative 'roda/chain'
31
- chain_instrument NewRelic::Agent::Instrumentation::Roda::Build::Chain
31
+ chain_instrument NewRelic::Agent::Instrumentation::Roda::Build::Chain, supportability_name
32
32
  chain_instrument NewRelic::Agent::Instrumentation::Roda::Chain
33
33
  end
34
34
  Roda.class_eval { extend NewRelic::Agent::Instrumentation::Roda::Ignorer }
@@ -20,10 +20,20 @@ module NewRelic::Agent::Instrumentation
20
20
  module Prepend
21
21
  include NewRelic::Agent::Instrumentation::RubyKafka
22
22
 
23
- def each_message(*args)
24
- super do |message|
25
- each_message_with_new_relic(message) do
26
- yield(message)
23
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3')
24
+ def each_message(**args)
25
+ super do |message|
26
+ each_message_with_new_relic(message) do
27
+ yield(message)
28
+ end
29
+ end
30
+ end
31
+ else
32
+ def each_message(*args)
33
+ super do |message|
34
+ each_message_with_new_relic(message) do
35
+ yield(message)
36
+ end
27
37
  end
28
38
  end
29
39
  end
@@ -14,8 +14,6 @@ DependencyDetection.defer do
14
14
  end
15
15
 
16
16
  executes do
17
- NewRelic::Agent.logger.info('Installing ruby-kafka instrumentation')
18
-
19
17
  if use_prepend?
20
18
  prepend_instrument Kafka::Producer, NewRelic::Agent::Instrumentation::RubyKafkaProducer::Prepend
21
19
  prepend_instrument Kafka::Consumer, NewRelic::Agent::Instrumentation::RubyKafkaConsumer::Prepend
@@ -6,7 +6,7 @@
6
6
  # Delayed extensions are disabled by default in Sidekiq 5 and 6 and
7
7
  # were removed entirely in Sidekiq 7.
8
8
  #
9
- # see https://github.com/mperham/sidekiq/issues/5076 for the discussion
9
+ # see https://github.com/sidekiq/sidekiq/issues/5076 for the discussion
10
10
  # of the removal, which includes mentions of alternatives
11
11
  if defined?(Sidekiq::VERSION) && Sidekiq::VERSION < '7.0.0'
12
12
  class Sidekiq::Extensions::DelayedClass
@@ -16,10 +16,6 @@ DependencyDetection.defer do
16
16
  depends_on { Sinatra::Base.private_method_defined?(:process_route) }
17
17
  depends_on { Sinatra::Base.private_method_defined?(:route_eval) }
18
18
 
19
- executes do
20
- NewRelic::Agent.logger.info('Installing Sinatra instrumentation')
21
- end
22
-
23
19
  executes do
24
20
  if use_prepend?
25
21
  prepend_instrument Sinatra::Base, NewRelic::Agent::Instrumentation::Sinatra::Prepend
@@ -32,14 +28,15 @@ DependencyDetection.defer do
32
28
  end
33
29
 
34
30
  executes do
31
+ supportability_name = NewRelic::Agent::Instrumentation::Sinatra::Tracer::INSTRUMENTATION_NAME
35
32
  # These requires are inside an executes block because they require rack, and
36
33
  # we can't be sure that rack is available when this file is first required.
37
34
  require 'new_relic/rack/agent_hooks'
38
35
  require 'new_relic/rack/browser_monitoring'
39
36
  if use_prepend?
40
- prepend_instrument Sinatra::Base.singleton_class, NewRelic::Agent::Instrumentation::Sinatra::Build::Prepend
37
+ prepend_instrument Sinatra::Base.singleton_class, NewRelic::Agent::Instrumentation::Sinatra::Build::Prepend, supportability_name
41
38
  else
42
- chain_instrument NewRelic::Agent::Instrumentation::Sinatra::Build::Chain
39
+ chain_instrument NewRelic::Agent::Instrumentation::Sinatra::Build::Chain, supportability_name
43
40
  end
44
41
  end
45
42
  end
@@ -9,8 +9,6 @@ DependencyDetection.defer do
9
9
  named :thread
10
10
 
11
11
  executes do
12
- NewRelic::Agent.logger.info('Installing Thread Instrumentation')
13
-
14
12
  if use_prepend?
15
13
  prepend_instrument Thread, NewRelic::Agent::Instrumentation::MonitoredThread::Prepend
16
14
  else
@@ -11,10 +11,6 @@ DependencyDetection.defer do
11
11
 
12
12
  depends_on { defined?(Tilt) }
13
13
 
14
- executes do
15
- NewRelic::Agent.logger.info('Installing Tilt instrumentation')
16
- end
17
-
18
14
  executes do
19
15
  if use_prepend?
20
16
  prepend_instrument Tilt::Template, NewRelic::Agent::Instrumentation::Tilt::Prepend
@@ -18,7 +18,6 @@ DependencyDetection.defer do
18
18
  end
19
19
 
20
20
  executes do
21
- NewRelic::Agent.logger.info('Installing Typhoeus instrumentation')
22
21
  require 'new_relic/agent/distributed_tracing/cross_app_tracing'
23
22
  require 'new_relic/agent/http_clients/typhoeus_wrappers'
24
23
  end
@@ -10,12 +10,7 @@ module NewRelic::Agent::Instrumentation
10
10
  NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
11
11
 
12
12
  begin
13
- segment = NewRelic::Agent::Tracer.start_segment(
14
- name: metric_name(
15
- self.class.respond_to?(:identifier) ? self.class.identifier : nil,
16
- self.class.name
17
- )
18
- )
13
+ segment = NewRelic::Agent::Tracer.start_segment(name: metric_name)
19
14
  yield
20
15
  rescue => e
21
16
  NewRelic::Agent.notice_error(e)
@@ -25,8 +20,16 @@ module NewRelic::Agent::Instrumentation
25
20
  end
26
21
  end
27
22
 
28
- def metric_name(identifier, component)
29
- "View/#{metric_path(identifier)}/#{component}"
23
+ def metric_name
24
+ # ViewComponent determines a component's identifier differently depending on the version
25
+ # https://github.com/ViewComponent/view_component/pull/2153
26
+ component_identifier = defined?(self.class.source_location) ? self.class.source_location : self.class.identifier
27
+
28
+ "View/#{metric_path(component_identifier)}/#{self.class.name}"
29
+ rescue => e
30
+ NewRelic::Agent.logger.error('Error identifying View Component metric name', e)
31
+
32
+ 'View/component'
30
33
  end
31
34
 
32
35
  def metric_path(identifier)
@@ -15,8 +15,6 @@ DependencyDetection.defer do
15
15
  end
16
16
 
17
17
  executes do
18
- NewRelic::Agent.logger.info('Installing ViewComponent instrumentation')
19
-
20
18
  if use_prepend?
21
19
  prepend_instrument ViewComponent::Base, NewRelic::Agent::Instrumentation::ViewComponent::Prepend
22
20
  else
@@ -9,7 +9,7 @@ module NewRelic
9
9
  extend self
10
10
 
11
11
  def decorate(message)
12
- return message unless decorating_enabled?
12
+ return message if !decorating_enabled? || message.nil?
13
13
 
14
14
  metadata = NewRelic::Agent.linking_metadata
15
15
 
@@ -37,7 +37,17 @@ module NewRelic
37
37
  def escape_entity_name(entity_name)
38
38
  return unless entity_name
39
39
 
40
- URI::DEFAULT_PARSER.escape(entity_name)
40
+ # TODO: OLD RUBIES 3.3
41
+ # URI version 1.0 marked URI::RFC3986_PARSER.escape as obsolete,
42
+ # which URI::DEFAULT_PARSER is an alias for.
43
+ # URI version 1.0+ will ship with Ruby 3.4
44
+ # Once we drop support for Rubies below 3.4, we can use the
45
+ # URI::RFC2396 parser exclusively.
46
+ if Gem::Version.new(URI::VERSION) >= Gem::Version.new('1.0')
47
+ URI::RFC2396_PARSER.escape(entity_name)
48
+ else
49
+ URI::DEFAULT_PARSER.escape(entity_name)
50
+ end
41
51
  end
42
52
  end
43
53
  end
@@ -25,6 +25,7 @@ module NewRelic
25
25
  METRICS_SUPPORTABILITY_FORMAT = 'Supportability/Logging/Metrics/Ruby/%s'.freeze
26
26
  FORWARDING_SUPPORTABILITY_FORMAT = 'Supportability/Logging/Forwarding/Ruby/%s'.freeze
27
27
  DECORATING_SUPPORTABILITY_FORMAT = 'Supportability/Logging/LocalDecorating/Ruby/%s'.freeze
28
+ LABELS_SUPPORTABILITY_FORMAT = 'Supportability/Logging/Labels/Ruby/%s'.freeze
28
29
  MAX_BYTES = 32768 # 32 * 1024 bytes (32 kibibytes)
29
30
 
30
31
  named :LogEventAggregator
@@ -38,6 +39,7 @@ module NewRelic
38
39
  METRICS_ENABLED_KEY = :'application_logging.metrics.enabled'
39
40
  FORWARDING_ENABLED_KEY = :'application_logging.forwarding.enabled'
40
41
  DECORATING_ENABLED_KEY = :'application_logging.local_decorating.enabled'
42
+ LABELS_ENABLED_KEY = :'application_logging.forwarding.labels.enabled'
41
43
  LOG_LEVEL_KEY = :'application_logging.forwarding.log_level'
42
44
  CUSTOM_ATTRIBUTES_KEY = :'application_logging.forwarding.custom_attributes'
43
45
 
@@ -51,6 +53,7 @@ module NewRelic
51
53
  @high_security = NewRelic::Agent.config[:high_security]
52
54
  @instrumentation_logger_enabled = NewRelic::Agent::Instrumentation::Logger.enabled?
53
55
  @attributes = NewRelic::Agent::LogEventAttributes.new
56
+
54
57
  register_for_done_configuring(events)
55
58
  end
56
59
 
@@ -186,6 +189,10 @@ module NewRelic
186
189
  attributes.add_custom_attributes(custom_attributes)
187
190
  end
188
191
 
192
+ def labels
193
+ @labels ||= create_labels
194
+ end
195
+
189
196
  # Because our transmission format (MELT) is different than historical
190
197
  # agent payloads, extract the munging here to keep the service focused
191
198
  # on the general harvest + transmit instead of the format.
@@ -201,8 +208,9 @@ module NewRelic
201
208
  # To save on unnecessary data transmission, trim the entity.type
202
209
  # sent by classic logs-in-context
203
210
  common_attributes.delete(ENTITY_TYPE_KEY)
204
-
205
- common_attributes.merge!(NewRelic::Agent.agent.log_event_aggregator.attributes.custom_attributes)
211
+ aggregator = NewRelic::Agent.agent.log_event_aggregator
212
+ common_attributes.merge!(aggregator.attributes.custom_attributes)
213
+ common_attributes.merge!(aggregator.labels)
206
214
 
207
215
  _, items = data
208
216
  payload = [{
@@ -247,6 +255,7 @@ module NewRelic
247
255
  record_configuration_metric(METRICS_SUPPORTABILITY_FORMAT, METRICS_ENABLED_KEY)
248
256
  record_configuration_metric(FORWARDING_SUPPORTABILITY_FORMAT, FORWARDING_ENABLED_KEY)
249
257
  record_configuration_metric(DECORATING_SUPPORTABILITY_FORMAT, DECORATING_ENABLED_KEY)
258
+ record_configuration_metric(LABELS_SUPPORTABILITY_FORMAT, LABELS_ENABLED_KEY)
250
259
 
251
260
  add_custom_attributes(NewRelic::Agent.config[CUSTOM_ATTRIBUTES_KEY])
252
261
  end
@@ -327,6 +336,23 @@ module NewRelic
327
336
 
328
337
  Logger::Severity.const_get(severity_constant) < Logger::Severity.const_get(configured_log_level_constant)
329
338
  end
339
+
340
+ def create_labels
341
+ return NewRelic::EMPTY_HASH unless NewRelic::Agent.config[LABELS_ENABLED_KEY]
342
+
343
+ downcased_exclusions = NewRelic::Agent.config[:'application_logging.forwarding.labels.exclude'].map(&:downcase)
344
+ log_labels = {}
345
+
346
+ NewRelic::Agent.config.parsed_labels.each do |parsed_label|
347
+ next if downcased_exclusions.include?(parsed_label['label_type'].downcase)
348
+
349
+ # labels are referred to as tags in the UI, so prefix the
350
+ # label-related attributes with 'tags.*'
351
+ log_labels["tags.#{parsed_label['label_type']}"] = parsed_label['label_value']
352
+ end
353
+
354
+ log_labels
355
+ end
330
356
  end
331
357
  end
332
358
  end