newrelic_rpm 9.19.0 → 9.20.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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +38 -0
  3. data/lib/new_relic/agent/configuration/default_source.rb +85 -85
  4. data/lib/new_relic/agent/configuration/manager.rb +5 -2
  5. data/lib/new_relic/agent/configuration/yaml_source.rb +2 -2
  6. data/lib/new_relic/agent/database.rb +1 -1
  7. data/lib/new_relic/agent/database_adapter.rb +1 -1
  8. data/lib/new_relic/agent/datastores/redis.rb +1 -1
  9. data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +1 -1
  10. data/lib/new_relic/agent/distributed_tracing.rb +2 -0
  11. data/lib/new_relic/agent/external.rb +2 -0
  12. data/lib/new_relic/agent/instrumentation/action_dispatch.rb +1 -1
  13. data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +1 -1
  14. data/lib/new_relic/agent/instrumentation/action_mailbox.rb +1 -1
  15. data/lib/new_relic/agent/instrumentation/action_mailer.rb +1 -1
  16. data/lib/new_relic/agent/instrumentation/active_job.rb +1 -1
  17. data/lib/new_relic/agent/instrumentation/active_record.rb +6 -4
  18. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +2 -2
  19. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +11 -9
  20. data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +2 -2
  21. data/lib/new_relic/agent/instrumentation/async_http.rb +1 -1
  22. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/instrumentation.rb +1 -1
  23. data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +1 -1
  24. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +4 -0
  25. data/lib/new_relic/agent/instrumentation/curb.rb +1 -1
  26. data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +1 -2
  27. data/lib/new_relic/agent/instrumentation/elasticsearch.rb +1 -1
  28. data/lib/new_relic/agent/instrumentation/ethon.rb +1 -1
  29. data/lib/new_relic/agent/instrumentation/excon.rb +1 -1
  30. data/lib/new_relic/agent/instrumentation/fiber/chain.rb +1 -1
  31. data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +1 -1
  32. data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -4
  33. data/lib/new_relic/agent/instrumentation/httpx/instrumentation.rb +1 -1
  34. data/lib/new_relic/agent/instrumentation/httpx.rb +1 -1
  35. data/lib/new_relic/agent/instrumentation/logstasher.rb +1 -1
  36. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +1 -1
  37. data/lib/new_relic/agent/instrumentation/memcache/helper.rb +2 -2
  38. data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +1 -1
  39. data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +1 -1
  40. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +1 -1
  41. data/lib/new_relic/agent/instrumentation/net_http.rb +2 -1
  42. data/lib/new_relic/agent/instrumentation/rake.rb +1 -1
  43. data/lib/new_relic/agent/instrumentation/rdkafka/chain.rb +2 -2
  44. data/lib/new_relic/agent/instrumentation/rdkafka/prepend.rb +2 -2
  45. data/lib/new_relic/agent/instrumentation/redis/constants.rb +2 -2
  46. data/lib/new_relic/agent/instrumentation/resque.rb +2 -2
  47. data/lib/new_relic/agent/instrumentation/roda.rb +1 -1
  48. data/lib/new_relic/agent/instrumentation/ruby_kafka/prepend.rb +1 -1
  49. data/lib/new_relic/agent/instrumentation/ruby_openai.rb +2 -2
  50. data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +1 -1
  51. data/lib/new_relic/agent/instrumentation/stripe.rb +1 -1
  52. data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +2 -2
  53. data/lib/new_relic/agent/llm/chat_completion_summary.rb +1 -1
  54. data/lib/new_relic/agent/llm/embedding.rb +1 -1
  55. data/lib/new_relic/agent/local_log_decorator.rb +1 -1
  56. data/lib/new_relic/agent/logging.rb +1 -1
  57. data/lib/new_relic/agent/messaging.rb +5 -0
  58. data/lib/new_relic/agent/method_tracer.rb +3 -0
  59. data/lib/new_relic/agent/monitors/inbound_request_monitor.rb +1 -1
  60. data/lib/new_relic/agent/monitors/synthetics_monitor.rb +1 -1
  61. data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +2 -2
  62. data/lib/new_relic/agent/opentelemetry/context/propagation/trace_propagator.rb +66 -0
  63. data/lib/new_relic/agent/opentelemetry/context/propagation.rb +15 -0
  64. data/lib/new_relic/agent/opentelemetry/context.rb +13 -0
  65. data/lib/new_relic/agent/opentelemetry/trace/span.rb +15 -7
  66. data/lib/new_relic/agent/opentelemetry/trace/tracer.rb +106 -15
  67. data/lib/new_relic/agent/opentelemetry/transaction_patch.rb +69 -0
  68. data/lib/new_relic/agent/opentelemetry_bridge.rb +7 -1
  69. data/lib/new_relic/agent/parameter_filtering.rb +1 -1
  70. data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -1
  71. data/lib/new_relic/agent/samplers/memory_sampler.rb +1 -1
  72. data/lib/new_relic/agent/span_event_primitive.rb +5 -0
  73. data/lib/new_relic/agent/tracer.rb +1 -1
  74. data/lib/new_relic/agent/transaction/datastore_segment.rb +1 -1
  75. data/lib/new_relic/agent/transaction/distributed_tracer.rb +3 -3
  76. data/lib/new_relic/agent/transaction/message_broker_segment.rb +1 -1
  77. data/lib/new_relic/agent/transaction/trace_context.rb +4 -4
  78. data/lib/new_relic/agent/transaction_time_aggregator.rb +1 -1
  79. data/lib/new_relic/agent/utilization/ecs.rb +22 -0
  80. data/lib/new_relic/agent/utilization/ecs_v4.rb +22 -0
  81. data/lib/new_relic/agent/utilization_data.rb +25 -0
  82. data/lib/new_relic/agent/vm/c_ruby_vm.rb +3 -3
  83. data/lib/new_relic/agent.rb +28 -0
  84. data/lib/new_relic/constants.rb +1 -0
  85. data/lib/new_relic/control/instrumentation.rb +1 -1
  86. data/lib/new_relic/dependency_detection.rb +0 -1
  87. data/lib/new_relic/helper.rb +7 -0
  88. data/lib/new_relic/version.rb +1 -1
  89. data/lib/sequel/extensions/new_relic_instrumentation.rb +1 -1
  90. data/lib/tasks/helpers/newrelicyml.rb +2 -0
  91. data/newrelic.yml +14 -14
  92. data/newrelic_rpm.gemspec +1 -1
  93. metadata +11 -6
