newrelic_rpm 9.9.0 → 9.21.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/.build_ignore +1 -0
- data/CHANGELOG.md +463 -1
- data/CONTRIBUTING.md +2 -2
- data/README.md +16 -17
- data/Rakefile +1 -1
- data/lib/boot/strap.rb +102 -0
- data/lib/new_relic/agent/agent.rb +6 -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/agent_logger.rb +1 -0
- data/lib/new_relic/agent/aws.rb +68 -0
- data/lib/new_relic/agent/configuration/default_source.rb +603 -105
- data/lib/new_relic/agent/configuration/environment_source.rb +5 -1
- data/lib/new_relic/agent/configuration/manager.rb +28 -2
- data/lib/new_relic/agent/configuration/yaml_source.rb +7 -2
- data/lib/new_relic/agent/database/obfuscation_helpers.rb +11 -11
- data/lib/new_relic/agent/database/obfuscator.rb +1 -0
- data/lib/new_relic/agent/database.rb +41 -1
- data/lib/new_relic/agent/database_adapter.rb +1 -1
- data/lib/new_relic/agent/datastores/redis.rb +1 -1
- data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +1 -1
- data/lib/new_relic/agent/distributed_tracing.rb +4 -2
- data/lib/new_relic/agent/error_collector.rb +37 -10
- data/lib/new_relic/agent/external.rb +2 -0
- data/lib/new_relic/agent/health_check.rb +136 -0
- data/lib/new_relic/agent/http_clients/uri_util.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_dispatch.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_mailbox.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_mailer.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_job.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +6 -2
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +0 -13
- data/lib/new_relic/agent/instrumentation/active_record.rb +7 -12
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +7 -3
- data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +11 -9
- data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +2 -2
- 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 +2 -3
- 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/chain.rb +37 -0
- data/lib/new_relic/agent/instrumentation/aws_sqs/instrumentation.rb +67 -0
- data/lib/new_relic/agent/instrumentation/aws_sqs/prepend.rb +21 -0
- data/lib/new_relic/agent/instrumentation/aws_sqs.rb +23 -0
- data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +14 -0
- data/lib/new_relic/agent/instrumentation/bunny.rb +3 -4
- data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +1 -3
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/curb.rb +4 -5
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +0 -23
- data/lib/new_relic/agent/instrumentation/dynamodb/chain.rb +27 -0
- data/lib/new_relic/agent/instrumentation/dynamodb/instrumentation.rb +64 -0
- data/lib/new_relic/agent/instrumentation/dynamodb/prepend.rb +19 -0
- data/lib/new_relic/agent/instrumentation/dynamodb.rb +23 -0
- data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +1 -2
- data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +53 -7
- data/lib/new_relic/agent/instrumentation/elasticsearch.rb +1 -3
- data/lib/new_relic/agent/instrumentation/ethon.rb +1 -5
- data/lib/new_relic/agent/instrumentation/excon.rb +1 -17
- data/lib/new_relic/agent/instrumentation/fiber/chain.rb +1 -1
- data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +1 -1
- 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/grpc/client/instrumentation.rb +0 -1
- data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -5
- data/lib/new_relic/agent/instrumentation/httprb.rb +0 -1
- data/lib/new_relic/agent/instrumentation/httpx/instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/httpx.rb +1 -5
- data/lib/new_relic/agent/instrumentation/logger.rb +1 -3
- data/lib/new_relic/agent/instrumentation/logstasher/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/logstasher/instrumentation.rb +24 -0
- data/lib/new_relic/agent/instrumentation/logstasher/prepend.rb +13 -0
- data/lib/new_relic/agent/instrumentation/logstasher.rb +25 -0
- data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache/helper.rb +2 -2
- data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache.rb +0 -1
- data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +3 -3
- data/lib/new_relic/agent/instrumentation/net_http.rb +2 -1
- data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +0 -2
- data/lib/new_relic/agent/instrumentation/opensearch/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/opensearch/instrumentation.rb +66 -0
- data/lib/{tasks/instrumentation_generator/templates/instrumentation.tt → new_relic/agent/instrumentation/opensearch/prepend.rb} +4 -4
- 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/rack/instrumentation.rb +3 -0
- data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +9 -5
- data/lib/new_relic/agent/instrumentation/rake.rb +1 -2
- 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/cluster_middleware.rb +26 -0
- data/lib/new_relic/agent/instrumentation/redis/constants.rb +2 -2
- data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +14 -11
- data/lib/new_relic/agent/instrumentation/redis/middleware.rb +3 -0
- data/lib/new_relic/agent/instrumentation/redis.rb +11 -5
- data/lib/new_relic/agent/instrumentation/resque.rb +8 -6
- data/lib/new_relic/agent/instrumentation/roda.rb +5 -5
- 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/ruby_openai.rb +2 -2
- data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delay_extensions.rb +24 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +2 -2
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +9 -15
- data/lib/new_relic/agent/instrumentation/sinatra.rb +3 -19
- data/lib/new_relic/agent/instrumentation/stripe.rb +1 -1
- data/lib/new_relic/agent/instrumentation/stripe_subscriber.rb +22 -1
- 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/instrumentation.rb +2 -2
- 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/llm/chat_completion_summary.rb +1 -1
- data/lib/new_relic/agent/llm/embedding.rb +1 -1
- data/lib/new_relic/agent/local_log_decorator.rb +20 -3
- data/lib/new_relic/agent/log_event_aggregator.rb +119 -28
- data/lib/new_relic/agent/logging.rb +1 -1
- data/lib/new_relic/agent/messaging.rb +16 -5
- data/lib/new_relic/agent/method_tracer.rb +3 -0
- data/lib/new_relic/agent/monitors/inbound_request_monitor.rb +1 -1
- data/lib/new_relic/agent/monitors/synthetics_monitor.rb +1 -1
- data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +2 -2
- data/lib/new_relic/agent/new_relic_service.rb +8 -2
- data/lib/new_relic/agent/opentelemetry/context/propagation/trace_propagator.rb +66 -0
- data/lib/new_relic/agent/opentelemetry/context/propagation.rb +15 -0
- data/lib/{tasks/instrumentation_generator/templates/Envfile.tt → new_relic/agent/opentelemetry/context.rb} +9 -5
- data/lib/new_relic/agent/opentelemetry/trace/span.rb +31 -0
- data/lib/new_relic/agent/opentelemetry/trace/tracer.rb +129 -0
- data/lib/new_relic/agent/opentelemetry/trace/tracer_provider.rb +18 -0
- data/lib/new_relic/agent/opentelemetry/trace.rb +15 -0
- data/lib/new_relic/agent/opentelemetry/transaction_patch.rb +69 -0
- data/lib/new_relic/agent/opentelemetry_bridge.rb +32 -0
- data/lib/new_relic/agent/parameter_filtering.rb +1 -1
- data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -1
- data/lib/new_relic/agent/samplers/memory_sampler.rb +1 -1
- data/lib/new_relic/agent/serverless_handler.rb +247 -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 +16 -11
- 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/tracer.rb +1 -1
- data/lib/new_relic/agent/transaction/abstract_segment.rb +2 -1
- data/lib/new_relic/agent/transaction/datastore_segment.rb +1 -1
- data/lib/new_relic/agent/transaction/distributed_tracer.rb +3 -3
- data/lib/new_relic/agent/transaction/external_request_segment.rb +0 -10
- data/lib/new_relic/agent/transaction/message_broker_segment.rb +4 -1
- data/lib/new_relic/agent/transaction/request_attributes.rb +14 -7
- data/lib/new_relic/agent/transaction/trace_context.rb +34 -5
- data/lib/new_relic/agent/transaction/tracing.rb +3 -3
- data/lib/new_relic/agent/transaction.rb +4 -7
- data/lib/new_relic/agent/transaction_time_aggregator.rb +1 -1
- data/lib/new_relic/agent/utilization/ecs.rb +22 -0
- data/lib/new_relic/agent/utilization/ecs_v4.rb +22 -0
- data/lib/new_relic/agent/utilization_data.rb +40 -5
- data/lib/new_relic/agent/vm/c_ruby_vm.rb +3 -3
- data/lib/new_relic/agent.rb +124 -2
- data/lib/new_relic/constants.rb +1 -0
- 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/control/instance_methods.rb +6 -0
- data/lib/new_relic/control/instrumentation.rb +1 -1
- data/lib/new_relic/control/private_instance_methods.rb +4 -0
- data/lib/new_relic/control/security_interface.rb +57 -0
- data/lib/new_relic/control.rb +1 -1
- data/lib/new_relic/dependency_detection.rb +11 -14
- data/lib/new_relic/environment_report.rb +2 -2
- data/lib/new_relic/helper.rb +22 -0
- data/lib/new_relic/language_support.rb +3 -1
- data/lib/new_relic/local_environment.rb +1 -4
- data/lib/new_relic/rack/browser_monitoring.rb +20 -8
- data/lib/new_relic/version.rb +1 -1
- data/lib/sequel/extensions/new_relic_instrumentation.rb +3 -2
- data/lib/tasks/config.rake +7 -3
- data/lib/tasks/gha.rake +31 -0
- data/lib/tasks/helpers/config.html.erb +3 -2
- data/lib/tasks/helpers/format.rb +1 -1
- data/lib/tasks/helpers/newrelicyml.rb +80 -13
- data/newrelic.yml +425 -162
- data/newrelic_rpm.gemspec +3 -1
- data/test/agent_helper.rb +24 -2
- metadata +91 -22
- data/lib/tasks/instrumentation_generator/README.md +0 -63
- data/lib/tasks/instrumentation_generator/TODO.md +0 -33
- data/lib/tasks/instrumentation_generator/instrumentation.thor +0 -121
- data/lib/tasks/instrumentation_generator/templates/chain.tt +0 -21
- data/lib/tasks/instrumentation_generator/templates/chain_method.tt +0 -7
- data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +0 -29
- data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +0 -3
- data/lib/tasks/instrumentation_generator/templates/newrelic.yml.tt +0 -19
- data/lib/tasks/instrumentation_generator/templates/prepend.tt +0 -13
- data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +0 -3
- data/lib/tasks/instrumentation_generator/templates/test.tt +0 -15
@@ -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,7 +19,7 @@ DependencyDetection.defer do
|
|
19
19
|
|
20
20
|
depends_on do
|
21
21
|
begin
|
22
|
-
if
|
22
|
+
if NewRelic::Helper.rubygems_specs.map(&:name).include?('newrelic-grape')
|
23
23
|
NewRelic::Agent.logger.info('Not installing New Relic supported Grape instrumentation because the third party newrelic-grape gem is present')
|
24
24
|
false
|
25
25
|
else
|
@@ -16,14 +16,10 @@ DependencyDetection.defer do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
depends_on do
|
19
|
-
|
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
|
26
|
-
NewRelic::Agent.logger.info('Installing HTTPClient instrumentation')
|
27
23
|
require 'new_relic/agent/distributed_tracing/cross_app_tracing'
|
28
24
|
require 'new_relic/agent/http_clients/httpclient_wrappers'
|
29
25
|
end
|
@@ -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 =
|
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,11 +10,7 @@ DependencyDetection.defer do
|
|
10
10
|
named :httpx
|
11
11
|
|
12
12
|
depends_on do
|
13
|
-
defined?(HTTPX) &&
|
14
|
-
end
|
15
|
-
|
16
|
-
executes do
|
17
|
-
NewRelic::Agent.logger.info('Installing httpx instrumentation')
|
13
|
+
defined?(HTTPX) && NewRelic::Helper.version_satisfied?(HTTPX::VERSION, '>=', '1.0.0')
|
18
14
|
end
|
19
15
|
|
20
16
|
executes do
|
@@ -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
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# This file is distributed under New Relic's license terms.
|
2
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
module NewRelic::Agent::Instrumentation
|
6
|
+
module LogStasher::Chain
|
7
|
+
def self.instrument!
|
8
|
+
::LogStasher.singleton_class.class_eval do
|
9
|
+
include NewRelic::Agent::Instrumentation::LogStasher
|
10
|
+
|
11
|
+
alias_method(:build_logstash_event_without_new_relic, :build_logstash_event)
|
12
|
+
|
13
|
+
def build_logstash_event(*args)
|
14
|
+
build_logstash_event_with_new_relic(*args) do
|
15
|
+
build_logstash_event_without_new_relic(*args)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# This file is distributed under New Relic's license terms.
|
2
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
module NewRelic::Agent::Instrumentation
|
6
|
+
module LogStasher
|
7
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
8
|
+
|
9
|
+
def self.enabled?
|
10
|
+
NewRelic::Agent.config[:'instrumentation.logstasher'] != 'disabled'
|
11
|
+
end
|
12
|
+
|
13
|
+
def build_logstash_event_with_new_relic(*args)
|
14
|
+
logstasher_event = yield
|
15
|
+
log = logstasher_event.instance_variable_get(:@data)
|
16
|
+
|
17
|
+
::NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
18
|
+
::NewRelic::Agent.agent.log_event_aggregator.record_logstasher_event(log)
|
19
|
+
::NewRelic::Agent::LocalLogDecorator.decorate(log)
|
20
|
+
|
21
|
+
logstasher_event
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# This file is distributed under New Relic's license terms.
|
2
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
module NewRelic::Agent::Instrumentation
|
6
|
+
module LogStasher::Prepend
|
7
|
+
include NewRelic::Agent::Instrumentation::LogStasher
|
8
|
+
|
9
|
+
def build_logstash_event(*args)
|
10
|
+
build_logstash_event_with_new_relic(*args) { super }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,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 'logstasher/instrumentation'
|
6
|
+
require_relative 'logstasher/chain'
|
7
|
+
require_relative 'logstasher/prepend'
|
8
|
+
|
9
|
+
DependencyDetection.defer do
|
10
|
+
named :logstasher
|
11
|
+
|
12
|
+
depends_on do
|
13
|
+
defined?(LogStasher) &&
|
14
|
+
NewRelic::Helper.version_satisfied?(LogStasher::VERSION, '>=', '1.0.0') &&
|
15
|
+
NewRelic::Agent.config[:'application_logging.enabled']
|
16
|
+
end
|
17
|
+
|
18
|
+
executes do
|
19
|
+
if use_prepend?
|
20
|
+
prepend_instrument LogStasher.singleton_class, NewRelic::Agent::Instrumentation::LogStasher::Prepend
|
21
|
+
else
|
22
|
+
chain_instrument NewRelic::Agent::Instrumentation::LogStasher::Chain
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -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
|
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 <=
|
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 <=
|
16
|
+
NewRelic::Helper.version_satisfied?(BINARY_PROTOCOL_SUPPORTED_VERSION, '<=', ::Dalli::VERSION)
|
17
17
|
end
|
18
18
|
|
19
19
|
def client_methods
|
@@ -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
|
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
|
@@ -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|
|
@@ -21,7 +21,7 @@ module NewRelic
|
|
21
21
|
|
22
22
|
begin
|
23
23
|
response = nil
|
24
|
-
segment
|
24
|
+
segment&.add_request_headers(wrapped_request)
|
25
25
|
|
26
26
|
# RUBY-1244 Disable further tracing in request to avoid double
|
27
27
|
# counting if connection wasn't started (which calls request again).
|
@@ -34,10 +34,10 @@ module NewRelic
|
|
34
34
|
wrapped_response = NewRelic::Agent::HTTPClients::NetHTTPResponse.new(response)
|
35
35
|
|
36
36
|
if NewRelic::Agent::LLM.openai_parent?(segment)
|
37
|
-
NewRelic::Agent::LLM.populate_openai_response_headers(wrapped_response, segment
|
37
|
+
NewRelic::Agent::LLM.populate_openai_response_headers(wrapped_response, segment&.parent)
|
38
38
|
end
|
39
39
|
|
40
|
-
segment
|
40
|
+
segment&.process_response_headers(wrapped_response)
|
41
41
|
|
42
42
|
response
|
43
43
|
ensure
|
@@ -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) &&
|
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
|
@@ -16,8 +16,6 @@ module NewRelic
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.find_all_subscribers
|
19
|
-
# TODO: need to talk to Rails core about an API for this,
|
20
|
-
# rather than digging through Listener ivars
|
21
19
|
instance_variable_names = [:@subscribers, :@string_subscribers, :@other_subscribers]
|
22
20
|
all_subscribers = []
|
23
21
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# This file is distributed under New Relic's license terms.
|
2
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
module NewRelic::Agent::Instrumentation
|
6
|
+
module OpenSearch::Chain
|
7
|
+
def self.instrument!
|
8
|
+
::OpenSearch::Transport::Client.class_eval do
|
9
|
+
include NewRelic::Agent::Instrumentation::OpenSearch
|
10
|
+
|
11
|
+
alias_method(:perform_request_without_tracing, :perform_request)
|
12
|
+
|
13
|
+
def perform_request(*args)
|
14
|
+
perform_request_with_tracing(*args) do
|
15
|
+
perform_request_without_tracing(*args)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# This file is distributed under New Relic's license terms.
|
2
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
module NewRelic::Agent::Instrumentation
|
6
|
+
module OpenSearch
|
7
|
+
PRODUCT_NAME = 'OpenSearch'
|
8
|
+
OPERATION = 'perform_request'
|
9
|
+
OPERATION_PATTERN = %r{/lib/opensearch/api/(?!.+#{OPERATION})}
|
10
|
+
INSTANCE_METHOD_PATTERN = /:in (?:`|')(?:.+#)?([^']+)'\z/
|
11
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
12
|
+
|
13
|
+
def perform_request_with_tracing(_method, _path, params = NewRelic::EMPTY_HASH, body = nil, _headers = nil, _opts = nil, &_block)
|
14
|
+
return yield unless NewRelic::Agent::Tracer.tracing_enabled?
|
15
|
+
|
16
|
+
segment = NewRelic::Agent::Tracer.start_datastore_segment(
|
17
|
+
product: PRODUCT_NAME,
|
18
|
+
operation: nr_operation || OPERATION,
|
19
|
+
host: nr_hosts[:host],
|
20
|
+
port_path_or_id: nr_hosts[:port],
|
21
|
+
database_name: nr_cluster_name
|
22
|
+
)
|
23
|
+
begin
|
24
|
+
NewRelic::Agent::Tracer.capture_segment_error(segment) { yield }
|
25
|
+
ensure
|
26
|
+
if segment
|
27
|
+
segment.notice_nosql_statement(nr_reported_query(body || params))
|
28
|
+
segment.finish
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# See Elasticsearch instrumentation for explanation on Ruby 3.4 changes to match instance method
|
36
|
+
def nr_operation
|
37
|
+
location = caller_locations.detect { |loc| loc.to_s.match?(OPERATION_PATTERN) }
|
38
|
+
return unless location && location.to_s =~ INSTANCE_METHOD_PATTERN
|
39
|
+
|
40
|
+
Regexp.last_match(1)
|
41
|
+
end
|
42
|
+
|
43
|
+
def nr_reported_query(query)
|
44
|
+
return unless NewRelic::Agent.config[:'opensearch.capture_queries']
|
45
|
+
return query unless NewRelic::Agent.config[:'opensearch.obfuscate_queries']
|
46
|
+
|
47
|
+
NewRelic::Agent::Datastores::NosqlObfuscator.obfuscate_statement(query)
|
48
|
+
end
|
49
|
+
|
50
|
+
def nr_cluster_name
|
51
|
+
return @nr_cluster_name if defined?(@nr_cluster_name)
|
52
|
+
return if nr_hosts.empty?
|
53
|
+
|
54
|
+
NewRelic::Agent.disable_all_tracing do
|
55
|
+
@nr_cluster_name ||= perform_request('GET', '/').body['cluster_name']
|
56
|
+
end
|
57
|
+
rescue StandardError => e
|
58
|
+
NewRelic::Agent.logger.error('Failed to get cluster name for OpenSearch', e)
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def nr_hosts
|
63
|
+
@nr_hosts ||= (transport.hosts.first || NewRelic::EMPTY_HASH)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -3,11 +3,11 @@
|
|
3
3
|
# frozen_string_literal: true
|
4
4
|
|
5
5
|
module NewRelic::Agent::Instrumentation
|
6
|
-
module
|
6
|
+
module OpenSearch::Prepend
|
7
|
+
include NewRelic::Agent::Instrumentation::OpenSearch
|
7
8
|
|
8
|
-
def
|
9
|
-
|
10
|
-
yield
|
9
|
+
def perform_request(*args)
|
10
|
+
perform_request_with_tracing(*args) { super }
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -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
|
+
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
|
+
if use_prepend?
|
18
|
+
prepend_instrument OpenSearch::Transport::Client, NewRelic::Agent::Instrumentation::OpenSearch::Prepend
|
19
|
+
else
|
20
|
+
chain_instrument NewRelic::Agent::Instrumentation::OpenSearch::Chain
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -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
|
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
|
@@ -13,6 +13,7 @@ module NewRelic
|
|
13
13
|
attr_accessor :_nr_deferred_detection_ran
|
14
14
|
end
|
15
15
|
builder_class._nr_deferred_detection_ran = false
|
16
|
+
NewRelic::Control::SecurityInterface.instance.wait = true
|
16
17
|
end
|
17
18
|
|
18
19
|
def deferred_dependency_check
|
@@ -21,6 +22,8 @@ module NewRelic
|
|
21
22
|
NewRelic::Agent.logger.info('Doing deferred dependency-detection before Rack startup')
|
22
23
|
DependencyDetection.detect!
|
23
24
|
self.class._nr_deferred_detection_ran = true
|
25
|
+
NewRelic::Control::SecurityInterface.instance.wait = false
|
26
|
+
NewRelic::Control::SecurityInterface.instance.init_agent
|
24
27
|
end
|
25
28
|
|
26
29
|
def check_for_late_instrumentation(app)
|
@@ -32,15 +32,19 @@ DependencyDetection.defer do
|
|
32
32
|
NewRelic::Agent::Instrumentation::ActionControllerSubscriber \
|
33
33
|
.subscribe(/^process_action.action_controller$/)
|
34
34
|
|
35
|
-
subs = %w[
|
35
|
+
subs = %w[exist_fragment?
|
36
|
+
expire_fragment
|
37
|
+
halted_callback
|
38
|
+
read_fragment
|
39
|
+
redirect_to
|
36
40
|
send_data
|
41
|
+
send_file
|
37
42
|
send_stream
|
38
|
-
|
39
|
-
|
40
|
-
unpermitted_parameters]
|
43
|
+
write_fragment
|
44
|
+
unpermitted_parameters].map { |s| Regexp.escape(s) }
|
41
45
|
|
42
46
|
# have to double escape period because its going from string -> regex
|
43
47
|
NewRelic::Agent::Instrumentation::ActionControllerOtherSubscriber \
|
44
|
-
.subscribe(Regexp.new("^(
|
48
|
+
.subscribe(Regexp.new("^(?:#{subs.join('|')})\\.action_controller$"))
|
45
49
|
end
|
46
50
|
end
|
@@ -12,12 +12,11 @@ DependencyDetection.defer do
|
|
12
12
|
configure_with :rake
|
13
13
|
|
14
14
|
depends_on { defined?(Rake) && defined?(Rake::VERSION) }
|
15
|
-
depends_on {
|
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
|
|
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
|
|
@@ -0,0 +1,72 @@
|
|
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 NewRelic::Helper.version_satisfied?(::Rdkafka::VERSION, '>=', '0.16.0') ||
|
44
|
+
NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '2.7.0')
|
45
|
+
def producer(**kwargs)
|
46
|
+
producer_without_new_relic(**kwargs).tap do |producer|
|
47
|
+
set_nr_config(producer)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def consumer(**kwargs)
|
52
|
+
consumer_without_new_relic(**kwargs).tap do |consumer|
|
53
|
+
set_nr_config(consumer)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
else
|
57
|
+
def producer
|
58
|
+
producer_without_new_relic.tap do |producer|
|
59
|
+
set_nr_config(producer)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def consumer
|
64
|
+
consumer_without_new_relic.tap do |consumer|
|
65
|
+
set_nr_config(consumer)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
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
|