newrelic_rpm 9.12.0 → 9.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +120 -0
  3. data/README.md +16 -20
  4. data/lib/new_relic/agent/configuration/default_source.rb +112 -3
  5. data/lib/new_relic/agent/configuration/environment_source.rb +5 -1
  6. data/lib/new_relic/agent/configuration/manager.rb +23 -0
  7. data/lib/new_relic/agent/database/obfuscation_helpers.rb +11 -11
  8. data/lib/new_relic/agent/instrumentation/active_merchant.rb +0 -13
  9. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +0 -19
  10. data/lib/new_relic/agent/instrumentation/dynamodb/instrumentation.rb +3 -2
  11. data/lib/new_relic/agent/instrumentation/excon.rb +0 -16
  12. data/lib/new_relic/agent/instrumentation/grape.rb +3 -1
  13. data/lib/new_relic/agent/instrumentation/opensearch/chain.rb +21 -0
  14. data/lib/new_relic/agent/instrumentation/opensearch/instrumentation.rb +66 -0
  15. data/lib/new_relic/agent/instrumentation/opensearch/prepend.rb +13 -0
  16. data/lib/new_relic/agent/instrumentation/opensearch.rb +25 -0
  17. data/lib/new_relic/agent/instrumentation/rdkafka/chain.rb +71 -0
  18. data/lib/new_relic/agent/instrumentation/rdkafka/instrumentation.rb +70 -0
  19. data/lib/new_relic/agent/instrumentation/rdkafka/prepend.rb +66 -0
  20. data/lib/new_relic/agent/instrumentation/rdkafka.rb +27 -0
  21. data/lib/new_relic/agent/instrumentation/redis.rb +7 -5
  22. data/lib/new_relic/agent/instrumentation/ruby_kafka/chain.rb +55 -0
  23. data/lib/new_relic/agent/instrumentation/ruby_kafka/instrumentation.rb +67 -0
  24. data/lib/new_relic/agent/instrumentation/ruby_kafka/prepend.rb +50 -0
  25. data/lib/new_relic/agent/instrumentation/ruby_kafka.rb +27 -0
  26. data/lib/new_relic/agent/instrumentation/sidekiq.rb +0 -14
  27. data/lib/new_relic/agent/instrumentation/sinatra.rb +0 -13
  28. data/lib/new_relic/agent/instrumentation/view_component/instrumentation.rb +4 -1
  29. data/lib/new_relic/agent/javascript_instrumentor.rb +2 -3
  30. data/lib/new_relic/agent/messaging.rb +11 -5
  31. data/lib/new_relic/agent/serverless_handler.rb +241 -12
  32. data/lib/new_relic/agent/serverless_handler_event_sources.json +155 -0
  33. data/lib/new_relic/agent/serverless_handler_event_sources.rb +49 -0
  34. data/lib/new_relic/agent/system_info.rb +14 -0
  35. data/lib/new_relic/agent/transaction/request_attributes.rb +13 -1
  36. data/lib/new_relic/agent/transaction/trace_context.rb +1 -1
  37. data/lib/new_relic/agent.rb +93 -0
  38. data/lib/new_relic/control/frameworks/grape.rb +14 -0
  39. data/lib/new_relic/control/frameworks/padrino.rb +14 -0
  40. data/lib/new_relic/control/frameworks/rails4.rb +4 -2
  41. data/lib/new_relic/environment_report.rb +6 -2
  42. data/lib/new_relic/language_support.rb +7 -1
  43. data/lib/new_relic/local_environment.rb +1 -4
  44. data/lib/new_relic/version.rb +1 -1
  45. data/lib/tasks/helpers/newrelicyml.rb +73 -11
  46. data/lib/tasks/instrumentation_generator/instrumentation.thor +1 -1
  47. data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +3 -3
  48. data/newrelic.yml +118 -54
  49. metadata +19 -3
