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
|
@@ -68,6 +68,8 @@ module NewRelic
|
|
|
68
68
|
module Multi
|
|
69
69
|
include NewRelic::Agent::MethodTracer
|
|
70
70
|
|
|
71
|
+
INSTRUMENTATION_NAME = 'Curb'
|
|
72
|
+
|
|
71
73
|
# Add CAT with callbacks if the request is serial
|
|
72
74
|
def add_with_tracing(curl)
|
|
73
75
|
if curl.respond_to?(:_nr_serial) && curl._nr_serial
|
|
@@ -81,6 +83,8 @@ module NewRelic
|
|
|
81
83
|
def perform_with_tracing
|
|
82
84
|
return yield if first_request_is_serial?
|
|
83
85
|
|
|
86
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
|
87
|
+
|
|
84
88
|
trace_execution_scoped('External/Multiple/Curb::Multi/perform') do
|
|
85
89
|
yield
|
|
86
90
|
end
|
|
@@ -12,21 +12,20 @@ DependencyDetection.defer do
|
|
|
12
12
|
|
|
13
13
|
depends_on do
|
|
14
14
|
defined?(Curl) && defined?(Curl::CURB_VERSION) &&
|
|
15
|
-
|
|
15
|
+
NewRelic::Helper.version_satisfied?(Curl::CURB_VERSION, '>=', CURB_MIN_VERSION)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
executes do
|
|
19
|
-
NewRelic::Agent.logger.info('Installing Curb instrumentation')
|
|
20
19
|
require 'new_relic/agent/distributed_tracing/cross_app_tracing'
|
|
21
20
|
require 'new_relic/agent/http_clients/curb_wrappers'
|
|
22
21
|
end
|
|
23
22
|
|
|
24
23
|
executes do
|
|
25
24
|
if use_prepend?
|
|
26
|
-
prepend_instrument Curl::Easy, NewRelic::Agent::Instrumentation::Curb::Easy::Prepend
|
|
27
|
-
prepend_instrument Curl::Multi, NewRelic::Agent::Instrumentation::Curb::Multi::Prepend
|
|
25
|
+
prepend_instrument Curl::Easy, NewRelic::Agent::Instrumentation::Curb::Easy::Prepend, 'Curb::Easy'
|
|
26
|
+
prepend_instrument Curl::Multi, NewRelic::Agent::Instrumentation::Curb::Multi::Prepend, 'Curb::Multi'
|
|
28
27
|
else
|
|
29
|
-
chain_instrument NewRelic::Agent::Instrumentation::Curb::Chain
|
|
28
|
+
chain_instrument NewRelic::Agent::Instrumentation::Curb::Chain, NewRelic::Agent::Instrumentation::Curb::Multi::INSTRUMENTATION_NAME
|
|
30
29
|
end
|
|
31
30
|
end
|
|
32
31
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# This file is distributed under New Relic's license terms.
|
|
2
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
|
3
3
|
# frozen_string_literal: true
|
|
4
|
+
|
|
4
5
|
require_relative 'instrumentation'
|
|
5
6
|
|
|
6
7
|
module NewRelic::Agent::Instrumentation
|
|
@@ -31,8 +31,11 @@ module NewRelic
|
|
|
31
31
|
include NewRelic::Agent::Instrumentation::ControllerInstrumentation
|
|
32
32
|
|
|
33
33
|
NR_TRANSACTION_CATEGORY = 'OtherTransaction/DelayedJob'.freeze
|
|
34
|
+
INSTRUMENTATION_NAME = 'DelayedJob'
|
|
34
35
|
|
|
35
36
|
def invoke_job_with_tracing
|
|
37
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
|
38
|
+
|
|
36
39
|
options = {
|
|
37
40
|
:category => NR_TRANSACTION_CATEGORY,
|
|
38
41
|
:path => ::NewRelic::Agent::Instrumentation::DelayedJob::Naming.name_from_payload(payload_object)
|
|
@@ -82,10 +82,6 @@ DependencyDetection.defer do
|
|
|
82
82
|
defined?(Delayed) && defined?(Delayed::Worker)
|
|
83
83
|
end
|
|
84
84
|
|
|
85
|
-
executes do
|
|
86
|
-
NewRelic::Agent.logger.info('Installing DelayedJob instrumentation [part 1/2]')
|
|
87
|
-
end
|
|
88
|
-
|
|
89
85
|
executes do
|
|
90
86
|
if use_prepend?
|
|
91
87
|
prepend_instrument Delayed::Worker, NewRelic::Agent::Instrumentation::DelayedJob::Prepend
|
|
@@ -93,23 +89,4 @@ DependencyDetection.defer do
|
|
|
93
89
|
chain_instrument NewRelic::Agent::Instrumentation::DelayedJob::Chain
|
|
94
90
|
end
|
|
95
91
|
end
|
|
96
|
-
|
|
97
|
-
executes do
|
|
98
|
-
next unless delayed_job_version < Gem::Version.new('4.1.0')
|
|
99
|
-
|
|
100
|
-
deprecation_msg = 'Instrumentation for DelayedJob versions below 4.1.0 is deprecated.' \
|
|
101
|
-
'It will stop being monitored in version 9.0.0. ' \
|
|
102
|
-
'Please upgrade your DelayedJob version to continue receiving full support. ' \
|
|
103
|
-
|
|
104
|
-
NewRelic::Agent.logger.log_once(
|
|
105
|
-
:warn,
|
|
106
|
-
:deprecated_delayed_job_version,
|
|
107
|
-
deprecation_msg
|
|
108
|
-
)
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def delayed_job_version
|
|
112
|
-
# the following line needs else branch coverage
|
|
113
|
-
Gem.loaded_specs['delayed_job'].version if Gem.loaded_specs['delayed_job'] # rubocop:disable Style/SafeNavigation
|
|
114
|
-
end
|
|
115
92
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# This file is distributed under New Relic's license terms.
|
|
2
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
module NewRelic::Agent::Instrumentation
|
|
6
|
+
module DynamoDB::Chain
|
|
7
|
+
def self.instrument!
|
|
8
|
+
::Aws::DynamoDB::Client.class_eval do
|
|
9
|
+
include NewRelic::Agent::Instrumentation::DynamoDB
|
|
10
|
+
|
|
11
|
+
NewRelic::Agent::Instrumentation::DynamoDB::INSTRUMENTED_METHODS.each do |method_name|
|
|
12
|
+
alias_method("#{method_name}_without_new_relic".to_sym, method_name.to_sym)
|
|
13
|
+
|
|
14
|
+
define_method(method_name) do |*args|
|
|
15
|
+
instrument_method_with_new_relic(method_name, *args) { send("#{method_name}_without_new_relic".to_sym, *args) }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
alias_method(:build_request_without_new_relic, :build_request)
|
|
20
|
+
|
|
21
|
+
def build_request(*args)
|
|
22
|
+
build_request_with_new_relic(*args) { build_request_without_new_relic(*args) }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
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 DynamoDB
|
|
7
|
+
INSTRUMENTED_METHODS = %w[
|
|
8
|
+
create_table
|
|
9
|
+
delete_item
|
|
10
|
+
delete_table
|
|
11
|
+
get_item
|
|
12
|
+
put_item
|
|
13
|
+
query
|
|
14
|
+
scan
|
|
15
|
+
update_item
|
|
16
|
+
].freeze
|
|
17
|
+
|
|
18
|
+
PRODUCT = 'DynamoDB'
|
|
19
|
+
DEFAULT_HOST = 'dynamodb.amazonaws.com'
|
|
20
|
+
|
|
21
|
+
def instrument_method_with_new_relic(method_name, *args)
|
|
22
|
+
return yield unless NewRelic::Agent::Tracer.tracing_enabled?
|
|
23
|
+
|
|
24
|
+
NewRelic::Agent.record_instrumentation_invocation(PRODUCT)
|
|
25
|
+
|
|
26
|
+
segment = NewRelic::Agent::Tracer.start_datastore_segment(
|
|
27
|
+
product: PRODUCT,
|
|
28
|
+
operation: method_name,
|
|
29
|
+
host: config&.endpoint&.host || DEFAULT_HOST,
|
|
30
|
+
port_path_or_id: config&.endpoint&.port,
|
|
31
|
+
collection: args[0][:table_name]
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
arn = get_arn(args[0])
|
|
35
|
+
segment&.add_agent_attribute('cloud.resource_id', arn) if arn
|
|
36
|
+
|
|
37
|
+
@nr_captured_request = nil # clear request just in case
|
|
38
|
+
begin
|
|
39
|
+
NewRelic::Agent::Tracer.capture_segment_error(segment) { yield }
|
|
40
|
+
ensure
|
|
41
|
+
segment&.add_agent_attribute('aws.operation', method_name)
|
|
42
|
+
segment&.add_agent_attribute('aws.requestId', @nr_captured_request&.context&.http_response&.headers&.[]('x-amzn-requestid'))
|
|
43
|
+
segment&.add_agent_attribute('aws.region', config&.region)
|
|
44
|
+
segment&.finish
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def build_request_with_new_relic(*args)
|
|
49
|
+
@nr_captured_request = yield
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def nr_account_id
|
|
53
|
+
return @nr_account_id if defined?(@nr_account_id)
|
|
54
|
+
|
|
55
|
+
@nr_account_id = NewRelic::Agent::Aws.get_account_id(config)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def get_arn(params)
|
|
59
|
+
return unless params[:table_name]
|
|
60
|
+
|
|
61
|
+
NewRelic::Agent::Aws.create_arn(PRODUCT.downcase, "table/#{params[:table_name]}", config&.region, nr_account_id)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
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 DynamoDB::Prepend
|
|
7
|
+
include NewRelic::Agent::Instrumentation::DynamoDB
|
|
8
|
+
|
|
9
|
+
INSTRUMENTED_METHODS.each do |method_name|
|
|
10
|
+
define_method(method_name) do |*args|
|
|
11
|
+
instrument_method_with_new_relic(method_name, *args) { super(*args) }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def build_request(*args)
|
|
16
|
+
build_request_with_new_relic(*args) { super }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
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 'dynamodb/instrumentation'
|
|
6
|
+
require_relative 'dynamodb/chain'
|
|
7
|
+
require_relative 'dynamodb/prepend'
|
|
8
|
+
|
|
9
|
+
DependencyDetection.defer do
|
|
10
|
+
named :dynamodb
|
|
11
|
+
|
|
12
|
+
depends_on do
|
|
13
|
+
defined?(Aws::DynamoDB::Client)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
executes do
|
|
17
|
+
if use_prepend?
|
|
18
|
+
prepend_instrument Aws::DynamoDB::Client, NewRelic::Agent::Instrumentation::DynamoDB::Prepend
|
|
19
|
+
else
|
|
20
|
+
chain_instrument NewRelic::Agent::Instrumentation::DynamoDB::Chain
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
# frozen_string_literal: true
|
|
4
4
|
|
|
5
5
|
module NewRelic::Agent::Instrumentation
|
|
6
|
-
module Elasticsearch
|
|
6
|
+
module Elasticsearch::Chain
|
|
7
7
|
def self.instrument!
|
|
8
|
-
to_instrument = if ::
|
|
9
|
-
::Gem::Version.create('8.0.0')
|
|
8
|
+
to_instrument = if NewRelic::Helper.version_satisfied?(::Elasticsearch::VERSION, '<', '8.0.0')
|
|
10
9
|
::Elasticsearch::Transport::Client
|
|
11
10
|
else
|
|
12
11
|
::Elastic::Transport::Client
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# This file is distributed under New Relic's license terms.
|
|
2
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
|
3
3
|
# frozen_string_literal: true
|
|
4
|
+
|
|
4
5
|
require_relative '../../datastores/nosql_obfuscator'
|
|
5
6
|
|
|
6
7
|
module NewRelic::Agent::Instrumentation
|
|
@@ -8,16 +9,72 @@ module NewRelic::Agent::Instrumentation
|
|
|
8
9
|
PRODUCT_NAME = 'Elasticsearch'
|
|
9
10
|
OPERATION = 'perform_request'
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
# Pattern to use with client caller location strings. Look for a location
|
|
13
|
+
# that contains '/lib/elasticsearch/api/' and is NOT followed by the
|
|
14
|
+
# string held in the OPERATION constant
|
|
15
|
+
OPERATION_PATTERN = %r{/lib/elasticsearch/api/(?!.+#{OPERATION})}.freeze
|
|
16
|
+
|
|
17
|
+
# Use the OPERATION_PATTERN pattern to find the appropriate caller location
|
|
18
|
+
# that will contain the client instance method (example: 'search') and
|
|
19
|
+
# return that method name.
|
|
20
|
+
#
|
|
21
|
+
# A Ruby caller location matching the OPERATION_PATTERN will contain an
|
|
22
|
+
# elasticsearch client instance method name (such as "search"), and that
|
|
23
|
+
# method name will be used as the operation name.
|
|
24
|
+
#
|
|
25
|
+
# With Ruby < 3.4 the method name is listed as:
|
|
26
|
+
#
|
|
27
|
+
# `search'
|
|
28
|
+
#
|
|
29
|
+
# with an opening backtick and a closing single tick. And only the
|
|
30
|
+
# method name itself is listed.
|
|
31
|
+
#
|
|
32
|
+
# With Ruby 3.4+ the method name is listed as:
|
|
33
|
+
#
|
|
34
|
+
# 'Elasticsearch::API::Actions#search'
|
|
35
|
+
#
|
|
36
|
+
# with opening and closing single ticks and the class defining the
|
|
37
|
+
# instance method listed.
|
|
38
|
+
#
|
|
39
|
+
# (?:) = ?: prevents capturing
|
|
40
|
+
# (?:`|') = allow ` or '
|
|
41
|
+
# (?:.+#) = allow the class name and '#' prefix to exist but ignore it
|
|
42
|
+
# ([^']+)' = after the opening ` or ', capturing everything up to the
|
|
43
|
+
# closing '. [^']+ = one or more characters that are not '
|
|
44
|
+
#
|
|
45
|
+
# Example Ruby 3.3.1 input:
|
|
46
|
+
#
|
|
47
|
+
# /Users/fallwith/.rubies/ruby-3.3.1/lib/ruby/gems/3.3.0/gems/elasticsearch-api-7.17.10/lib/elasticsearch/api/actions/index.rb:74:in `index'
|
|
48
|
+
#
|
|
49
|
+
# Example Ruby 3.4.0-preview1 input:
|
|
50
|
+
#
|
|
51
|
+
# /Users/fallwith/.rubies/ruby-3.4.0-preview1/lib/ruby/gems/3.4.0+0/gems/elasticsearch-api-7.17.10/lib/elasticsearch/api/actions/index.rb:74:in 'Elasticsearch::API::Actions#index'
|
|
52
|
+
#
|
|
53
|
+
# Example output for both Rubies:
|
|
54
|
+
#
|
|
55
|
+
# index
|
|
56
|
+
|
|
57
|
+
INSTANCE_METHOD_PATTERN = /:in (?:`|')(?:.+#)?([^']+)'\z/.freeze
|
|
58
|
+
|
|
59
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
|
60
|
+
|
|
61
|
+
# We need the positional arguments `params` and `body`
|
|
62
|
+
# to capture the nosql statement
|
|
63
|
+
# *args protects the instrumented method if new arguments are added to
|
|
64
|
+
# perform_request
|
|
65
|
+
def perform_request_with_tracing(_method, _path, params = {}, body = nil, _headers = nil, *_args)
|
|
12
66
|
return yield unless NewRelic::Agent::Tracer.tracing_enabled?
|
|
13
67
|
|
|
68
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
|
69
|
+
|
|
14
70
|
segment = NewRelic::Agent::Tracer.start_datastore_segment(
|
|
15
71
|
product: PRODUCT_NAME,
|
|
16
72
|
operation: nr_operation || OPERATION,
|
|
17
73
|
host: nr_hosts[:host],
|
|
18
|
-
port_path_or_id:
|
|
74
|
+
port_path_or_id: nr_hosts[:port],
|
|
19
75
|
database_name: nr_cluster_name
|
|
20
76
|
)
|
|
77
|
+
|
|
21
78
|
begin
|
|
22
79
|
NewRelic::Agent::Tracer.capture_segment_error(segment) { yield }
|
|
23
80
|
ensure
|
|
@@ -31,13 +88,10 @@ module NewRelic::Agent::Instrumentation
|
|
|
31
88
|
private
|
|
32
89
|
|
|
33
90
|
def nr_operation
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
string.include?('lib/elasticsearch/api') && !string.include?(OPERATION)
|
|
37
|
-
end
|
|
38
|
-
return nil unless operation_index
|
|
91
|
+
location = caller_locations.detect { |loc| loc.to_s.match?(OPERATION_PATTERN) }
|
|
92
|
+
return unless location && location.to_s =~ INSTANCE_METHOD_PATTERN
|
|
39
93
|
|
|
40
|
-
|
|
94
|
+
Regexp.last_match(1)
|
|
41
95
|
end
|
|
42
96
|
|
|
43
97
|
def nr_reported_query(query)
|
|
@@ -48,11 +102,12 @@ module NewRelic::Agent::Instrumentation
|
|
|
48
102
|
end
|
|
49
103
|
|
|
50
104
|
def nr_cluster_name
|
|
51
|
-
return
|
|
105
|
+
return unless NewRelic::Agent.config[:'elasticsearch.capture_cluster_name']
|
|
106
|
+
return @nr_cluster_name if defined?(@nr_cluster_name)
|
|
52
107
|
return if nr_hosts.empty?
|
|
53
108
|
|
|
54
109
|
NewRelic::Agent.disable_all_tracing do
|
|
55
|
-
@nr_cluster_name ||= perform_request('GET', '
|
|
110
|
+
@nr_cluster_name ||= perform_request('GET', '/').body['cluster_name']
|
|
56
111
|
end
|
|
57
112
|
rescue StandardError => e
|
|
58
113
|
NewRelic::Agent.logger.error('Failed to get cluster name for elasticsearch', e)
|
|
@@ -14,9 +14,7 @@ DependencyDetection.defer do
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
executes do
|
|
17
|
-
NewRelic::
|
|
18
|
-
|
|
19
|
-
to_instrument = if Gem::Version.create(Elasticsearch::VERSION) < Gem::Version.create('8.0.0')
|
|
17
|
+
to_instrument = if NewRelic::Helper.version_satisfied?(Elasticsearch::VERSION, '<', '8.0.0')
|
|
20
18
|
Elasticsearch::Transport::Client
|
|
21
19
|
else
|
|
22
20
|
Elastic::Transport::Client
|
|
@@ -25,7 +23,7 @@ DependencyDetection.defer do
|
|
|
25
23
|
if use_prepend?
|
|
26
24
|
prepend_instrument to_instrument, NewRelic::Agent::Instrumentation::Elasticsearch::Prepend
|
|
27
25
|
else
|
|
28
|
-
chain_instrument NewRelic::Agent::Instrumentation::Elasticsearch
|
|
26
|
+
chain_instrument NewRelic::Agent::Instrumentation::Elasticsearch::Chain
|
|
29
27
|
end
|
|
30
28
|
end
|
|
31
29
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
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 Ethon
|
|
7
|
+
module Chain
|
|
8
|
+
def self.instrument!
|
|
9
|
+
::Ethon::Easy.class_eval do
|
|
10
|
+
include NewRelic::Agent::Instrumentation::Ethon::Easy
|
|
11
|
+
|
|
12
|
+
alias_method(:fabricate_without_tracing, :fabricate)
|
|
13
|
+
def fabricate(url, action_name, options)
|
|
14
|
+
fabricate_with_tracing(url, action_name, options) { fabricate_without_tracing(url, action_name, options) }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
alias_method(:headers_equals_without_tracing, :headers=)
|
|
18
|
+
def headers=(headers)
|
|
19
|
+
headers_equals_with_tracing(headers) { headers_equals_without_tracing(headers) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
alias_method(:perform_without_tracing, :perform)
|
|
23
|
+
def perform(*args)
|
|
24
|
+
perform_with_tracing(*args) { perform_without_tracing(*args) }
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
::Ethon::Multi.class_eval do
|
|
29
|
+
include NewRelic::Agent::Instrumentation::Ethon::Multi
|
|
30
|
+
|
|
31
|
+
alias_method(:perform_without_tracing, :perform)
|
|
32
|
+
def perform(*args)
|
|
33
|
+
perform_with_tracing(*args) { perform_without_tracing(*args) }
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
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/http_clients/ethon_wrappers'
|
|
6
|
+
|
|
7
|
+
module NewRelic::Agent::Instrumentation
|
|
8
|
+
module Ethon
|
|
9
|
+
module NRShared
|
|
10
|
+
INSTRUMENTATION_NAME = 'Ethon'
|
|
11
|
+
NOTICEABLE_ERROR_CLASS = 'Ethon::Errors::EthonError'
|
|
12
|
+
|
|
13
|
+
def prep_easy(easy, parent = nil)
|
|
14
|
+
wrapped_request = NewRelic::Agent::HTTPClients::EthonHTTPRequest.new(easy)
|
|
15
|
+
segment = NewRelic::Agent::Tracer.start_external_request_segment(
|
|
16
|
+
library: wrapped_request.type,
|
|
17
|
+
uri: wrapped_request.uri,
|
|
18
|
+
procedure: wrapped_request.method,
|
|
19
|
+
parent: parent
|
|
20
|
+
)
|
|
21
|
+
segment.add_request_headers(wrapped_request)
|
|
22
|
+
|
|
23
|
+
callback = proc do
|
|
24
|
+
wrapped_response = NewRelic::Agent::HTTPClients::EthonHTTPResponse.new(easy)
|
|
25
|
+
segment.process_response_headers(wrapped_response)
|
|
26
|
+
|
|
27
|
+
if easy.return_code != :ok
|
|
28
|
+
e = NewRelic::Agent::NoticeableError.new(NOTICEABLE_ERROR_CLASS,
|
|
29
|
+
"return_code: >>#{easy.return_code}<<, response_code: >>#{easy.response_code}<<")
|
|
30
|
+
segment.notice_error(e)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
::NewRelic::Agent::Transaction::Segment.finish(segment)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
easy.on_complete { callback.call }
|
|
37
|
+
|
|
38
|
+
segment
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def wrap_with_tracing(segment, &block)
|
|
42
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
|
43
|
+
|
|
44
|
+
NewRelic::Agent::Tracer.capture_segment_error(segment) do
|
|
45
|
+
yield
|
|
46
|
+
end
|
|
47
|
+
ensure
|
|
48
|
+
NewRelic::Agent::Transaction::Segment.finish(segment)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
module Easy
|
|
53
|
+
include NRShared
|
|
54
|
+
|
|
55
|
+
ACTION_INSTANCE_VAR = :@nr_action
|
|
56
|
+
HEADERS_INSTANCE_VAR = :@nr_headers
|
|
57
|
+
|
|
58
|
+
# `Ethon::Easy` doesn't expose the "action name" ('GET', 'POST', etc.)
|
|
59
|
+
# and Ethon's fabrication of HTTP classes uses
|
|
60
|
+
# `Ethon::Easy::Http::Custom` for non-standard actions. To be able to
|
|
61
|
+
# know the action name at `#perform` time, we set a new instance variable
|
|
62
|
+
# on the `Ethon::Easy` instance with the base name of the fabricated
|
|
63
|
+
# class, respecting the 'Custom' name where appropriate.
|
|
64
|
+
def fabricate_with_tracing(_url, action_name, _options)
|
|
65
|
+
fabbed = yield
|
|
66
|
+
instance_variable_set(ACTION_INSTANCE_VAR, NewRelic::Agent.base_name(fabbed.class.name).upcase)
|
|
67
|
+
fabbed
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# `Ethon::Easy` uses `Ethon::Easy::Header` to set request headers on
|
|
71
|
+
# libcurl with `#headers=`. After they are set, they aren't easy to get
|
|
72
|
+
# at again except via FFI so set a new instance variable on the
|
|
73
|
+
# `Ethon::Easy` instance to store them in Ruby hash format.
|
|
74
|
+
def headers_equals_with_tracing(headers)
|
|
75
|
+
instance_variable_set(HEADERS_INSTANCE_VAR, headers)
|
|
76
|
+
yield
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def perform_with_tracing(*args)
|
|
80
|
+
return unless NewRelic::Agent::Tracer.state.is_execution_traced?
|
|
81
|
+
|
|
82
|
+
segment = prep_easy(self)
|
|
83
|
+
wrap_with_tracing(segment) { yield }
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
module Multi
|
|
88
|
+
include NRShared
|
|
89
|
+
|
|
90
|
+
MULTI_SEGMENT_NAME = 'External/Multiple/Ethon::Multi/perform'
|
|
91
|
+
|
|
92
|
+
def perform_with_tracing(*args)
|
|
93
|
+
return unless NewRelic::Agent::Tracer.state.is_execution_traced?
|
|
94
|
+
|
|
95
|
+
segment = NewRelic::Agent::Tracer.start_segment(name: MULTI_SEGMENT_NAME)
|
|
96
|
+
|
|
97
|
+
wrap_with_tracing(segment) do
|
|
98
|
+
easy_handles.each { |easy| prep_easy(easy, segment) }
|
|
99
|
+
|
|
100
|
+
yield
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
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 Ethon
|
|
7
|
+
module Easy
|
|
8
|
+
module Prepend
|
|
9
|
+
include NewRelic::Agent::Instrumentation::Ethon::Easy
|
|
10
|
+
|
|
11
|
+
def fabricate(url, action_name, options)
|
|
12
|
+
fabricate_with_tracing(url, action_name, options) { super }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def headers=(headers)
|
|
16
|
+
headers_equals_with_tracing(headers) { super }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def perform(*args)
|
|
20
|
+
perform_with_tracing(*args) { super }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
module Multi
|
|
26
|
+
module Prepend
|
|
27
|
+
include NewRelic::Agent::Instrumentation::Ethon::Multi
|
|
28
|
+
|
|
29
|
+
def perform(*args)
|
|
30
|
+
perform_with_tracing(*args) { super }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
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 'ethon/instrumentation'
|
|
6
|
+
require_relative 'ethon/chain'
|
|
7
|
+
require_relative 'ethon/prepend'
|
|
8
|
+
|
|
9
|
+
DependencyDetection.defer do
|
|
10
|
+
named :ethon
|
|
11
|
+
|
|
12
|
+
# If Ethon is being used as a dependency of Typhoeus, allow the Typhoeus
|
|
13
|
+
# instrumentation to handle everything. Otherwise each external network call
|
|
14
|
+
# will confusingly result in "Ethon" segments duplicating the information
|
|
15
|
+
# already provided by "Typhoeus" segments.
|
|
16
|
+
depends_on do
|
|
17
|
+
!defined?(Typhoeus)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
depends_on do
|
|
21
|
+
defined?(Ethon) && NewRelic::Helper.version_satisfied?(Ethon::VERSION, '>=', '0.12.0')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
executes do
|
|
25
|
+
if use_prepend?
|
|
26
|
+
# NOTE: by default prepend_instrument will go with the module name that
|
|
27
|
+
# precedes 'Prepend' (so 'Easy' and 'Multi'), but we want to use
|
|
28
|
+
# 'Ethon::Easy' and 'Ethon::Multi' so 3rd argument is supplied
|
|
29
|
+
prepend_instrument Ethon::Easy, NewRelic::Agent::Instrumentation::Ethon::Easy::Prepend, Ethon::Easy.name
|
|
30
|
+
prepend_instrument Ethon::Multi, NewRelic::Agent::Instrumentation::Ethon::Multi::Prepend, Ethon::Multi.name
|
|
31
|
+
else
|
|
32
|
+
chain_instrument NewRelic::Agent::Instrumentation::Ethon::Chain
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -6,6 +6,7 @@ module ::Excon
|
|
|
6
6
|
module Middleware
|
|
7
7
|
class NewRelicCrossAppTracing
|
|
8
8
|
TRACE_DATA_IVAR = :@newrelic_trace_data
|
|
9
|
+
INSTRUMENTATION_NAME = 'Excon'
|
|
9
10
|
|
|
10
11
|
def initialize(stack)
|
|
11
12
|
@stack = stack
|
|
@@ -18,6 +19,8 @@ module ::Excon
|
|
|
18
19
|
# :idempotent in the options, but there will be only a single
|
|
19
20
|
# accompanying response_call/error_call.
|
|
20
21
|
if datum[:connection] && !datum[:connection].instance_variable_get(TRACE_DATA_IVAR)
|
|
22
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
|
23
|
+
|
|
21
24
|
wrapped_request = ::NewRelic::Agent::HTTPClients::ExconHTTPRequest.new(datum)
|
|
22
25
|
segment = NewRelic::Agent::Tracer.start_external_request_segment(
|
|
23
26
|
library: wrapped_request.type,
|
|
@@ -26,29 +26,13 @@ DependencyDetection.defer do
|
|
|
26
26
|
|
|
27
27
|
executes do
|
|
28
28
|
excon_version = Gem::Version.new(Excon::VERSION)
|
|
29
|
-
if excon_version >= EXCON_MIN_VERSION
|
|
29
|
+
if NewRelic::Helper.version_satisfied?(excon_version, '>=', EXCON_MIN_VERSION)
|
|
30
30
|
install_excon_instrumentation(excon_version)
|
|
31
31
|
else
|
|
32
32
|
NewRelic::Agent.logger.warn("Excon instrumentation requires at least version #{EXCON_MIN_VERSION}")
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
executes do
|
|
37
|
-
next unless Gem::Version.new(Excon::VERSION) < Gem::Version.new('0.56.0')
|
|
38
|
-
|
|
39
|
-
deprecation_msg = 'Instrumentation for Excon versions below 0.56.0 is deprecated.' \
|
|
40
|
-
'They will stop being monitored in version 9.0.0. ' \
|
|
41
|
-
'Please upgrade your Excon version to continue receiving full support. '
|
|
42
|
-
|
|
43
|
-
NewRelic::Agent.logger.log_once(
|
|
44
|
-
:warn,
|
|
45
|
-
:deprecated_excon_version,
|
|
46
|
-
deprecation_msg
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
NewRelic::Agent.record_metric('Supportability/Deprecated/Excon', 1)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
36
|
def install_excon_instrumentation(excon_version)
|
|
53
37
|
require 'new_relic/agent/distributed_tracing/cross_app_tracing'
|
|
54
38
|
require 'new_relic/agent/http_clients/excon_wrappers'
|