@@ -11,7 +11,7 @@ module NewRelic
11
11
  ACTIVE_RECORD = 'ActiveRecord'.freeze
12
12
 
13
13
  module BaseExtensions
14
- if RUBY_VERSION < '2.7.0'
14
+ if NewRelic::Helper.version_satisfied?(RUBY_VERSION, '<', '2.7.0')
15
15
  def save(*args, &blk)
16
16
  ::NewRelic::Agent.with_database_metric_name(self.class.name, nil, ACTIVE_RECORD) do
17
17
  super
@@ -46,7 +46,7 @@ module NewRelic
46
46
  # Starting in v5.1.6, this call no longer happens. We'll
47
47
  # have to set the database metrics explicitly now.
48
48
  #
49
- if RUBY_VERSION < '2.7.0'
49
+ if NewRelic::Helper.version_satisfied?(RUBY_VERSION, '<', '2.7.0')
50
50
  def touch(*args, **kwargs, &blk)
51
51
  ::NewRelic::Agent.with_database_metric_name(self.class.name, nil, ACTIVE_RECORD) do
52
52
  super
@@ -11,7 +11,7 @@ DependencyDetection.defer do
11
11
 
12
12
  depends_on do
13
13
  defined?(Async::HTTP) &&
14
- Gem::Version.new(Async::HTTP::VERSION) >= Gem::Version.new('0.59.0') &&
14
+ NewRelic::Helper.version_satisfied?(Async::HTTP::VERSION, '>=', '0.59.0') &&
15
15
  !defined?(Traces::Backend::NewRelic) # defined in the traces-backend-newrelic gem
16
16
  end
17
17
 
@@ -69,7 +69,7 @@ module NewRelic::Agent::Instrumentation
69
69
  end
70
70
 
71
71
  def get_stream_name(params, arn)
72
- params&.dig(:stream_name) || arn.split('/').last || 'unknown'
72
+ params&.dig(:stream_name) || arn.split('/').last || NewRelic::UNKNOWN_LOWER
73
73
  rescue => e
74
74
  NewRelic::Agent.logger.warn("Failed to get stream name: #{e}")
75
75
  end
@@ -12,7 +12,7 @@ DependencyDetection.defer do
12
12
  depends_on do
13
13
  defined?(Concurrent) &&
14
14
  defined?(Concurrent::VERSION) &&
15
- Gem::Version.new(Concurrent::VERSION) >= Gem::Version.new('1.1.5')
15
+ NewRelic::Helper.version_satisfied?(Concurrent::VERSION, '>=', '1.1.5')
16
16
  end
17
17
 
18
18
  executes do
@@ -54,6 +54,7 @@ module NewRelic
54
54
  # Have NewRelic ignore actions in this controller. Specify the actions as hash options
55
55
  # using :except and :only. If no actions are specified, all actions are ignored.
56
56
  #
57
+ # @!scope class
57
58
  # @api public
58
59
  #
59
60
  def newrelic_ignore(specifiers = {})
@@ -65,6 +66,7 @@ module NewRelic
65
66
  # actions that are not user facing or that skew your overall apdex measurement.
