newrelic_rpm 9.1.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 +27 -0
- data/CHANGELOG.md +841 -7
- data/CONTRIBUTING.md +2 -9
- data/README.md +25 -22
- data/Rakefile +2 -2
- data/bin/newrelic +3 -9
- data/bin/newrelic_rpm +15 -0
- data/init.rb +2 -2
- data/lib/boot/strap.rb +102 -0
- data/lib/new_relic/agent/agent.rb +11 -2
- data/lib/new_relic/agent/agent_helpers/connect.rb +13 -8
- data/lib/new_relic/agent/agent_helpers/harvest.rb +3 -0
- data/lib/new_relic/agent/agent_helpers/shutdown.rb +4 -1
- data/lib/new_relic/agent/agent_helpers/special_startup.rb +1 -1
- data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +4 -3
- data/lib/new_relic/agent/agent_helpers/startup.rb +11 -3
- data/lib/new_relic/agent/agent_logger.rb +3 -1
- data/lib/new_relic/agent/attribute_filter.rb +3 -3
- data/lib/new_relic/agent/attribute_pre_filtering.rb +109 -0
- data/lib/new_relic/agent/aws.rb +68 -0
- data/lib/new_relic/agent/configuration/default_source.rb +918 -166
- data/lib/new_relic/agent/configuration/environment_source.rb +15 -3
- data/lib/new_relic/agent/configuration/high_security_source.rb +1 -0
- data/lib/new_relic/agent/configuration/manager.rb +72 -11
- data/lib/new_relic/agent/configuration/security_policy_source.rb +11 -0
- data/lib/new_relic/agent/configuration/yaml_source.rb +22 -2
- data/lib/new_relic/agent/connect/request_builder.rb +1 -1
- data/lib/new_relic/agent/custom_event_aggregator.rb +27 -1
- 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/mongo/metric_translator.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/distributed_trace_payload.rb +4 -8
- data/lib/new_relic/agent/distributed_tracing.rb +5 -3
- data/lib/new_relic/agent/error_collector.rb +40 -11
- data/lib/new_relic/agent/event_loop.rb +1 -1
- data/lib/new_relic/agent/external.rb +2 -0
- data/lib/new_relic/agent/harvester.rb +1 -1
- data/lib/new_relic/agent/health_check.rb +136 -0
- data/lib/new_relic/agent/http_clients/abstract.rb +4 -0
- data/lib/new_relic/agent/http_clients/async_http_wrappers.rb +80 -0
- data/lib/new_relic/agent/http_clients/curb_wrappers.rb +1 -3
- data/lib/new_relic/agent/http_clients/ethon_wrappers.rb +109 -0
- data/lib/new_relic/agent/http_clients/excon_wrappers.rb +0 -3
- data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +1 -3
- data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +0 -3
- data/lib/new_relic/agent/http_clients/httpx_wrappers.rb +91 -0
- data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +1 -4
- data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +0 -3
- data/lib/new_relic/agent/http_clients/uri_util.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_controller_other_subscriber.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 +3 -16
- data/lib/new_relic/agent/instrumentation/active_record.rb +8 -13
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +8 -5
- data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +13 -10
- 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/chain.rb +69 -0
- data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/instrumentation.rb +17 -0
- data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/prepend.rb +37 -0
- data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger.rb +21 -0
- data/lib/new_relic/agent/instrumentation/active_support_logger/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/active_support_logger.rb +3 -3
- data/lib/new_relic/agent/instrumentation/async_http/chain.rb +23 -0
- data/lib/new_relic/agent/instrumentation/async_http/instrumentation.rb +37 -0
- data/lib/new_relic/agent/instrumentation/async_http/prepend.rb +15 -0
- data/lib/new_relic/agent/instrumentation/async_http.rb +27 -0
- 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/chain.rb +1 -1
- data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +23 -0
- data/lib/new_relic/agent/instrumentation/bunny.rb +4 -5
- data/lib/new_relic/agent/instrumentation/concurrent_ruby/chain.rb +1 -1
- data/lib/new_relic/agent/instrumentation/concurrent_ruby/instrumentation.rb +3 -4
- data/lib/new_relic/agent/instrumentation/concurrent_ruby/prepend.rb +1 -1
- data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +2 -3
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +5 -2
- data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/curb.rb +4 -5
- data/lib/new_relic/agent/instrumentation/delayed_job/chain.rb +1 -0
- data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +3 -0
- 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 +2 -3
- data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +65 -10
- data/lib/new_relic/agent/instrumentation/elasticsearch.rb +2 -4
- data/lib/new_relic/agent/instrumentation/ethon/chain.rb +39 -0
- data/lib/new_relic/agent/instrumentation/ethon/instrumentation.rb +105 -0
- data/lib/new_relic/agent/instrumentation/ethon/prepend.rb +35 -0
- data/lib/new_relic/agent/instrumentation/ethon.rb +35 -0
- data/lib/new_relic/agent/instrumentation/excon/middleware.rb +3 -0
- data/lib/new_relic/agent/instrumentation/excon.rb +1 -17
- data/lib/new_relic/agent/instrumentation/fiber/chain.rb +11 -4
- data/lib/new_relic/agent/instrumentation/fiber/instrumentation.rb +2 -6
- data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +10 -3
- data/lib/new_relic/agent/instrumentation/fiber.rb +1 -3
- data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +4 -3
- data/lib/new_relic/agent/instrumentation/grape.rb +1 -1
- data/lib/new_relic/agent/instrumentation/grpc/client/chain.rb +1 -1
- data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +5 -2
- data/lib/new_relic/agent/instrumentation/grpc/client/prepend.rb +1 -1
- data/lib/new_relic/agent/instrumentation/grpc/client/request_wrapper.rb +1 -1
- data/lib/new_relic/agent/instrumentation/grpc/server/instrumentation.rb +5 -1
- data/lib/new_relic/agent/instrumentation/grpc_client.rb +2 -2
- data/lib/new_relic/agent/instrumentation/grpc_server.rb +2 -2
- data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -5
- data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/httprb.rb +0 -1
- data/lib/new_relic/agent/instrumentation/httpx/chain.rb +20 -0
- data/lib/new_relic/agent/instrumentation/httpx/instrumentation.rb +51 -0
- data/lib/new_relic/agent/instrumentation/httpx/prepend.rb +15 -0
- data/lib/new_relic/agent/instrumentation/httpx.rb +23 -0
- data/lib/new_relic/agent/instrumentation/logger/instrumentation.rb +3 -0
- 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 +4 -2
- data/lib/new_relic/agent/instrumentation/memcache/helper.rb +2 -2
- data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +13 -4
- data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +4 -2
- data/lib/new_relic/agent/instrumentation/memcache.rb +4 -5
- data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +3 -5
- data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +13 -3
- data/lib/new_relic/agent/instrumentation/net_http.rb +2 -1
- data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +4 -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/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/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/padrino.rb +3 -3
- data/lib/new_relic/agent/instrumentation/queue_time.rb +1 -1
- data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +9 -0
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +4 -0
- data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +1 -1
- data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +10 -5
- data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +4 -0
- 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 +18 -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/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/resque.rb +8 -6
- data/lib/new_relic/agent/instrumentation/roda/chain.rb +43 -0
- data/lib/new_relic/agent/instrumentation/roda/ignorer.rb +45 -0
- data/lib/new_relic/agent/instrumentation/roda/instrumentation.rb +68 -0
- data/lib/new_relic/agent/instrumentation/roda/prepend.rb +24 -0
- data/lib/new_relic/agent/instrumentation/roda/roda_transaction_namer.rb +29 -0
- data/lib/new_relic/agent/instrumentation/roda.rb +36 -0
- 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/chain.rb +36 -0
- data/lib/new_relic/agent/instrumentation/ruby_openai/instrumentation.rb +196 -0
- data/lib/new_relic/agent/instrumentation/ruby_openai/prepend.rb +20 -0
- data/lib/new_relic/agent/instrumentation/ruby_openai.rb +35 -0
- data/lib/new_relic/agent/instrumentation/sequel.rb +1 -1
- data/lib/new_relic/agent/instrumentation/sidekiq/client.rb +4 -0
- 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/server.rb +26 -3
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +13 -16
- data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +1 -1
- data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/sinatra/transaction_namer.rb +1 -3
- data/lib/new_relic/agent/instrumentation/sinatra.rb +3 -19
- data/lib/new_relic/agent/instrumentation/stripe.rb +28 -0
- data/lib/new_relic/agent/instrumentation/stripe_subscriber.rb +98 -0
- data/lib/new_relic/agent/instrumentation/thread/chain.rb +1 -1
- data/lib/new_relic/agent/instrumentation/thread/instrumentation.rb +1 -5
- data/lib/new_relic/agent/instrumentation/thread/prepend.rb +1 -1
- data/lib/new_relic/agent/instrumentation/thread.rb +0 -2
- data/lib/new_relic/agent/instrumentation/tilt/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/tilt.rb +0 -4
- data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +7 -3
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +0 -1
- data/lib/new_relic/agent/instrumentation/view_component/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/view_component/instrumentation.rb +45 -0
- data/lib/{tasks/instrumentation_generator/templates/instrumentation.tt → new_relic/agent/instrumentation/view_component/prepend.rb} +4 -4
- data/lib/new_relic/agent/instrumentation/view_component.rb +24 -0
- data/lib/new_relic/agent/javascript_instrumentor.rb +2 -4
- data/lib/new_relic/agent/llm/chat_completion_message.rb +25 -0
- data/lib/new_relic/agent/llm/chat_completion_summary.rb +66 -0
- data/lib/new_relic/agent/llm/embedding.rb +60 -0
- data/lib/new_relic/agent/llm/llm_event.rb +95 -0
- data/lib/new_relic/agent/llm/response_headers.rb +80 -0
- data/lib/new_relic/agent/llm.rb +49 -0
- data/lib/new_relic/agent/local_log_decorator.rb +20 -3
- data/lib/new_relic/agent/log_event_aggregator.rb +149 -26
- data/lib/new_relic/agent/log_event_attributes.rb +115 -0
- data/lib/new_relic/agent/logging.rb +5 -5
- data/lib/new_relic/agent/messaging.rb +18 -7
- data/lib/new_relic/agent/method_tracer.rb +4 -1
- data/lib/new_relic/agent/method_tracer_helpers.rb +26 -5
- data/lib/new_relic/agent/monitors/inbound_request_monitor.rb +1 -1
- data/lib/new_relic/agent/monitors/synthetics_monitor.rb +12 -1
- data/lib/new_relic/agent/new_relic_service/encoders.rb +2 -2
- data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +2 -2
- data/lib/new_relic/agent/new_relic_service.rb +61 -28
- data/lib/new_relic/agent/obfuscator.rb +0 -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/pipe_channel_manager.rb +2 -2
- data/lib/new_relic/agent/pipe_service.rb +1 -1
- data/lib/new_relic/agent/rules_engine/segment_terms_rule.rb +1 -2
- data/lib/new_relic/agent/rules_engine.rb +1 -1
- data/lib/new_relic/agent/sampler.rb +1 -0
- 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 +406 -0
- 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 +32 -15
- data/lib/new_relic/agent/sql_sampler.rb +0 -1
- data/lib/new_relic/agent/system_info.rb +40 -0
- data/lib/new_relic/agent/threading/agent_thread.rb +1 -2
- data/lib/new_relic/agent/threading/backtrace_node.rb +10 -1
- data/lib/new_relic/agent/tracer.rb +16 -16
- data/lib/new_relic/agent/transaction/abstract_segment.rb +103 -41
- 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/distributed_tracing.rb +7 -8
- data/lib/new_relic/agent/transaction/external_request_segment.rb +5 -12
- data/lib/new_relic/agent/transaction/message_broker_segment.rb +5 -3
- data/lib/new_relic/agent/transaction/request_attributes.rb +54 -11
- data/lib/new_relic/agent/transaction/trace_context.rb +34 -5
- data/lib/new_relic/agent/transaction/tracing.rb +20 -4
- data/lib/new_relic/agent/transaction.rb +38 -13
- data/lib/new_relic/agent/transaction_error_primitive.rb +39 -19
- data/lib/new_relic/agent/transaction_event_primitive.rb +19 -0
- 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/gcp.rb +1 -3
- data/lib/new_relic/agent/utilization/vendor.rb +5 -7
- data/lib/new_relic/agent/utilization_data.rb +40 -5
- data/lib/new_relic/agent/vm/{mri_vm.rb → c_ruby_vm.rb} +10 -18
- data/lib/new_relic/agent/vm.rb +2 -2
- data/lib/new_relic/agent/worker_loop.rb +1 -1
- data/lib/new_relic/agent.rb +286 -17
- data/lib/new_relic/base64.rb +25 -0
- data/lib/new_relic/cli/command.rb +6 -3
- data/lib/new_relic/constants.rb +8 -0
- data/lib/new_relic/control/class_methods.rb +1 -7
- 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/rails.rb +17 -5
- data/lib/new_relic/control/frameworks/rails4.rb +1 -3
- data/lib/new_relic/control/frameworks/roda.rb +20 -0
- data/lib/new_relic/control/instance_methods.rb +13 -0
- data/lib/new_relic/control/instrumentation.rb +2 -16
- 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 +25 -13
- data/lib/new_relic/environment_report.rb +2 -2
- data/lib/new_relic/helper.rb +22 -0
- data/lib/new_relic/language_support.rb +12 -1
- data/lib/new_relic/latest_changes.rb +1 -1
- data/lib/new_relic/local_environment.rb +31 -18
- data/lib/new_relic/noticed_error.rb +5 -2
- data/lib/new_relic/rack/agent_hooks.rb +1 -1
- data/lib/new_relic/rack/agent_middleware.rb +0 -16
- data/lib/new_relic/rack/browser_monitoring.rb +29 -13
- data/lib/new_relic/supportability_helper.rb +5 -1
- data/lib/new_relic/thread_local_storage.rb +31 -0
- data/lib/new_relic/traced_thread.rb +2 -3
- data/lib/new_relic/version.rb +1 -1
- data/lib/sequel/extensions/new_relic_instrumentation.rb +4 -3
- data/lib/tasks/bump_version.rake +21 -0
- data/lib/tasks/config.rake +11 -5
- data/lib/tasks/coverage_report.rake +1 -1
- data/lib/tasks/gha.rake +31 -0
- data/lib/tasks/helpers/config.html.erb +94 -0
- data/lib/tasks/helpers/format.rb +11 -7
- data/lib/tasks/helpers/newrelicyml.rb +211 -0
- data/lib/tasks/helpers/version_bump.rb +62 -0
- data/lib/tasks/newrelic.rb +1 -0
- data/lib/tasks/newrelicyml.rake +13 -0
- data/lib/tasks/tests.rake +71 -0
- data/newrelic.yml +657 -251
- data/newrelic_rpm.gemspec +17 -10
- data/test/agent_helper.rb +38 -4
- metadata +230 -44
- data/.gitignore +0 -43
- data/.project +0 -23
- data/.rubocop.yml +0 -1909
- data/.rubocop_todo.yml +0 -61
- data/.simplecov +0 -15
- data/.snyk +0 -11
- data/.yardopts +0 -27
- data/Brewfile +0 -12
- data/DOCKER.md +0 -167
- data/Dockerfile +0 -10
- data/Guardfile +0 -26
- data/bin/newrelic_cmd +0 -6
- data/config/database.yml +0 -5
- data/config.dot +0 -278
- data/docker-compose.yml +0 -107
- data/lefthook.yml +0 -9
- data/lib/new_relic/agent/range_extensions.rb +0 -27
- data/lib/tasks/helpers/removers.rb +0 -33
- 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 -22
- data/lib/tasks/instrumentation_generator/templates/chain_method.tt +0 -8
- 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
- data/lib/tasks/multiverse.rake +0 -6
- data/lib/tasks/multiverse.rb +0 -83
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
# NOTE: there are multiple implementations of the Memcached client in Ruby,
|
|
6
6
|
# each with slightly different APIs and semantics.
|
|
7
7
|
# See:
|
|
8
|
-
#
|
|
9
|
-
#
|
|
8
|
+
# https://rubygems.org/gems/Ruby-MemCache (Gem: Ruby-MemCache)
|
|
9
|
+
# https://github.com/mperham/memcache-client (Gem: memcache-client)
|
|
10
10
|
# https://github.com/mperham/dalli (Gem: dalli)
|
|
11
11
|
|
|
12
12
|
require_relative 'memcache/helper'
|
|
@@ -58,7 +58,7 @@ DependencyDetection.defer do
|
|
|
58
58
|
prepend_instrument client_class, instrumenting_module, 'MemcachedDalli'
|
|
59
59
|
end
|
|
60
60
|
else
|
|
61
|
-
chain_instrument NewRelic::Agent::Instrumentation::Memcache::Dalli
|
|
61
|
+
chain_instrument NewRelic::Agent::Instrumentation::Memcache::Dalli, 'MemcachedDalli'
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
end
|
|
@@ -74,14 +74,13 @@ 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|
|
|
81
80
|
prepend_instrument client_class, instrumenting_module, 'MemcachedDalliCAS'
|
|
82
81
|
end
|
|
83
82
|
else
|
|
84
|
-
chain_instrument NewRelic::Agent::Instrumentation::Memcache::DalliCAS
|
|
83
|
+
chain_instrument NewRelic::Agent::Instrumentation::Memcache::DalliCAS, 'MemcachedDalliCAS'
|
|
85
84
|
end
|
|
86
85
|
end
|
|
87
86
|
end
|
|
@@ -21,7 +21,7 @@ module NewRelic
|
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
ERROR_KEYS = %w[
|
|
24
|
+
ERROR_KEYS = %w[writeErrors writeConcernError writeConcernErrors].freeze
|
|
25
25
|
|
|
26
26
|
def error_key_present?(event)
|
|
27
27
|
if reply = event.reply
|
|
@@ -106,7 +106,7 @@ module NewRelic
|
|
|
106
106
|
)
|
|
107
107
|
end
|
|
108
108
|
|
|
109
|
-
UNKNOWN =
|
|
109
|
+
UNKNOWN = NewRelic::UNKNOWN_LOWER
|
|
110
110
|
LOCALHOST = 'localhost'.freeze
|
|
111
111
|
|
|
112
112
|
def host_from_address(address)
|
|
@@ -131,10 +131,8 @@ module NewRelic
|
|
|
131
131
|
UNKNOWN
|
|
132
132
|
end
|
|
133
133
|
|
|
134
|
-
SLASH = '/'.freeze
|
|
135
|
-
|
|
136
134
|
def unix_domain_socket?(host)
|
|
137
|
-
host.start_with?(SLASH)
|
|
135
|
+
host.start_with?(NewRelic::SLASH)
|
|
138
136
|
end
|
|
139
137
|
end
|
|
140
138
|
end
|
|
@@ -6,7 +6,11 @@ module NewRelic
|
|
|
6
6
|
module Agent
|
|
7
7
|
module Instrumentation
|
|
8
8
|
module NetHTTP
|
|
9
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
|
10
|
+
|
|
9
11
|
def request_with_tracing(request)
|
|
12
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
|
13
|
+
|
|
10
14
|
wrapped_request = NewRelic::Agent::HTTPClients::NetHTTPRequest.new(self, request)
|
|
11
15
|
|
|
12
16
|
segment = NewRelic::Agent::Tracer.start_external_request_segment(
|
|
@@ -17,7 +21,7 @@ module NewRelic
|
|
|
17
21
|
|
|
18
22
|
begin
|
|
19
23
|
response = nil
|
|
20
|
-
segment
|
|
24
|
+
segment&.add_request_headers(wrapped_request)
|
|
21
25
|
|
|
22
26
|
# RUBY-1244 Disable further tracing in request to avoid double
|
|
23
27
|
# counting if connection wasn't started (which calls request again).
|
|
@@ -28,10 +32,16 @@ module NewRelic
|
|
|
28
32
|
end
|
|
29
33
|
|
|
30
34
|
wrapped_response = NewRelic::Agent::HTTPClients::NetHTTPResponse.new(response)
|
|
31
|
-
|
|
35
|
+
|
|
36
|
+
if NewRelic::Agent::LLM.openai_parent?(segment)
|
|
37
|
+
NewRelic::Agent::LLM.populate_openai_response_headers(wrapped_response, segment&.parent)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
segment&.process_response_headers(wrapped_response)
|
|
41
|
+
|
|
32
42
|
response
|
|
33
43
|
ensure
|
|
34
|
-
segment
|
|
44
|
+
segment&.finish
|
|
35
45
|
end
|
|
36
46
|
end
|
|
37
47
|
end
|
|
@@ -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
|
|
|
@@ -47,6 +45,10 @@ module NewRelic
|
|
|
47
45
|
end
|
|
48
46
|
end
|
|
49
47
|
|
|
48
|
+
# The agent doesn't use the traditional ActiveSupport::Notifications.subscribe
|
|
49
|
+
# pattern due to threading issues discovered on initial instrumentation.
|
|
50
|
+
# Instead we define a #start and #finish method, which Rails responds to.
|
|
51
|
+
# See: https://github.com/rails/rails/issues/12069
|
|
50
52
|
def start(name, id, payload)
|
|
51
53
|
return unless state.is_execution_traced?
|
|
52
54
|
|
|
@@ -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
|
|
@@ -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,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
|
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
module NewRelic::Agent::Instrumentation
|
|
6
6
|
module Padrino
|
|
7
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
|
8
|
+
|
|
7
9
|
def invoke_route_with_tracing(*args)
|
|
10
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
|
11
|
+
|
|
8
12
|
begin
|
|
9
13
|
env['newrelic.last_route'] = args[0].original_path
|
|
10
14
|
rescue => e
|
|
@@ -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
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
module NewRelic
|
|
6
6
|
module Agent
|
|
7
7
|
module Instrumentation
|
|
8
|
-
# https://newrelic.com/docs/features/tracking-front-end-time
|
|
8
|
+
# https://docs.newrelic.com/docs/features/tracking-front-end-time
|
|
9
9
|
# Record queue time metrics based on any of three headers
|
|
10
10
|
# which can be set on the request.
|
|
11
11
|
module QueueTime
|
|
@@ -6,11 +6,14 @@ module NewRelic
|
|
|
6
6
|
module Agent
|
|
7
7
|
module Instrumentation
|
|
8
8
|
module RackBuilder
|
|
9
|
+
INSTRUMENTATION_NAME = 'Rack'
|
|
10
|
+
|
|
9
11
|
def self.track_deferred_detection(builder_class)
|
|
10
12
|
class << builder_class
|
|
11
13
|
attr_accessor :_nr_deferred_detection_ran
|
|
12
14
|
end
|
|
13
15
|
builder_class._nr_deferred_detection_ran = false
|
|
16
|
+
NewRelic::Control::SecurityInterface.instance.wait = true
|
|
14
17
|
end
|
|
15
18
|
|
|
16
19
|
def deferred_dependency_check
|
|
@@ -19,6 +22,8 @@ module NewRelic
|
|
|
19
22
|
NewRelic::Agent.logger.info('Doing deferred dependency-detection before Rack startup')
|
|
20
23
|
DependencyDetection.detect!
|
|
21
24
|
self.class._nr_deferred_detection_ran = true
|
|
25
|
+
NewRelic::Control::SecurityInterface.instance.wait = false
|
|
26
|
+
NewRelic::Control::SecurityInterface.instance.init_agent
|
|
22
27
|
end
|
|
23
28
|
|
|
24
29
|
def check_for_late_instrumentation(app)
|
|
@@ -51,6 +56,8 @@ module NewRelic
|
|
|
51
56
|
def run_with_tracing(app)
|
|
52
57
|
return yield(app) unless middleware_instrumentation_enabled?
|
|
53
58
|
|
|
59
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
|
60
|
+
|
|
54
61
|
yield(::NewRelic::Agent::Instrumentation::MiddlewareProxy.wrap(app, true))
|
|
55
62
|
end
|
|
56
63
|
|
|
@@ -58,6 +65,8 @@ module NewRelic
|
|
|
58
65
|
return if middleware_class.nil?
|
|
59
66
|
return yield(middleware_class) unless middleware_instrumentation_enabled?
|
|
60
67
|
|
|
68
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
|
69
|
+
|
|
61
70
|
yield(::NewRelic::Agent::Instrumentation::MiddlewareProxy.for_class(middleware_class))
|
|
62
71
|
end
|
|
63
72
|
end
|
|
@@ -9,6 +9,8 @@ module NewRelic
|
|
|
9
9
|
module Instrumentation
|
|
10
10
|
module Rails3
|
|
11
11
|
module ActionController
|
|
12
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
|
13
|
+
|
|
12
14
|
# determine the path that is used in the metric name for
|
|
13
15
|
# the called controller action
|
|
14
16
|
def newrelic_metric_path(action_name_override = nil)
|
|
@@ -21,6 +23,8 @@ module NewRelic
|
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def process_action(*args) # THREAD_LOCAL_ACCESS
|
|
26
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
|
27
|
+
|
|
24
28
|
munged_params = NewRelic::Agent::ParameterFiltering.filter_rails_request_parameters(request.filtered_parameters)
|
|
25
29
|
perform_action_with_newrelic_trace(:category => :controller,
|
|
26
30
|
:name => self.action_name,
|
|
@@ -25,7 +25,7 @@ DependencyDetection.defer do
|
|
|
25
25
|
|
|
26
26
|
executes do
|
|
27
27
|
# enumerate the specific events we want so that we do not get unexpected additions in the future
|
|
28
|
-
ActiveSupport::Notifications.subscribe(/\A(?:perform_action|transmit
|
|
28
|
+
ActiveSupport::Notifications.subscribe(/\A(?:perform_action|transmit.*|broadcast)\.action_cable\z/,
|
|
29
29
|
NewRelic::Agent::Instrumentation::ActionCableSubscriber.new)
|
|
30
30
|
|
|
31
31
|
ActiveSupport.on_load(:action_cable) do
|
|
@@ -32,14 +32,19 @@ DependencyDetection.defer do
|
|
|
32
32
|
NewRelic::Agent::Instrumentation::ActionControllerSubscriber \
|
|
33
33
|
.subscribe(/^process_action.action_controller$/)
|
|
34
34
|
|
|
35
|
-
subs = %w[
|
|
36
|
-
|
|
37
|
-
redirect_to
|
|
35
|
+
subs = %w[exist_fragment?
|
|
36
|
+
expire_fragment
|
|
38
37
|
halted_callback
|
|
39
|
-
|
|
38
|
+
read_fragment
|
|
39
|
+
redirect_to
|
|
40
|
+
send_data
|
|
41
|
+
send_file
|
|
42
|
+
send_stream
|
|
43
|
+
write_fragment
|
|
44
|
+
unpermitted_parameters].map { |s| Regexp.escape(s) }
|
|
40
45
|
|
|
41
46
|
# have to double escape period because its going from string -> regex
|
|
42
47
|
NewRelic::Agent::Instrumentation::ActionControllerOtherSubscriber \
|
|
43
|
-
.subscribe(Regexp.new("^(
|
|
48
|
+
.subscribe(Regexp.new("^(?:#{subs.join('|')})\\.action_controller$"))
|
|
44
49
|
end
|
|
45
50
|
end
|
|
@@ -7,11 +7,15 @@ module NewRelic
|
|
|
7
7
|
module Instrumentation
|
|
8
8
|
module Rake
|
|
9
9
|
module Tracer
|
|
10
|
+
INSTRUMENTATION_NAME = 'Rake'
|
|
11
|
+
|
|
10
12
|
def invoke_with_newrelic_tracing(*args)
|
|
11
13
|
unless NewRelic::Agent::Instrumentation::Rake.should_trace?(name)
|
|
12
14
|
return yield
|
|
13
15
|
end
|
|
14
16
|
|
|
17
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
|
18
|
+
|
|
15
19
|
begin
|
|
16
20
|
timeout = NewRelic::Agent.config[:'rake.connect_timeout']
|
|
17
21
|
NewRelic::Agent.instance.wait_on_connect(timeout)
|
|
@@ -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
|
|
@@ -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) && NewRelic::Helper.version_satisfied?(::Rdkafka::VERSION, '>=', '0.16.0')) ||
|
|
40
|
+
NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '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
|