@@ -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
@@ -0,0 +1,71 @@
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 'instrumentation'
6
+
7
+ module NewRelic::Agent::Instrumentation
8
+ module Rdkafka::Chain
9
+ def self.instrument!
10
+ ::Rdkafka::Producer.class_eval do
11
+ include NewRelic::Agent::Instrumentation::Rdkafka
12
+
13
+ alias_method(:produce_without_new_relic, :produce)
14
+
15
+ def produce(**kwargs)
16
+ produce_with_new_relic(kwargs) do |headers|
17
+ kwargs[:headers] = headers
18
+ produce_without_new_relic(**kwargs)
19
+ end
20
+ end
21
+ end
22
+
23
+ ::Rdkafka::Consumer.class_eval do
24
+ include NewRelic::Agent::Instrumentation::Rdkafka
25
+
26
+ alias_method(:each_without_new_relic, :each)
27
+
28
+ def each(**kwargs)
29
+ each_without_new_relic(**kwargs) do |message|
30
+ each_with_new_relic(message) do
31
+ yield(message)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ ::Rdkafka::Config.class_eval do
38
+ include NewRelic::Agent::Instrumentation::RdkafkaConfig
39
+
40
+ alias_method(:producer_without_new_relic, :producer)
41
+ alias_method(:consumer_without_new_relic, :consumer)
42
+
43
+ if Gem::Version.new(::Rdkafka::VERSION) >= Gem::Version.new('0.16.0')
44
+ def producer(**kwargs)
45
+ producer_without_new_relic(**kwargs).tap do |producer|
46
+ set_nr_config(producer)
47
+ end
48
+ end
49
+
50
+ def consumer(**kwargs)
51
+ consumer_without_new_relic(**kwargs).tap do |consumer|
52
+ set_nr_config(consumer)
53
+ end
54
+ end
55
+ else
56
+ def producer
57
+ producer_without_new_relic.tap do |producer|
58
+ set_nr_config(producer)
59
+ end
60
+ end
61
+
62
+ def consumer
63
+ consumer_without_new_relic.tap do |consumer|
64
+ set_nr_config(consumer)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,70 @@
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 'new_relic/agent/messaging'
6
+
7
+ module NewRelic::Agent::Instrumentation
8
+ module Rdkafka
9
+ MESSAGING_LIBRARY = 'Kafka'
10
+ PRODUCE = 'Produce'
11
+ CONSUME = 'Consume'
12
+
13
+ INSTRUMENTATION_NAME = 'Rdkafka'
14
+
15
+ def produce_with_new_relic(*args)
16
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
17
+
18
+ topic_name = args[0][:topic]
19
+ segment = NewRelic::Agent::Tracer.start_message_broker_segment(
20
+ action: :produce,
21
+ library: MESSAGING_LIBRARY,
22
+ destination_type: :topic,
23
+ destination_name: topic_name
24
+ )
25
+ create_kafka_metrics(action: PRODUCE, topic: topic_name)
26
+
27
+ headers = args[0][:headers] || {}
28
+ ::NewRelic::Agent::DistributedTracing.insert_distributed_trace_headers(headers)
29
+
30
+ NewRelic::Agent::Tracer.capture_segment_error(segment) { yield(headers) }
31
+ ensure
32
+ segment&.finish
33
+ end
34
+
35
+ def each_with_new_relic(message)
36
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
37
+
38
+ headers = message&.headers || {}
39
+ topic_name = message&.topic
40
+
41
+ NewRelic::Agent::Messaging.wrap_message_broker_consume_transaction(
42
+ library: MESSAGING_LIBRARY,
43
+ destination_type: :topic,
44
+ destination_name: topic_name,
45
+ headers: headers,
46
+ action: :consume
47
+ ) do
48
+ create_kafka_metrics(action: CONSUME, topic: topic_name)
49
+ yield
50
+ end
51
+ end
52
+
53
+ def create_kafka_metrics(action:, topic:)
54
+ hosts = []
55
+ # both 'bootstrap.servers' and 'metadata.broker.list' are valid ways to specify the Kafka server
56
+ hosts << @nr_config[:'bootstrap.servers'] if @nr_config[:'bootstrap.servers']
57
+ hosts << @nr_config[:'metadata.broker.list'] if @nr_config[:'metadata.broker.list']
58
+ hosts.each do |host|
59
+ NewRelic::Agent.record_metric("MessageBroker/Kafka/Nodes/#{host}/#{action}/#{topic}", 1)
60
+ NewRelic::Agent.record_metric("MessageBroker/Kafka/Nodes/#{host}", 1)
61
+ end
62
+ end
63
+ end
64
+
65
+ module RdkafkaConfig
66
+ def set_nr_config(producer_or_consumer)
67
+ producer_or_consumer.instance_variable_set(:@nr_config, self)
68
+ end
69
+ end
70
+ 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
+ require_relative 'instrumentation'
6
+
7
+ module NewRelic::Agent::Instrumentation
8
+ module RdkafkaProducer
9
+ module Prepend
10
+ include NewRelic::Agent::Instrumentation::Rdkafka
11
+
12
+ def produce(**kwargs)
13
+ produce_with_new_relic(kwargs) do |headers|
14
+ kwargs[:headers] = headers
15
+ super
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ module RdkafkaConsumer
22
+ module Prepend
23
+ include NewRelic::Agent::Instrumentation::Rdkafka
24
+
25
+ def each
26
+ super do |message|
27
+ each_with_new_relic(message) do
28
+ yield(message)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ module RdkafkaConfig
36
+ module Prepend
37
+ include NewRelic::Agent::Instrumentation::RdkafkaConfig
38
+
39
+ if defined?(::Rdkafka) && Gem::Version.new(::Rdkafka::VERSION) >= Gem::Version.new('0.16.0')
40
+ def producer(**kwargs)
41
+ super.tap do |producer|
42
+ set_nr_config(producer)
43
+ end
44
+ end
45
+
46
+ def consumer(**kwargs)
47
+ super.tap do |consumer|
48
+ set_nr_config(consumer)
49
+ end
50
+ end
51
+ else # older versions
52
+ def producer
53
+ super.tap do |producer|
54
+ set_nr_config(producer)
55
+ end
56
+ end
57
+
58
+ def consumer
59
+ super.tap do |consumer|
60
+ set_nr_config(consumer)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ 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
+ DependencyDetection.defer do
6
+ named :rdkafka
7
+
8
+ depends_on do
9
+ defined?(Rdkafka)
10
+ end
11
+
12
+ executes do
13
+ NewRelic::Agent.logger.info('Installing rdkafka instrumentation')
14
+
15
+ require_relative 'rdkafka/instrumentation'
16
+ require_relative 'rdkafka/chain'
17
+ require_relative 'rdkafka/prepend'
18
+
19
+ if use_prepend?
20
+ prepend_instrument Rdkafka::Config, NewRelic::Agent::Instrumentation::RdkafkaConfig::Prepend
21
+ prepend_instrument Rdkafka::Producer, NewRelic::Agent::Instrumentation::RdkafkaProducer::Prepend
22
+ prepend_instrument Rdkafka::Consumer, NewRelic::Agent::Instrumentation::RdkafkaConsumer::Prepend
23
+ else
24
+ chain_instrument NewRelic::Agent::Instrumentation::Rdkafka::Chain
25
+ end
26
+ end
27
+ end
@@ -36,14 +36,16 @@ DependencyDetection.defer do
36
36
  RedisClient.register(NewRelic::Agent::Instrumentation::RedisClient::Middleware)