66
67
  # Accepts :except and :only options, as with #newrelic_ignore.
67
68
  #
69
+ # @!scope class
68
70
  # @api public
69
71
  #
70
72
  def newrelic_ignore_apdex(specifiers = {})
@@ -72,6 +74,7 @@ module NewRelic
72
74
  newrelic_ignore_aspect(NR_IGNORE_APDEX_KEY, specifiers)
73
75
  end
74
76
 
77
+ # @!scope class
75
78
  # @api public
76
79
  def newrelic_ignore_enduser(specifiers = {})
77
80
  NewRelic::Agent.record_api_supportability_metric(:newrelic_ignore_enduser)
@@ -159,6 +162,7 @@ module NewRelic
159
162
  # See NewRelic::Agent::Instrumentation::ControllerInstrumentation#perform_action_with_newrelic_trace
160
163
  # for the full list of available options.
161
164
  #
165
+ # @!scope class
162
166
  # @api public
163
167
  #
164
168
  def add_transaction_tracer(method, options = {})
@@ -12,7 +12,7 @@ DependencyDetection.defer do
12
12
 
13
13
  depends_on do
14
14
  defined?(Curl) && defined?(Curl::CURB_VERSION) &&
15
- Gem::Version.new(Curl::CURB_VERSION) >= CURB_MIN_VERSION
15
+ NewRelic::Helper.version_satisfied?(Curl::CURB_VERSION, '>=', CURB_MIN_VERSION)
16
16
  end
17
17
 
18
18
  executes do
@@ -5,8 +5,7 @@
5
5
  module NewRelic::Agent::Instrumentation
6
6
  module Elasticsearch::Chain
7
7
  def self.instrument!
8
- to_instrument = if ::Gem::Version.create(::Elasticsearch::VERSION) <
9
- ::Gem::Version.create('8.0.0')
8
+ to_instrument = if NewRelic::Helper.version_satisfied?(::Elasticsearch::VERSION, '<', '8.0.0')
10
9
  ::Elasticsearch::Transport::Client
11
10
  else
12
11
  ::Elastic::Transport::Client
@@ -14,7 +14,7 @@ DependencyDetection.defer do
14
14
  end
15
15
 
16
16
  executes do
17
- to_instrument = if Gem::Version.create(Elasticsearch::VERSION) < Gem::Version.create('8.0.0')
17
+ to_instrument = if NewRelic::Helper.version_satisfied?(Elasticsearch::VERSION, '<', '8.0.0')
18
18
  Elasticsearch::Transport::Client
19
19
  else
20
20
  Elastic::Transport::Client
@@ -18,7 +18,7 @@ DependencyDetection.defer do
18
18
  end
19
19
 
20
20
  depends_on do
21
- defined?(Ethon) && Gem::Version.new(Ethon::VERSION) >= Gem::Version.new('0.12.0')
21
+ defined?(Ethon) && NewRelic::Helper.version_satisfied?(Ethon::VERSION, '>=', '0.12.0')
22
22
  end
23
23
 
24
24
  executes do
@@ -26,7 +26,7 @@ DependencyDetection.defer do
26
26
 
27
27
  executes do
28
28
  excon_version = Gem::Version.new(Excon::VERSION)
29
- if excon_version >= EXCON_MIN_VERSION
29
+ if NewRelic::Helper.version_satisfied?(excon_version, '>=', EXCON_MIN_VERSION)
30
30
  install_excon_instrumentation(excon_version)
31
31
  else
32
32
  NewRelic::Agent.logger.warn("Excon instrumentation requires at least version #{EXCON_MIN_VERSION}")
@@ -10,7 +10,7 @@ module NewRelic::Agent::Instrumentation
10
10
 
11
11
  alias_method(:initialize_without_new_relic, :initialize)
12
12
 
13
- if RUBY_VERSION < '2.7.0'
13
+ if NewRelic::Helper.version_satisfied?(RUBY_VERSION, '<', '2.7.0')
14
14
  def initialize(*_args, &block)
15
15
  traced_block = add_thread_tracing(&block)
16
16
  initialize_with_newrelic_tracing { initialize_without_new_relic(&traced_block) }
@@ -9,7 +9,7 @@ module NewRelic::Agent::Instrumentation
9
9
  module Prepend
10
10
  include NewRelic::Agent::Instrumentation::MonitoredFiber
11
11
 
12
- if RUBY_VERSION < '2.7.0'
12
+ if NewRelic::Helper.version_satisfied?(RUBY_VERSION, '<', '2.7.0')
13
13
  def initialize(*_args, &block)
14
14
  traced_block = add_thread_tracing(&block)
15
15
  initialize_with_newrelic_tracing { super(&traced_block) }
