newrelic_rpm 9.12.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +217 -1
- data/CONTRIBUTING.md +2 -2
- data/README.md +16 -20
- data/lib/boot/strap.rb +4 -3
- data/lib/new_relic/agent/agent.rb +4 -0
- data/lib/new_relic/agent/agent_helpers/connect.rb +3 -0
- data/lib/new_relic/agent/agent_helpers/harvest.rb +3 -0
- data/lib/new_relic/agent/agent_helpers/shutdown.rb +3 -0
- data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +1 -0
- data/lib/new_relic/agent/agent_helpers/startup.rb +7 -0
- data/lib/new_relic/agent/aws.rb +6 -0
- data/lib/new_relic/agent/configuration/default_source.rb +363 -31
- data/lib/new_relic/agent/configuration/environment_source.rb +5 -1
- data/lib/new_relic/agent/configuration/manager.rb +23 -0
- data/lib/new_relic/agent/configuration/yaml_source.rb +6 -1
- data/lib/new_relic/agent/database/obfuscation_helpers.rb +11 -11
- data/lib/new_relic/agent/database.rb +41 -1
- data/lib/new_relic/agent/distributed_tracing.rb +2 -2
- data/lib/new_relic/agent/health_check.rb +136 -0
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +0 -13
- data/lib/new_relic/agent/instrumentation/active_record.rb +1 -8
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +5 -1
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +9 -16
- data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger.rb +0 -2
- data/lib/new_relic/agent/instrumentation/active_support_logger.rb +0 -2
- data/lib/new_relic/agent/instrumentation/async_http.rb +1 -2
- data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/instrumentation.rb +66 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/prepend.rb +15 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_firehose.rb +22 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/instrumentation.rb +91 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/prepend.rb +15 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis.rb +22 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/chain.rb +33 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/instrumentation.rb +93 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/prepend.rb +23 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_lambda.rb +23 -0
- data/lib/new_relic/agent/instrumentation/aws_sqs.rb +0 -2
- data/lib/new_relic/agent/instrumentation/bunny.rb +3 -4
- data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +0 -2
- data/lib/new_relic/agent/instrumentation/curb.rb +3 -4
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +0 -23
- data/lib/new_relic/agent/instrumentation/dynamodb/instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/dynamodb.rb +0 -2
- data/lib/new_relic/agent/instrumentation/elasticsearch.rb +0 -2
- data/lib/new_relic/agent/instrumentation/ethon.rb +0 -4
- data/lib/new_relic/agent/instrumentation/excon.rb +0 -16
- data/lib/new_relic/agent/instrumentation/fiber.rb +0 -2
- data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +0 -3
- data/lib/new_relic/agent/instrumentation/grape.rb +1 -1
- data/lib/new_relic/agent/instrumentation/httpclient.rb +0 -1
- data/lib/new_relic/agent/instrumentation/httprb.rb +0 -1
- data/lib/new_relic/agent/instrumentation/httpx.rb +0 -4
- data/lib/new_relic/agent/instrumentation/logger.rb +1 -3
- data/lib/new_relic/agent/instrumentation/logstasher.rb +0 -2
- data/lib/new_relic/agent/instrumentation/memcache.rb +0 -1
- data/lib/new_relic/agent/instrumentation/opensearch/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/opensearch/instrumentation.rb +66 -0
- data/lib/new_relic/agent/instrumentation/opensearch/prepend.rb +13 -0
- data/lib/new_relic/agent/instrumentation/opensearch.rb +23 -0
- data/lib/new_relic/agent/instrumentation/padrino.rb +3 -3
- data/lib/new_relic/agent/instrumentation/rake.rb +0 -1
- data/lib/new_relic/agent/instrumentation/rdkafka/chain.rb +72 -0
- data/lib/new_relic/agent/instrumentation/rdkafka/instrumentation.rb +70 -0
- data/lib/new_relic/agent/instrumentation/rdkafka/prepend.rb +67 -0
- data/lib/new_relic/agent/instrumentation/rdkafka.rb +25 -0
- data/lib/new_relic/agent/instrumentation/redis.rb +7 -6
- data/lib/new_relic/agent/instrumentation/resque.rb +7 -5
- data/lib/new_relic/agent/instrumentation/roda.rb +4 -4
- data/lib/new_relic/agent/instrumentation/ruby_kafka/chain.rb +55 -0
- data/lib/new_relic/agent/instrumentation/ruby_kafka/instrumentation.rb +67 -0
- data/lib/new_relic/agent/instrumentation/ruby_kafka/prepend.rb +60 -0
- data/lib/new_relic/agent/instrumentation/ruby_kafka.rb +25 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +1 -1
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +0 -14
- data/lib/new_relic/agent/instrumentation/sinatra.rb +3 -19
- data/lib/new_relic/agent/instrumentation/thread.rb +0 -2
- data/lib/new_relic/agent/instrumentation/tilt.rb +0 -4
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +0 -1
- data/lib/new_relic/agent/instrumentation/view_component/instrumentation.rb +11 -5
- data/lib/new_relic/agent/instrumentation/view_component.rb +0 -2
- data/lib/new_relic/agent/javascript_instrumentor.rb +2 -3
- data/lib/new_relic/agent/local_log_decorator.rb +12 -2
- data/lib/new_relic/agent/log_event_aggregator.rb +28 -2
- data/lib/new_relic/agent/messaging.rb +11 -5
- data/lib/new_relic/agent/new_relic_service.rb +8 -2
- data/lib/new_relic/agent/serverless_handler.rb +241 -12
- data/lib/new_relic/agent/serverless_handler_event_sources.json +155 -0
- data/lib/new_relic/agent/serverless_handler_event_sources.rb +49 -0
- data/lib/new_relic/agent/span_event_primitive.rb +4 -2
- data/lib/new_relic/agent/system_info.rb +14 -0
- data/lib/new_relic/agent/threading/backtrace_node.rb +10 -1
- data/lib/new_relic/agent/transaction/message_broker_segment.rb +3 -0
- data/lib/new_relic/agent/transaction/request_attributes.rb +13 -1
- data/lib/new_relic/agent/transaction/trace_context.rb +1 -1
- data/lib/new_relic/agent.rb +95 -2
- data/lib/new_relic/control/frameworks/grape.rb +14 -0
- data/lib/new_relic/control/frameworks/padrino.rb +14 -0
- data/lib/new_relic/control/frameworks/rails4.rb +1 -3
- data/lib/new_relic/dependency_detection.rb +11 -13
- data/lib/new_relic/environment_report.rb +2 -2
- data/lib/new_relic/helper.rb +15 -0
- data/lib/new_relic/language_support.rb +3 -1
- data/lib/new_relic/local_environment.rb +1 -4
- data/lib/new_relic/version.rb +1 -1
- data/lib/sequel/extensions/new_relic_instrumentation.rb +1 -1
- data/lib/tasks/helpers/newrelicyml.rb +73 -11
- data/lib/tasks/instrumentation_generator/instrumentation.thor +1 -1
- data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +11 -8
- data/newrelic.yml +224 -79
- data/test/agent_helper.rb +8 -1
- metadata +32 -6
@@ -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,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_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
|
+
(Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0'))
|
41
|
+
def producer(**kwargs)
|
42
|
+
super.tap do |producer|
|
43
|
+
set_nr_config(producer)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def consumer(**kwargs)
|
48
|
+
super.tap do |consumer|
|
49
|
+
set_nr_config(consumer)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
else # older versions
|
53
|
+
def producer
|
54
|
+
super.tap do |producer|
|
55
|
+
set_nr_config(producer)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def consumer
|
60
|
+
super.tap do |consumer|
|
61
|
+
set_nr_config(consumer)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
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
|
+
DependencyDetection.defer do
|
6
|
+
named :rdkafka
|
7
|
+
|
8
|
+
depends_on do
|
9
|
+
defined?(Rdkafka)
|
10
|
+
end
|
11
|
+
|
12
|
+
executes do
|
13
|
+
require_relative 'rdkafka/instrumentation'
|
14
|
+
require_relative 'rdkafka/chain'
|
15
|
+
require_relative 'rdkafka/prepend'
|
16
|
+
|
17
|
+
if use_prepend?
|
18
|
+
prepend_instrument Rdkafka::Config, NewRelic::Agent::Instrumentation::RdkafkaConfig::Prepend
|
19
|
+
prepend_instrument Rdkafka::Producer, NewRelic::Agent::Instrumentation::RdkafkaProducer::Prepend
|
20
|
+
prepend_instrument Rdkafka::Consumer, NewRelic::Agent::Instrumentation::RdkafkaConsumer::Prepend
|
21
|
+
else
|
22
|
+
chain_instrument NewRelic::Agent::Instrumentation::Rdkafka::Chain
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -31,19 +31,20 @@ 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
|
|
38
37
|
if defined?(Redis::Cluster::Client)
|
39
|
-
|
38
|
+
RedisClient.register(NewRelic::Agent::Instrumentation::RedisClient::ClusterMiddleware)
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
unless defined?(Redis::Cluster::Client)
|
43
|
+
if use_prepend?
|
44
|
+
prepend_instrument Redis::Client, NewRelic::Agent::Instrumentation::Redis::Prepend
|
45
|
+
else
|
46
|
+
chain_instrument NewRelic::Agent::Instrumentation::Redis::Chain
|
47
|
+
end
|
47
48
|
end
|
48
49
|
end
|
49
50
|
end
|
@@ -19,11 +19,13 @@ DependencyDetection.defer do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
executes do
|
22
|
-
NewRelic::Agent.
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
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 }
|
@@ -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,60 @@
|
|
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
|
+
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
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
module RubyKafkaClient
|
44
|
+
module Prepend
|
45
|
+
include NewRelic::Agent::Instrumentation::RubyKafkaConfig
|
46
|
+
|
47
|
+
def producer(**kwargs)
|
48
|
+
super.tap do |producer|
|
49
|
+
set_nr_config(producer)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def consumer(**kwargs)
|
54
|
+
super.tap do |consumer|
|
55
|
+
set_nr_config(consumer)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
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 '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
|
+
if use_prepend?
|
18
|
+
prepend_instrument Kafka::Producer, NewRelic::Agent::Instrumentation::RubyKafkaProducer::Prepend
|
19
|
+
prepend_instrument Kafka::Consumer, NewRelic::Agent::Instrumentation::RubyKafkaConsumer::Prepend
|
20
|
+
prepend_instrument Kafka::Client, NewRelic::Agent::Instrumentation::RubyKafkaClient::Prepend
|
21
|
+
else
|
22
|
+
chain_instrument NewRelic::Agent::Instrumentation::RubyKafka::Chain
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -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/
|
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
|
@@ -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
|
@@ -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,27 +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
|
-
|
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
42
|
end
|
@@ -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
|
@@ -10,9 +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(self.class.identifier, self.class.name)
|
15
|
-
)
|
13
|
+
segment = NewRelic::Agent::Tracer.start_segment(name: metric_name)
|
16
14
|
yield
|
17
15
|
rescue => e
|
18
16
|
NewRelic::Agent.notice_error(e)
|
@@ -22,8 +20,16 @@ module NewRelic::Agent::Instrumentation
|
|
22
20
|
end
|
23
21
|
end
|
24
22
|
|
25
|
-
def metric_name
|
26
|
-
|
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'
|
27
33
|
end
|
28
34
|
|
29
35
|
def metric_path(identifier)
|
@@ -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
|
-
|
168
|
-
|
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)
|
@@ -9,7 +9,7 @@ module NewRelic
|
|
9
9
|
extend self
|
10
10
|
|
11
11
|
def decorate(message)
|
12
|
-
return message
|
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
|
-
|
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
|