37
37
 
38
38
  if defined?(Redis::Cluster::Client)
39
- return RedisClient.register(NewRelic::Agent::Instrumentation::RedisClient::ClusterMiddleware)
39
+ RedisClient.register(NewRelic::Agent::Instrumentation::RedisClient::ClusterMiddleware)
40
40
  end
41
41
  end
42
42
 
43
- if use_prepend?
44
- prepend_instrument Redis::Client, NewRelic::Agent::Instrumentation::Redis::Prepend
45
- else
46
- 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
47
49
  end
48
50
  end
49
51
  end
@@ -0,0 +1,55 @@
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 RubyKafka::Chain
7
+ def self.instrument!
8
+ ::Kafka::Producer.class_eval do
9
+ include NewRelic::Agent::Instrumentation::RubyKafka
10
+
11
+ alias_method(:produce_without_new_relic, :produce)
12
+
13
+ def produce(value, **kwargs)
14
+ produce_with_new_relic(value, **kwargs) do |headers|
15
+ kwargs[:headers] = headers
16
+ produce_without_new_relic(value, **kwargs)
17
+ end
18
+ end
19
+ end
20
+
21
+ ::Kafka::Consumer.class_eval do
22
+ include NewRelic::Agent::Instrumentation::RubyKafka
23
+
24
+ alias_method(:each_message_without_new_relic, :each_message)
25
+
26
+ def each_message(*args)
27
+ each_message_without_new_relic(*args) do |message|
28
+ each_message_with_new_relic(message) do
29
+ yield(message)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ ::Kafka::Client.class_eval do
36
+ include NewRelic::Agent::Instrumentation::RubyKafkaConfig
37
+
38
+ alias_method(:producer_without_new_relic, :producer)
39
+ alias_method(:consumer_without_new_relic, :consumer)
40
+
41
+ def producer(**kwargs)
42
+ producer_without_new_relic(**kwargs).tap do |producer|
43
+ set_nr_config(producer)
44
+ end
45
+ end
46
+
47
+ def consumer(**kwargs)
48
+ consumer_without_new_relic(**kwargs).tap do |consumer|
49
+ set_nr_config(consumer)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,67 @@
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 'new_relic/agent/messaging'
6
+
7
+ module NewRelic::Agent::Instrumentation
8
+ module RubyKafka
9
+ MESSAGING_LIBRARY = 'Kafka'
10
+ PRODUCE = 'Produce'
11
+ CONSUME = 'Consume'
12
+
13
+ INSTRUMENTATION_NAME = 'ruby-kafka'
14
+
15
+ def produce_with_new_relic(value, **kwargs)
16
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
17
+
18
+ topic_name = kwargs[:topic]
19
+ segment = NewRelic::Agent::Tracer.start_message_broker_segment(
20
+ action: :produce,
21
+ library: MESSAGING_LIBRARY,
22
+ destination_type: :topic,
23
+ destination_name: topic_name
24
+ )
25
+ create_kafka_metrics(action: PRODUCE, topic: topic_name)
26
+
27
+ headers = kwargs[:headers] || {}
28
+ ::NewRelic::Agent::DistributedTracing.insert_distributed_trace_headers(headers)
29
+
30
+ NewRelic::Agent::Tracer.capture_segment_error(segment) { yield(headers) }
31
+ ensure
32
+ segment&.finish
33
+ end
34
+
35
+ def each_message_with_new_relic(message)
36
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
37
+
38
+ headers = message&.headers || {}
39
+ topic_name = message&.topic
40
+
41
+ NewRelic::Agent::Messaging.wrap_message_broker_consume_transaction(
42
+ library: MESSAGING_LIBRARY,
43
+ destination_type: :topic,
44
+ destination_name: topic_name,
45
+ headers: headers,
46
+ action: :consume
47
+ ) do
48
+ create_kafka_metrics(action: CONSUME, topic: topic_name)
49
+ yield
50
+ end
51
+ end
52
+
53
+ def create_kafka_metrics(action:, topic:)
54
+ @nr_config.each do |seed_broker|
55
+ host = "#{seed_broker&.host}:#{seed_broker&.port}"
56
+ NewRelic::Agent.record_metric("MessageBroker/Kafka/Nodes/#{host}/#{action}/#{topic}", 1)
57
+ NewRelic::Agent.record_metric("MessageBroker/Kafka/Nodes/#{host}", 1)
58
+ end
59
+ end
60
+ end
61
+
62
+ module RubyKafkaConfig
63
+ def set_nr_config(producer_or_consumer)
64
+ producer_or_consumer.instance_variable_set(:@nr_config, @seed_brokers)
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,50 @@
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 RubyKafkaProducer
7
+ module Prepend
8
+ include NewRelic::Agent::Instrumentation::RubyKafka
9
+
10
+ def produce(value, **kwargs)
11
+ produce_with_new_relic(value, **kwargs) do |headers|
12
+ kwargs[:headers] = headers
13
+ super
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ module RubyKafkaConsumer
20
+ module Prepend
21
+ include NewRelic::Agent::Instrumentation::RubyKafka
22
+
23
+ def each_message(*args)
24
+ super do |message|
25
+ each_message_with_new_relic(message) do
26
+ yield(message)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ module RubyKafkaClient
34
+ module Prepend
35
+ include NewRelic::Agent::Instrumentation::RubyKafkaConfig
36
+
37
+ def producer(**kwargs)
38
+ super.tap do |producer|
39
+ set_nr_config(producer)
40
+ end
41
+ end
42
+
43
+ def consumer(**kwargs)
44
+ super.tap do |consumer|
45
+ set_nr_config(consumer)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ 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 'ruby_kafka/instrumentation'
6
+ require_relative 'ruby_kafka/chain'
7
+ require_relative 'ruby_kafka/prepend'
8
+
9
+ DependencyDetection.defer do
10
+ named :'ruby_kafka'
11
+
12
+ depends_on do
13
+ defined?(Kafka)
14
+ end
15
+
16
+ executes do
17
+ NewRelic::Agent.logger.info('Installing ruby-kafka instrumentation')
18
+
19
+ if use_prepend?
20
+ prepend_instrument Kafka::Producer, NewRelic::Agent::Instrumentation::RubyKafkaProducer::Prepend
21
+ prepend_instrument Kafka::Consumer, NewRelic::Agent::Instrumentation::RubyKafkaConsumer::Prepend
22
+ prepend_instrument Kafka::Client, NewRelic::Agent::Instrumentation::RubyKafkaClient::Prepend
23
+ else
24
+ chain_instrument NewRelic::Agent::Instrumentation::RubyKafka::Chain
25
+ end
26
+ end
27
+ 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
@@ -11,7 +11,10 @@ module NewRelic::Agent::Instrumentation
11
11
 