@@ -16,10 +16,7 @@ DependencyDetection.defer do
16
16
  end
17
17
 
18
18
  depends_on do
19
- minimum_supported_version = Gem::Version.new(HTTPCLIENT_MIN_VERSION)
20
- current_version = Gem::Version.new(HTTPClient::VERSION)
21
-
22
- current_version >= minimum_supported_version
19
+ NewRelic::Helper.version_satisfied?(HTTPClient::VERSION, '>=', HTTPCLIENT_MIN_VERSION)
23
20
  end
24
21
 
25
22
  executes do
@@ -30,7 +30,7 @@ module NewRelic::Agent::Instrumentation::HTTPX
30
30
 
31
31
  def nr_finish_segment
32
32
  proc do |request, segment|
33
- response = @responses[request]
33
+ response = request.response if request
34
34
 
35
35
  unless response
36
36
  NewRelic::Agent.logger.debug('Processed an on-response callback for HTTPX but could not find the response!')
@@ -10,7 +10,7 @@ DependencyDetection.defer do
10
10
  named :httpx
11
11
 
12
12
  depends_on do
13
- defined?(HTTPX) && Gem::Version.new(HTTPX::VERSION) >= Gem::Version.new('1.0.0')
13
+ defined?(HTTPX) && NewRelic::Helper.version_satisfied?(HTTPX::VERSION, '>=', '1.0.0')
14
14
  end
15
15
 
16
16
  executes do
@@ -11,7 +11,7 @@ DependencyDetection.defer do
11
11
 
12
12
  depends_on do
13
13
  defined?(LogStasher) &&
14
- Gem::Version.new(LogStasher::VERSION) >= Gem::Version.new('1.0.0') &&
14
+ NewRelic::Helper.version_satisfied?(LogStasher::VERSION, '>=', '1.0.0') &&
15
15
  NewRelic::Agent.config[:'application_logging.enabled']
16
16
  end
17
17
 
@@ -61,7 +61,7 @@ module NewRelic
61
61
  # TODO: MAJOR VERSION
62
62
  # Dalli - 3.1.0 renamed send_multiget to pipelined_get, but the method is otherwise the same
63
63
  # Once we no longer support Dalli < 3.1.0, remove this conditional logic
64
- if Gem::Version.new(::Dalli::VERSION) >= Gem::Version.new('3.1.0')
64
+ if NewRelic::Helper.version_satisfied?(::Dalli::VERSION, '>=', '3.1.0')
65
65
  alias_method(:pipelined_get_without_newrelic_trace, :pipelined_get)
66
66
  def pipelined_get(keys)
67
67
  send_multiget_with_newrelic_tracing(keys) { pipelined_get_without_newrelic_trace(keys) }
@@ -9,11 +9,11 @@ module NewRelic::Agent::Instrumentation
9
9
  BINARY_PROTOCOL_SUPPORTED_VERSION = Gem::Version.new('3.0.2')
10
10
 
11
11
  def supports_datastore_instances?
12
- DATASTORE_INSTANCES_SUPPORTED_VERSION <= Gem::Version.new(::Dalli::VERSION)
12
+ NewRelic::Helper.version_satisfied?(DATASTORE_INSTANCES_SUPPORTED_VERSION, '<=', ::Dalli::VERSION)
13
13
  end
14
14
 
15
15
  def supports_binary_protocol?
16
- BINARY_PROTOCOL_SUPPORTED_VERSION <= Gem::Version.new(::Dalli::VERSION)
16
+ NewRelic::Helper.version_satisfied?(BINARY_PROTOCOL_SUPPORTED_VERSION, '<=', ::Dalli::VERSION)
17
17
  end
18
18
 
19
19
  def client_methods
@@ -6,7 +6,7 @@ module NewRelic::Agent::Instrumentation
6
6
  module Memcache
7
7
  module Tracer
8
8
  SLASH = '/'
9
- UNKNOWN = 'unknown'
9
+ UNKNOWN = NewRelic::UNKNOWN_LOWER
10
10
  LOCALHOST = 'localhost'
11
11
  MULTIGET_METRIC_NAME = 'get_multi_request'
12
12
  MEMCACHED = 'Memcached'
@@ -87,7 +87,7 @@ module NewRelic::Agent::Instrumentation
87
87
  # TODO: MAJOR VERSION
88
88
  # Dalli - 3.1.0 renamed send_multiget to pipelined_get, but the method is otherwise the same
89
89
  # Once we no longer support Dalli < 3.1.0, remove this conditional logic
90
- if Gem::Version.new(::Dalli::VERSION) >= Gem::Version.new('3.1.0')
90
+ if NewRelic::Helper.version_satisfied?(::Dalli::VERSION, '>=', '3.1.0')
91
91
  def pipelined_get(keys)
92
92
  send_multiget_with_newrelic_tracing(keys) { super }
93
93
  end
@@ -106,7 +106,7 @@ module NewRelic
106
106
  )
107
107
  end
108
108
 
109
- UNKNOWN = 'unknown'.freeze
109
+ UNKNOWN = NewRelic::UNKNOWN_LOWER
110
110
  LOCALHOST = 'localhost'.freeze
111
111
 
112
112
  def host_from_address(address)
@@ -19,7 +19,8 @@ DependencyDetection.defer do
19
19
 
20
20
  # Airbrake uses method chaining on Net::HTTP in versions < 10.0.2 (10.0.2 updated to prepend for Net:HTTP)
21
21
  conflicts_with_prepend do
22
- defined?(Airbrake) && defined?(Airbrake::AIRBRAKE_VERSION) && Gem::Version.create(Airbrake::AIRBRAKE_VERSION) < Gem::Version.create('10.0.2')
22
+ defined?(Airbrake) && defined?(Airbrake::AIRBRAKE_VERSION) &&
23
+ NewRelic::Helper.version_satisfied?(Airbrake::AIRBRAKE_VERSION, '<', '10.0.2')
23
24
  end
24
25
 
25
26
  conflicts_with_prepend do
@@ -12,7 +12,7 @@ DependencyDetection.defer do
12
12
  configure_with :rake
13
13
 
14
14
  depends_on { defined?(Rake) && defined?(Rake::VERSION) }
15
- depends_on { Gem::Version.new(Rake::VERSION) >= Gem::Version.new('10.0.0') }
15
+ depends_on { NewRelic::Helper.version_satisfied?(Rake::VERSION, '>=', '10.0.0') }
16
16
  depends_on { NewRelic::Agent.config[:'rake.tasks'].any? }
17
17
  depends_on { NewRelic::Agent::Instrumentation::Rake.safe_from_third_party_gem? }
18
18
 
@@ -40,8 +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') ||
44
- (Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0'))
43
+ if NewRelic::Helper.version_satisfied?(::Rdkafka::VERSION, '>=', '0.16.0') ||
44
+ NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '2.7.0')
45
45
  def producer(**kwargs)
46
46
  producer_without_new_relic(**kwargs).tap do |producer|
47
47
  set_nr_config(producer)
@@ -36,8 +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')) ||
40
- (Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0'))
39
+ if (defined?(::Rdkafka) && NewRelic::Helper.version_satisfied?(::Rdkafka::VERSION, '>=', '0.16.0')) ||
40
+ NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '2.7.0')
41
41
  def producer(**kwargs)
42
42
  super.tap do |producer|
43
43
  set_nr_config(producer)
@@ -6,12 +6,12 @@ module NewRelic::Agent::Instrumentation::Redis
6
6
  class Constants
7
7
  PRODUCT_NAME = 'Redis'
8
8
  CONNECT = 'connect'
9
- UNKNOWN = 'unknown'
9
+ UNKNOWN = NewRelic::UNKNOWN_LOWER
10
10
  LOCALHOST = 'localhost'
11
11
  MULTI_OPERATION = 'multi'
12
12
  PIPELINE_OPERATION = 'pipeline'
13
13
  HAS_REDIS_CLIENT = defined?(::Redis) &&
14
- Gem::Version.new(::Redis::VERSION) >= Gem::Version.new('5.0.0') &&
14
+ NewRelic::Helper.version_satisfied?(::Redis::VERSION, '>=', '5.0.0') &&
15
15
  !defined?(::RedisClient).nil?
16
16
  end
17
17
  end
@@ -15,7 +15,7 @@ DependencyDetection.defer do
15
15
 
16
16
  # Airbrake uses method chaining on Resque::Job on versions < 11.0.3
17
17
  conflicts_with_prepend do
18
- defined?(Airbrake) && defined?(Airbrake::AIRBRAKE_VERSION) && Gem::Version.create(Airbrake::AIRBRAKE_VERSION) < Gem::Version.create('11.0.3')
18
+ defined?(Airbrake) && defined?(Airbrake::AIRBRAKE_VERSION) && NewRelic::Helper.version_satisfied?(Airbrake::AIRBRAKE_VERSION, '<', '11.0.3')
19
19
  end
20
20
 
21
21
  executes do
@@ -25,7 +25,7 @@ DependencyDetection.defer do
25
25
  # we don't believe this lib is still necessary for Ruby 3.4 users.
26
26
  # however, if we receive customer feedback to the contrary, we can find
27
27
  # an alternate approach.
28
- Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.4')
28
+ NewRelic::Helper.version_satisfied?(RUBY_VERSION, '<', '3.4')
29
29
  NewRelic::Agent.logger.info('Requiring resolv-replace')
30
30
  require 'resolv'
31
31
  require 'resolv-replace'
@@ -11,7 +11,7 @@ DependencyDetection.defer do
11
11
 