12
12
  begin
13
13
  segment = NewRelic::Agent::Tracer.start_segment(
14
- name: metric_name(self.class.identifier, self.class.name)
14
+ name: metric_name(
15
+ self.class.respond_to?(:identifier) ? self.class.identifier : nil,
16
+ self.class.name
17
+ )
15
18
  )
16
19
  yield
17
20
  rescue => e
@@ -164,9 +164,8 @@ module NewRelic
164
164
 
165
165
  def add_ssl_for_http(data)
166
166
  ssl_for_http = NewRelic::Agent.config[:'browser_monitoring.ssl_for_http']
167
- unless ssl_for_http.nil?
168
- data[SSL_FOR_HTTP_KEY] = ssl_for_http
169
- end
167
+
168
+ data[SSL_FOR_HTTP_KEY] = ssl_for_http if ssl_for_http
170
169
  end
171
170
 
172
171
  def add_attributes(data, txn)
@@ -117,7 +117,8 @@ module NewRelic
117
117
  queue_name: nil,
118
118
  exchange_type: nil,
119
119
  reply_to: nil,
120
- correlation_id: nil)
120
+ correlation_id: nil,
121
+ action: nil)
121
122
 
122
123
  state = Tracer.state
123
124
  return yield if state.current_transaction
@@ -125,12 +126,12 @@ module NewRelic
125
126
  txn = nil