12
12
  depends_on do
13
13
  defined?(Roda) &&
14
- Gem::Version.new(Roda::RodaVersion) >= Gem::Version.new('3.19.0') &&
14
+ NewRelic::Helper.version_satisfied?(Roda::RodaVersion, '>=', '3.19.0') &&
15
15
  Roda::RodaPlugins::Base::ClassMethods.private_method_defined?(:build_rack_app) &&
16
16
  Roda::RodaPlugins::Base::InstanceMethods.method_defined?(:_roda_handle_main_route)
17
17
  end
@@ -20,7 +20,7 @@ module NewRelic::Agent::Instrumentation
20
20
  module Prepend
21
21
  include NewRelic::Agent::Instrumentation::RubyKafka
22
22
 
23
- if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3')
23
+ if NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '3')
24
24
  def each_message(**args)
25
25
  super do |message|
26
26
  each_message_with_new_relic(message) do
@@ -12,13 +12,13 @@ DependencyDetection.defer do
12
12
  depends_on do
13
13
  NewRelic::Agent.config[:'ai_monitoring.enabled'] &&
14
14
  defined?(OpenAI) && defined?(OpenAI::Client) &&
15
- Gem::Version.new(OpenAI::VERSION) >= Gem::Version.new('3.4.0')
15
+ NewRelic::Helper.version_satisfied?(OpenAI::VERSION, '>=', '3.4.0')
16
16
  end
17
17
 
18
18
  executes do
19
19
  if use_prepend?
20
20
  # TODO: Remove condition when we drop support for versions below 5.0.0
21
- if Gem::Version.new(OpenAI::VERSION) >= Gem::Version.new('5.0.0')
21
+ if NewRelic::Helper.version_satisfied?(OpenAI::VERSION, '>=', '5.0.0')
22
22
  prepend_instrument OpenAI::Client,
23
23
  NewRelic::Agent::Instrumentation::OpenAI::Prepend,
24
24
  NewRelic::Agent::Instrumentation::OpenAI::VENDOR
@@ -8,7 +8,7 @@
8
8
  #
9
9
  # see https://github.com/sidekiq/sidekiq/issues/5076 for the discussion
10
10
  # of the removal, which includes mentions of alternatives
11
- if defined?(Sidekiq::VERSION) && Sidekiq::VERSION < '7.0.0'
11
+ if defined?(Sidekiq::VERSION) && NewRelic::Helper.version_satisfied?(Sidekiq::VERSION, '<', '7.0.0')
12
12
  class Sidekiq::Extensions::DelayedClass
13
13
  def newrelic_trace_args(msg, queue)
14
14
  (target, method_name, _args) = if YAML.respond_to?(:unsafe_load)
@@ -13,7 +13,7 @@ DependencyDetection.defer do
13
13
 
14
14
  depends_on do
15
15
  defined?(Stripe) &&
16
- Gem::Version.new(Stripe::VERSION) >= Gem::Version.new('5.38.0')
16
+ NewRelic::Helper.version_satisfied?(Stripe::VERSION, '>=', '5.38.0')
17
17
  end
18
18
 
19
19
  executes do
@@ -8,11 +8,11 @@ module NewRelic
8
8
  module Typhoeus
9
9
  HYDRA_SEGMENT_NAME = 'External/Multiple/Typhoeus::Hydra/run'
10
10
  NOTICEABLE_ERROR_CLASS = 'Typhoeus::Errors::TyphoeusError'
11
- EARLIEST_VERSION = Gem::Version.new('0.5.3')
11
+ EARLIEST_VERSION = '0.5.3'
12
12
  INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
13
13
 
14
14
  def self.is_supported_version?
15
- Gem::Version.new(::Typhoeus::VERSION) >= EARLIEST_VERSION
15
+ NewRelic::Helper.version_satisfied?(::Typhoeus::VERSION, '>=', EARLIEST_VERSION)
16
16
  end
17
17
 
18
18
  def self.request_is_hydra_enabled?(request)
@@ -32,7 +32,7 @@ module NewRelic
32
32
  # TODO: OLD RUBIES < 2.6
33
33
  # Hash#merge accepts multiple arguments in 2.6
34
34
  # Remove condition once support for Ruby <2.6 is dropped
35
- if RUBY_VERSION >= '2.6.0'
35
+ if NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '2.6.0')
36
36
  LlmEvent::ATTRIBUTE_NAME_EXCEPTIONS.merge(ResponseHeaders::ATTRIBUTE_NAME_EXCEPTIONS, ATTRIBUTE_NAME_EXCEPTIONS)
37
37
  else
38
38
  LlmEvent::ATTRIBUTE_NAME_EXCEPTIONS.merge(ResponseHeaders::ATTRIBUTE_NAME_EXCEPTIONS).merge(ATTRIBUTE_NAME_EXCEPTIONS)
@@ -25,7 +25,7 @@ module NewRelic
25
25
  # TODO: OLD RUBIES < 2.6
26
26
  # Hash#merge accepts multiple arguments in 2.6
27
27
  # Remove condition once support for Ruby <2.6 is dropped
28
- if RUBY_VERSION >= '2.6.0'
28
+ if NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '2.6.0')
29
29
  LlmEvent::ATTRIBUTE_NAME_EXCEPTIONS.merge(ResponseHeaders::ATTRIBUTE_NAME_EXCEPTIONS, ATTRIBUTE_NAME_EXCEPTIONS)
30
30
  else
31
31
  LlmEvent::ATTRIBUTE_NAME_EXCEPTIONS.merge(ResponseHeaders::ATTRIBUTE_NAME_EXCEPTIONS).merge(ATTRIBUTE_NAME_EXCEPTIONS)
@@ -43,7 +43,7 @@ module NewRelic
43
43
  # URI version 1.0+ will ship with Ruby 3.4
44
44
  # Once we drop support for Rubies below 3.4, we can use the
45
45
  # URI::RFC2396 parser exclusively.
46
- if Gem::Version.new(URI::VERSION) >= Gem::Version.new('1.0')
46
+ if NewRelic::Helper.version_satisfied?(URI::VERSION, '>=', '1.0')
47
47
  URI::RFC2396_PARSER.escape(entity_name)
48
48
  else
49
49
  URI::DEFAULT_PARSER.escape(entity_name)
@@ -165,7 +165,7 @@ module NewRelic
165
165
  # Positional and Keyword arguments are separated beginning with Ruby 2.7
166
166
  # Signature of ::Logger constructor changes in Ruby 2.4 to have both positional and keyword args
167
167
  # We pivot on Ruby 2.7 for widest supportability with least amount of hassle.
168
- if RUBY_VERSION < '2.7.0'
168
+ if NewRelic::Helper.version_satisfied?(RUBY_VERSION, '<', '2.7.0')
169
169
  def initialize(*args)
170
170
  super(*args)
171
171
  self.formatter = DecoratingFormatter.new
@@ -49,6 +49,7 @@ module NewRelic
49
49
  #
50
50
  # @return [NewRelic::Agent::Transaction::MessageBrokerSegment]
51
51
  #
52
+ # @!scope class
52
53
  # @api public
53
54
  #