126
127
 
127
128
  begin
128
- txn_name = transaction_name(library, destination_type, destination_name)
129
+ txn_name = transaction_name(library, destination_type, destination_name, action)
129
130
 
130
131
  txn = Tracer.start_transaction(name: txn_name, category: :message)
131
-
132
132
  if headers
133
- txn.distributed_tracer.consume_message_headers(headers, state, RABBITMQ_TRANSPORT_TYPE)
133
+ NewRelic::Agent::DistributedTracing::accept_distributed_trace_headers(headers, library) # to handle the new w3c headers
134
+ txn.distributed_tracer.consume_message_headers(headers, state, library) # to do the expected old things
134
135
  CrossAppTracing.reject_messaging_cat_headers(headers).each do |k, v|
135
136
  txn.add_agent_attribute(:"message.headers.#{k}", v, AttributeFilter::DST_NONE) unless v.nil?
136
137
  end
@@ -327,12 +328,17 @@ module NewRelic
327
328
  NewRelic::Agent.config[:'message_tracer.segment_parameters.enabled']
328
329
  end
329
330
 
330
- def transaction_name(library, destination_type, destination_name)
331
+ def transaction_name(library, destination_type, destination_name, action = nil)
331
332
  transaction_name = Transaction::MESSAGE_PREFIX + library
332
333
  transaction_name << NewRelic::SLASH
333
334
  transaction_name << Transaction::MessageBrokerSegment::TYPES[destination_type]
334
335
  transaction_name << NewRelic::SLASH
335
336
 
337
+ if action == :consume
338
+ transaction_name << 'Consume'
339
+ transaction_name << NewRelic::SLASH
340
+ end
341
+
336
342
  case destination_type
337
343
  when :queue
338
344
  transaction_name << Transaction::MessageBrokerSegment::NAMED