54
55
  def start_message_broker_segment(action: nil,
@@ -107,6 +108,7 @@ module NewRelic
107
108
  # @return return value of given block, which will be the same as the
108
109
  # return value of an un-instrumented subscribed callback
109
110
  #
111
+ # @!scope class
110
112
  # @api public
111
113
  #
112
114
  def wrap_message_broker_consume_transaction(library:,
@@ -180,6 +182,7 @@ module NewRelic
180
182
  #
181
183
  # @return [NewRelic::Agent::Transaction::MessageBrokerSegment]
182
184
  #
185
+ # @!scope class
183
186
  # @api public
184
187
  #
185
188
  def start_amqp_publish_segment(library:,
@@ -240,6 +243,7 @@ module NewRelic
240
243
  #
241
244
  # @return [NewRelic::Agent::Transaction::MessageBrokerSegment]
242
245
  #
246
+ # @!scope class
243
247
  # @api public
244
248
  #
245
249
  def start_amqp_consume_segment(library:,
@@ -301,6 +305,7 @@ module NewRelic
301
305
  # @return return value of given block, which will be the same as the
302
306
  # return value of an un-instrumented subscribed callback
303
307
  #
308
+ # @!scope class
304
309
  # @api public
305
310
  #
306
311
  def wrap_amqp_consume_transaction(library: nil,
@@ -65,6 +65,7 @@ module NewRelic
65
65
  # categories, but generally this *should never ever be done*. Most of the time you can aggregate
66
66
  # on the server.
67
67
  #
68
+ # @!scope class
68
69
  # @api public
69
70
  #
70
71
  def trace_execution_scoped(metric_names, options = NewRelic::EMPTY_HASH) # THREAD_LOCAL_ACCESS
@@ -81,6 +82,7 @@ module NewRelic
81
82
  #
82
83
  # * <tt>metric_names</tt> is a single name or an array of names of metrics
83
84
  #
85
+ # @!scope class
84
86
  # @api public
85
87
  #
86
88
  def trace_execution_unscoped(metric_names, options = NewRelic::EMPTY_HASH) # THREAD_LOCAL_ACCESS
@@ -241,6 +243,7 @@ module NewRelic
241
243
  # # Instrument foo in transaction traces only
242
244
  # add_method_tracer :foo, 'Custom/foo', :metric => false
243
245
  #
246
+ # @!scope class
244
247
  # @api public
245
248
  #
246
249
  def add_method_tracer(method_name, metric_name = nil, options = {})
@@ -32,7 +32,7 @@ module NewRelic
32
32
 
33
33
  def deserialize_header(encoded_header, key)
34
34
  decoded_header = obfuscator.deobfuscate(encoded_header)
35
- ::JSON.load(decoded_header)
35
+ ::JSON.parse(decoded_header)
36
36
  rescue => err
37
37
  # If we have a failure of any type here, just return nil and carry on
38
38
  NewRelic::Agent.logger.debug("Failure deserializing encoded header '#{key}' in #{self.class}, #{err.class}, #{err.message}")
@@ -35,7 +35,7 @@ module NewRelic
35
35
  end
36
36
 
37
37
  def load_json(header, key)
38
- ::JSON.load(header)
38
+ ::JSON.parse(header)
39
39
  rescue => err
40
40
  NewRelic::Agent.logger.debug("Failure loading json header '#{key}' in #{self.class}, #{err.class}, #{err.message}")
41
41
  nil
@@ -19,7 +19,7 @@ module NewRelic
19
19
  def warn_for_yajl
20
20
  if defined?(::Yajl)
21
21
  require 'yajl/version'
22
- if Gem::Version.new(::Yajl::VERSION) < OK_YAJL_VERSION
22
+ if NewRelic::Helper.version_satisfied?(::Yajl::VERSION, '<', OK_YAJL_VERSION)
23
23
  ::NewRelic::Agent.logger.warn("Detected yajl-ruby version #{::Yajl::VERSION} which can cause segfaults with newrelic_rpm's thread profiling features. We strongly recommend you upgrade to the latest yajl-ruby version available.")
24
24
  end
25
25
  end
@@ -42,7 +42,7 @@ module NewRelic
42
42
  return nil
43
43
  end
44
44
 
45
- return_value(::JSON.load(data))
45
+ return_value(::JSON.parse(data))
46
46
  rescue => e
47
47
  ::NewRelic::Agent.logger.debug("#{e.class.name} : #{e.message} encountered loading collector response: #{data}")
48
48
  raise
@@ -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
6
+ module Agent
7
+ module OpenTelemetry
8
+ module Context
9
+ module Propagation
10
+ class TracePropagator
11
+ # The carrier is the object carrying the headers
12
+ # The context argument is a no-op, as the OpenTelemetry context is not used
13
+ # The setter argument is a no-op, added for consistency with the OpenTelemetry API
14
+ def inject(carrier, context: ::OpenTelemetry::Context.current, setter: nil)
15
+ # TODO: determine if we need to update this method to take Context into account
16
+ NewRelic::Agent::DistributedTracing.insert_distributed_trace_headers(carrier)
17
+ end
18
+
19
+ # The return value for this method should be an instance of the
20
+ # OpenTelemetry Context class. The return value of
21
+ # #accept_distributed_trace_headers is a transaction, so we cannot
22
+ # use it to extract the context.
23
+ def extract(carrier, context: ::OpenTelemetry::Context.current, getter: ::OpenTelemetry::Context::Propagation.text_map_getter)
24
+ carrier_format = determine_format(getter)
25
+ trace_context = NewRelic::Agent::DistributedTracing::TraceContext.parse(
26
+ carrier: carrier,
27
+ format: carrier_format,
28
+ trace_state_entry_key: Transaction::TraceContext::AccountHelpers.trace_state_entry_key
29
+ )
30
+ tp = trace_context.trace_parent
31
+ span_context = ::OpenTelemetry::Trace::SpanContext.new(
32
+ trace_id: tp['trace_id'],
33
+ span_id: tp['parent_id'],
34
+ trace_flags: tp['trace_flags'],
35
+ tracestate: trace_context.trace_state_payload,
36
+ remote: true
37
+ )
38
+ span = ::OpenTelemetry::Trace.non_recording_span(span_context)
39
+
40
+ ::OpenTelemetry::Trace.context_with_span(span, parent_context: context)
41
+ rescue StandardError => e
42
+ NewRelic::Agent.logger.error("Unable to extract context: #{e.message}")
43
+ context
44
+ end
45
+
46
+ private
47
+
48
+ # The getter is the way OpenTelemetry handles Rack vs. non-Rack
49
+ # formats. Rather than using their parser, get the class info we
50
+ # need to do things the New Relic way
51
+ def determine_format(getter)
52
+ case getter
53
+ when ::OpenTelemetry::Context::Propagation::RackEnvGetter
54
+ FORMAT_RACK
55
+ when defined?(::OpenTelemetry::Common) && ::OpenTelemetry::Common::Propagation::RackEnvGetter
56
+ FORMAT_RACK
57
+ else
58
+ FORMAT_NON_RACK
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end