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
|
@@ -92,16 +92,20 @@ module NewRelic
|
|
|
92
92
|
elsif type == Symbol
|
|
93
93
|
self[config_key] = value.to_sym
|
|
94
94
|
elsif type == Array
|
|
95
|
-
self[config_key] =
|
|
95
|
+
self[config_key] = if DEFAULTS[config_key].key?(:transform)
|
|
96
|
+
DEFAULTS[config_key][:transform].call(value)
|
|
97
|
+
else
|
|
98
|
+
value.split(/\s*,\s*/)
|
|
99
|
+
end
|
|
96
100
|
elsif type == NewRelic::Agent::Configuration::Boolean
|
|
97
101
|
if /false|off|no/i.match?(value)
|
|
98
102
|
self[config_key] = false
|
|
99
103
|
elsif !value.nil?
|
|
100
104
|
self[config_key] = true
|
|
101
105
|
end
|
|
102
|
-
|
|
106
|
+
elsif !serverless?
|
|
103
107
|
::NewRelic::Agent.logger.info("#{environment_key} does not have a corresponding configuration setting (#{config_key} does not exist).")
|
|
104
|
-
::NewRelic::Agent.logger.info('Run `rake newrelic:config:docs` or visit https://newrelic.com/docs/ruby/ruby-agent-configuration to see a list of available configuration settings.')
|
|
108
|
+
::NewRelic::Agent.logger.info('Run `rake newrelic:config:docs` or visit https://docs.newrelic.com/docs/apm/agents/ruby-agent/configuration/ruby-agent-configuration to see a list of available configuration settings.')
|
|
105
109
|
self[config_key] = value
|
|
106
110
|
end
|
|
107
111
|
end
|
|
@@ -114,6 +118,14 @@ module NewRelic
|
|
|
114
118
|
def collect_new_relic_environment_variable_keys
|
|
115
119
|
ENV.keys.select { |key| key.match(SUPPORTED_PREFIXES) }
|
|
116
120
|
end
|
|
121
|
+
|
|
122
|
+
# we can't rely on the :'serverless_mode.enabled' config parameter being
|
|
123
|
+
# set yet to signify serverless mode given that we're in the midst of
|
|
124
|
+
# building the config but we can always rely on the env var being set
|
|
125
|
+
# by the Lambda layer
|
|
126
|
+
def serverless?
|
|
127
|
+
NewRelic::Agent::ServerlessHandler.env_var_set?
|
|
128
|
+
end
|
|
117
129
|
end
|
|
118
130
|
end
|
|
119
131
|
end
|
|
@@ -15,6 +15,8 @@ module NewRelic
|
|
|
15
15
|
module Agent
|
|
16
16
|
module Configuration
|
|
17
17
|
class Manager
|
|
18
|
+
DEPENDENCY_DETECTION_VALUES = %i[prepend chain unsatisfied].freeze
|
|
19
|
+
|
|
18
20
|
# Defining these explicitly saves object allocations that we incur
|
|
19
21
|
# if we use Forwardable and def_delegators.
|
|
20
22
|
def [](key)
|
|
@@ -32,6 +34,7 @@ module NewRelic
|
|
|
32
34
|
def initialize
|
|
33
35
|
reset_to_defaults
|
|
34
36
|
@callbacks = Hash.new { |hash, key| hash[key] = [] }
|
|
37
|
+
@lock = Mutex.new
|
|
35
38
|
end
|
|
36
39
|
|
|
37
40
|
def add_config_for_testing(source, level = 0)
|
|
@@ -135,7 +138,14 @@ module NewRelic
|
|
|
135
138
|
end
|
|
136
139
|
|
|
137
140
|
def evaluate_and_apply_transformations(key, value)
|
|
138
|
-
|
|
141
|
+
evaluated = evaluate_procs(value)
|
|
142
|
+
default = enforce_allowlist(key, evaluated)
|
|
143
|
+
return default if default
|
|
144
|
+
|
|
145
|
+
boolean = enforce_boolean(key, value)
|
|
146
|
+
evaluated = boolean if [true, false].include?(boolean)
|
|
147
|
+
|
|
148
|
+
apply_transformations(key, evaluated)
|
|
139
149
|
end
|
|
140
150
|
|
|
141
151
|
def apply_transformations(key, value)
|
|
@@ -143,7 +153,7 @@ module NewRelic
|
|
|
143
153
|
begin
|
|
144
154
|
transform.call(value)
|
|
145
155
|
rescue => e
|
|
146
|
-
|
|
156
|
+
NewRelic::Agent.logger.error("Error applying transformation for #{key}, pre-transform value was: #{value}.", e)
|
|
147
157
|
raise e
|
|
148
158
|
end
|
|
149
159
|
else
|
|
@@ -151,8 +161,33 @@ module NewRelic
|
|
|
151
161
|
end
|
|
152
162
|
end
|
|
153
163
|
|
|
164
|
+
def enforce_allowlist(key, value)
|
|
165
|
+
return unless allowlist = default_source.allowlist_for(key)
|
|
166
|
+
return if allowlist.include?(value)
|
|
167
|
+
|
|
168
|
+
default = default_source.default_for(key)
|
|
169
|
+
NewRelic::Agent.logger.warn "Invalid value '#{value}' for #{key}, applying default value of '#{default}'"
|
|
170
|
+
default
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def enforce_boolean(key, value)
|
|
174
|
+
type = default_source.value_from_defaults(key, :type)
|
|
175
|
+
return unless type == Boolean
|
|
176
|
+
|
|
177
|
+
bool_value = default_source.boolean_for(key, value)
|
|
178
|
+
return bool_value unless bool_value.nil?
|
|
179
|
+
|
|
180
|
+
default = default_source.default_for(key)
|
|
181
|
+
NewRelic::Agent.logger.warn "Invalid value '#{value}' for #{key}, applying default value of '#{default}'"
|
|
182
|
+
default
|
|
183
|
+
end
|
|
184
|
+
|
|
154
185
|
def transform_from_default(key)
|
|
155
|
-
|
|
186
|
+
default_source.transform_for(key)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def default_source
|
|
190
|
+
NewRelic::Agent::Configuration::DefaultSource
|
|
156
191
|
end
|
|
157
192
|
|
|
158
193
|
def register_callback(key, &proc)
|
|
@@ -211,7 +246,7 @@ module NewRelic
|
|
|
211
246
|
begin
|
|
212
247
|
thawed_layer[k] = instance_eval(&v) if v.respond_to?(:call)
|
|
213
248
|
rescue => e
|
|
214
|
-
|
|
249
|
+
NewRelic::Agent.logger.debug("#{e.class.name} : #{e.message} - when accessing config key #{k}")
|
|
215
250
|
thawed_layer[k] = nil
|
|
216
251
|
end
|
|
217
252
|
thawed_layer.delete(:config)
|
|
@@ -228,7 +263,7 @@ module NewRelic
|
|
|
228
263
|
end
|
|
229
264
|
|
|
230
265
|
def to_collector_hash
|
|
231
|
-
DottedHash.new(apply_mask(flattened)).to_hash.delete_if do |k,
|
|
266
|
+
DottedHash.new(apply_mask(flattened)).to_hash.delete_if do |k, _v|
|
|
232
267
|
default = DEFAULTS[k]
|
|
233
268
|
if default
|
|
234
269
|
default[:exclude_from_reported_settings]
|
|
@@ -347,6 +382,7 @@ module NewRelic
|
|
|
347
382
|
@security_policy_source = nil
|
|
348
383
|
@high_security_source = nil
|
|
349
384
|
@environment_source = EnvironmentSource.new
|
|
385
|
+
log_config(:add, @environment_source) # this is the only place the EnvironmentSource is ever created, so we should log it
|
|
350
386
|
@server_source = nil
|
|
351
387
|
@manual_source = nil
|
|
352
388
|
@yaml_source = nil
|
|
@@ -357,17 +393,42 @@ module NewRelic
|
|
|
357
393
|
reset_cache
|
|
358
394
|
end
|
|
359
395
|
|
|
396
|
+
# reset the configuration hash, but do not replace previously auto
|
|
397
|
+
# determined dependency detection values with nil or 'auto'
|
|
360
398
|
def reset_cache
|
|
399
|
+
return new_cache unless defined?(@cache) && @cache
|
|
400
|
+
|
|
401
|
+
# Modifying the @cache hash under JRuby - even with a `synchronize do`
|
|
402
|
+
# block and a `Hash#dup` operation - has been known to cause issues
|
|
403
|
+
# with JRuby for concurrent access of the hash while it is being
|
|
404
|
+
# modified. The hash really only needs to be modified for the benefit
|
|
405
|
+
# of the security agent, so if JRuby is in play and the security agent
|
|
406
|
+
# is not, don't attempt to modify the hash at all and return early.
|
|
407
|
+
return new_cache if NewRelic::LanguageSupport.jruby? && !Agent.config[:'security.agent.enabled']
|
|
408
|
+
|
|
409
|
+
@lock.synchronize do
|
|
410
|
+
preserved = @cache.dup.select { |_k, v| DEPENDENCY_DETECTION_VALUES.include?(v) }
|
|
411
|
+
new_cache
|
|
412
|
+
preserved.each { |k, v| @cache[k] = v }
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
@cache
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
def new_cache
|
|
361
419
|
@cache = Hash.new { |hash, key| hash[key] = self.fetch(key) }
|
|
362
420
|
end
|
|
363
421
|
|
|
364
422
|
def log_config(direction, source)
|
|
365
|
-
# Just generating this log message (specifically calling
|
|
366
|
-
#
|
|
367
|
-
#
|
|
368
|
-
#
|
|
369
|
-
|
|
370
|
-
|
|
423
|
+
# Just generating this log message (specifically calling `flattened`)
|
|
424
|
+
# is expensive enough that we don't want to do it unless we're
|
|
425
|
+
# actually going to be logging the message based on our current log
|
|
426
|
+
# level, so use a `do` block.
|
|
427
|
+
NewRelic::Agent.logger.debug do
|
|
428
|
+
source_hash = source.dup.to_h.delete_if { |k, _v| DEFAULTS.fetch(k, {}).fetch(:exclude_from_reported_settings, false) }
|
|
429
|
+
final_hash = flattened.delete_if { |k, _h| DEFAULTS.fetch(k, {}).fetch(:exclude_from_reported_settings, false) }
|
|
430
|
+
|
|
431
|
+
"Updating config (#{direction}) from #{source.class} with values: #{source_hash}. \nConfig Stack Results: #{final_hash.inspect}"
|
|
371
432
|
end
|
|
372
433
|
end
|
|
373
434
|
|
|
@@ -7,6 +7,8 @@ require 'new_relic/agent/configuration/dotted_hash'
|
|
|
7
7
|
module NewRelic
|
|
8
8
|
module Agent
|
|
9
9
|
module Configuration
|
|
10
|
+
# The Language Security Policy Source gives customers the ability to
|
|
11
|
+
# configure high security mode settings.
|
|
10
12
|
class SecurityPolicySource < DottedHash
|
|
11
13
|
class << self
|
|
12
14
|
def enabled?(option)
|
|
@@ -147,6 +149,15 @@ module NewRelic
|
|
|
147
149
|
permitted_fn: nil
|
|
148
150
|
}
|
|
149
151
|
],
|
|
152
|
+
'ai_monitoring' => [
|
|
153
|
+
{
|
|
154
|
+
option: :'ai_monitoring.enabled',
|
|
155
|
+
supported: true,
|
|
156
|
+
enabled_fn: method(:enabled?),
|
|
157
|
+
disabled_value: false,
|
|
158
|
+
permitted_fn: nil
|
|
159
|
+
}
|
|
160
|
+
],
|
|
150
161
|
'allow_raw_exception_messages' => [
|
|
151
162
|
{
|
|
152
163
|
option: :'strip_exception_messages.enabled',
|
|
@@ -36,11 +36,13 @@ module NewRelic
|
|
|
36
36
|
erb_file = process_erb(raw_file)
|
|
37
37
|
config = process_yaml(erb_file, env, config, @file_path)
|
|
38
38
|
rescue ScriptError, StandardError => e
|
|
39
|
+
NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::FAILED_TO_PARSE_CONFIG)
|
|
39
40
|
log_failure("Failed to read or parse configuration file at #{path}", e)
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
substitute_transaction_threshold(config)
|
|
43
44
|
booleanify_values(config, 'agent_enabled', 'enabled')
|
|
45
|
+
apply_aliases(config)
|
|
44
46
|
|
|
45
47
|
super(config, true)
|
|
46
48
|
end
|
|
@@ -52,6 +54,8 @@ module NewRelic
|
|
|
52
54
|
protected
|
|
53
55
|
|
|
54
56
|
def validate_config_file_path(path)
|
|
57
|
+
return if NewRelic::Agent.config[:'serverless_mode.enabled']
|
|
58
|
+
|
|
55
59
|
expanded_path = File.expand_path(path)
|
|
56
60
|
|
|
57
61
|
if path.empty? || !File.exist?(expanded_path)
|
|
@@ -63,7 +67,7 @@ module NewRelic
|
|
|
63
67
|
end
|
|
64
68
|
|
|
65
69
|
def warn_missing_config_file(path)
|
|
66
|
-
based_on =
|
|
70
|
+
based_on = NewRelic::UNKNOWN_LOWER
|
|
67
71
|
source = ::NewRelic::Agent.config.source(:config_path)
|
|
68
72
|
candidate_paths = [path]
|
|
69
73
|
|
|
@@ -96,7 +100,11 @@ module NewRelic
|
|
|
96
100
|
file.gsub!(/^\s*#.*$/, '#')
|
|
97
101
|
ERB.new(file).result(binding)
|
|
98
102
|
rescue ScriptError, StandardError => e
|
|
99
|
-
|
|
103
|
+
NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::FAILED_TO_PARSE_CONFIG)
|
|
104
|
+
message = 'Failed ERB processing configuration file. This is typically caused by a Ruby error in <% %> templating blocks in your newrelic.yml file.'
|
|
105
|
+
failure_array = [message, e]
|
|
106
|
+
failure_array << e.backtrace[0] if NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '3.4.0')
|
|
107
|
+
log_failure(*failure_array)
|
|
100
108
|
nil
|
|
101
109
|
end
|
|
102
110
|
end
|
|
@@ -165,6 +173,18 @@ module NewRelic
|
|
|
165
173
|
end
|
|
166
174
|
result
|
|
167
175
|
end
|
|
176
|
+
|
|
177
|
+
def apply_aliases(config)
|
|
178
|
+
DEFAULTS.each do |config_setting, value|
|
|
179
|
+
next unless value[:aliases]
|
|
180
|
+
|
|
181
|
+
value[:aliases].each do |config_alias|
|
|
182
|
+
next unless config[config_setting].nil? && !config[config_alias.to_s].nil?
|
|
183
|
+
|
|
184
|
+
config[config_setting] = config[config_alias.to_s]
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
168
188
|
end
|
|
169
189
|
end
|
|
170
190
|
end
|
|
@@ -24,7 +24,7 @@ module NewRelic
|
|
|
24
24
|
:host => local_host,
|
|
25
25
|
:display_host => Agent.config[:'process_host.display_name'],
|
|
26
26
|
:app_name => Agent.config[:app_name],
|
|
27
|
-
:language =>
|
|
27
|
+
:language => LANGUAGE,
|
|
28
28
|
:labels => Agent.config.parsed_labels,
|
|
29
29
|
:agent_version => NewRelic::VERSION::STRING,
|
|
30
30
|
:environment => @environment_report,
|
|
@@ -14,6 +14,9 @@ module NewRelic
|
|
|
14
14
|
TIMESTAMP = 'timestamp'.freeze
|
|
15
15
|
PRIORITY = 'priority'.freeze
|
|
16
16
|
EVENT_TYPE_REGEX = /^[a-zA-Z0-9:_ ]+$/.freeze
|
|
17
|
+
MAX_ATTRIBUTE_COUNT = 64
|
|
18
|
+
MAX_ATTRIBUTE_SIZE = 4095
|
|
19
|
+
MAX_NAME_SIZE = 255
|
|
17
20
|
|
|
18
21
|
named :CustomEventAggregator
|
|
19
22
|
capacity_key :'custom_insights_events.max_samples_stored'
|
|
@@ -49,10 +52,33 @@ module NewRelic
|
|
|
49
52
|
{TYPE => type,
|
|
50
53
|
TIMESTAMP => Process.clock_gettime(Process::CLOCK_REALTIME).to_i,
|
|
51
54
|
PRIORITY => priority},
|
|
52
|
-
|
|
55
|
+
create_custom_event_attributes(type, attributes)
|
|
53
56
|
]
|
|
54
57
|
end
|
|
55
58
|
|
|
59
|
+
def create_custom_event_attributes(type, attributes)
|
|
60
|
+
result = AttributeProcessing.flatten_and_coerce(attributes)
|
|
61
|
+
|
|
62
|
+
if result.size > MAX_ATTRIBUTE_COUNT
|
|
63
|
+
NewRelic::Agent.logger.warn("Custom event attributes are limited to #{MAX_ATTRIBUTE_COUNT}. Discarding #{result.size - MAX_ATTRIBUTE_COUNT} attributes")
|
|
64
|
+
result = result.first(MAX_ATTRIBUTE_COUNT)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
result.each_with_object({}) do |(key, val), new_result|
|
|
68
|
+
# name is limited to 255
|
|
69
|
+
if key.is_a?(String) && key.length > MAX_NAME_SIZE
|
|
70
|
+
key = key[0, MAX_NAME_SIZE]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# value is limited to 4095 except for LLM content-related events
|
|
74
|
+
if val.is_a?(String) && val.length > MAX_ATTRIBUTE_SIZE
|
|
75
|
+
val = val[0, MAX_ATTRIBUTE_SIZE] unless NewRelic::Agent::LLM.exempt_event_attribute?(type, key)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
new_result[key] = val
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
56
82
|
def after_initialize
|
|
57
83
|
@type_strings = Hash.new { |hash, key| hash[key] = key.to_s.freeze }
|
|
58
84
|
end
|
|
@@ -7,17 +7,17 @@ module NewRelic
|
|
|
7
7
|
module Database
|
|
8
8
|
module ObfuscationHelpers
|
|
9
9
|
COMPONENTS_REGEX_MAP = {
|
|
10
|
-
:
|
|
11
|
-
:
|
|
12
|
-
:
|
|
13
|
-
:
|
|
14
|
-
:
|
|
15
|
-
:
|
|
16
|
-
:
|
|
17
|
-
:
|
|
18
|
-
:
|
|
19
|
-
:
|
|
20
|
-
}
|
|
10
|
+
single_quotes: /'(?:[^']|'')*?(?:\\'.*|'(?!'))/,
|
|
11
|
+
double_quotes: /"(?:[^"]|"")*?(?:\\".*|"(?!"))/,
|
|
12
|
+
dollar_quotes: /(\$(?!\d)[^$]*?\$).*?(?:\1|$)/,
|
|
13
|
+
uuids: /\{?(?:[0-9a-fA-F]-*){32}\}?/,
|
|
14
|
+
numeric_literals: /-?\b(?:[0-9]+\.)?[0-9]+([eE][+-]?[0-9]+)?\b/,
|
|
15
|
+
boolean_literals: /\b(?:true|false|null)\b/i,
|
|
16
|
+
hexadecimal_literals: /0x[0-9a-fA-F]+/,
|
|
17
|
+
comments: /(?:#|--).*?(?=\r|\n|$)/i,
|
|
18
|
+
multi_line_comments: %r{/\*.*?\*/}m,
|
|
19
|
+
oracle_quoted_strings: /q'\[.*?(?:\]'|$)|q'\{.*?(?:\}'|$)|q'<.*?(?:>'|$)|q'\(.*?(?:\)'|$)/
|
|
20
|
+
}.freeze
|
|
21
21
|
|
|
22
22
|
DIALECT_COMPONENTS = {
|
|
23
23
|
:fallback => COMPONENTS_REGEX_MAP.keys,
|
|
@@ -90,6 +90,42 @@ module NewRelic
|
|
|
90
90
|
ConnectionManager.instance.get_connection(config, &connector)
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
+
def explain_this(statement, use_execute = false)
|
|
94
|
+
if supports_with_connection?
|
|
95
|
+
explain_this_using_with_connection(statement)
|
|
96
|
+
else
|
|
97
|
+
explain_this_using_adapter_connection(statement, use_execute)
|
|
98
|
+
end
|
|
99
|
+
rescue => e
|
|
100
|
+
NewRelic::Agent.logger.error("Couldn't fetch the explain plan for statement: #{e}")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def explain_this_using_with_connection(statement)
|
|
104
|
+
::ActiveRecord::Base.with_connection do |conn|
|
|
105
|
+
conn.exec_query("EXPLAIN #{statement.sql}", "Explain #{statement.name}", statement.binds)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def explain_this_using_adapter_connection(statement, use_execute)
|
|
110
|
+
connection = get_connection(statement.config) do
|
|
111
|
+
::ActiveRecord::Base.send(:"#{statement.config[:adapter]}_connection", statement.config)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
if use_execute
|
|
115
|
+
connection.execute("EXPLAIN #{statement.sql}")
|
|
116
|
+
else
|
|
117
|
+
connection.exec_query("EXPLAIN #{statement.sql}", "Explain #{statement.name}", statement.binds)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# ActiveRecord v7.2.0 introduced with_connection
|
|
122
|
+
def supports_with_connection?
|
|
123
|
+
return @supports_with_connection if defined?(@supports_with_connection)
|
|
124
|
+
|
|
125
|
+
@supports_with_connection = defined?(::ActiveRecord::VERSION::STRING) &&
|
|
126
|
+
NewRelic::Helper.version_satisfied?(ActiveRecord::VERSION::STRING, '>=', '7.2.0')
|
|
127
|
+
end
|
|
128
|
+
|
|
93
129
|
def close_connections
|
|
94
130
|
ConnectionManager.instance.close_connections
|
|
95
131
|
end
|
|
@@ -241,9 +277,11 @@ module NewRelic
|
|
|
241
277
|
MYSQL_PREFIX = 'mysql'.freeze
|
|
242
278
|
MYSQL2_PREFIX = 'mysql2'.freeze
|
|
243
279
|
SQLITE_PREFIX = 'sqlite'.freeze
|
|
280
|
+
TRILOGY_PREFIX = 'trilogy'.freeze
|
|
281
|
+
REDSHIFT_PREFIX = 'redshift'.freeze
|
|
244
282
|
|
|
245
283
|
def symbolized_adapter(adapter)
|
|
246
|
-
if adapter.start_with?(POSTGRES_PREFIX) || adapter == POSTGIS_PREFIX
|
|
284
|
+
if adapter.start_with?(POSTGRES_PREFIX) || adapter == POSTGIS_PREFIX || adapter == REDSHIFT_PREFIX
|
|
247
285
|
:postgres
|
|
248
286
|
elsif adapter == MYSQL_PREFIX
|
|
249
287
|
:mysql
|
|
@@ -253,6 +291,8 @@ module NewRelic
|
|
|
253
291
|
:mysql2
|
|
254
292
|
elsif adapter.start_with?(SQLITE_PREFIX)
|
|
255
293
|
:sqlite
|
|
294
|
+
elsif adapter == TRILOGY_PREFIX
|
|
295
|
+
:trilogy
|
|
256
296
|
else
|
|
257
297
|
adapter.to_sym
|
|
258
298
|
end
|
|
@@ -25,7 +25,7 @@ module NewRelic
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def value
|
|
28
|
-
match = VERSIONS.keys.find { |key| version >=
|
|
28
|
+
match = VERSIONS.keys.find { |key| NewRelic::Helper.version_satisfied?(version, '>=', key) }
|
|
29
29
|
return unless match
|
|
30
30
|
|
|
31
31
|
VERSIONS[match].call(env)
|
|
@@ -128,7 +128,7 @@ module NewRelic
|
|
|
128
128
|
end
|
|
129
129
|
|
|
130
130
|
def self.drop_indexes?(name, payload)
|
|
131
|
-
name == :deleteIndexes && payload[:selector] && payload[:selector][:index] ==
|
|
131
|
+
name == :deleteIndexes && payload[:selector] && payload[:selector][:index] == ASTERISK
|
|
132
132
|
end
|
|
133
133
|
|
|
134
134
|
def self.drop_index?(name, payload)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# frozen_string_literal: true
|
|
4
4
|
|
|
5
5
|
require 'json'
|
|
6
|
-
require 'base64'
|
|
6
|
+
require 'new_relic/base64'
|
|
7
7
|
|
|
8
8
|
module NewRelic
|
|
9
9
|
module Agent
|
|
@@ -35,7 +35,7 @@ module NewRelic
|
|
|
35
35
|
|
|
36
36
|
class << self
|
|
37
37
|
def for_transaction(transaction)
|
|
38
|
-
return nil unless connected?
|
|
38
|
+
return nil unless Agent.instance.connected?
|
|
39
39
|
|
|
40
40
|
payload = new
|
|
41
41
|
payload.version = VERSION
|
|
@@ -78,7 +78,7 @@ module NewRelic
|
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
def from_http_safe(http_safe_payload)
|
|
81
|
-
decoded_payload = Base64.strict_decode64(http_safe_payload)
|
|
81
|
+
decoded_payload = NewRelic::Base64.strict_decode64(http_safe_payload)
|
|
82
82
|
from_json(decoded_payload)
|
|
83
83
|
end
|
|
84
84
|
|
|
@@ -101,10 +101,6 @@ module NewRelic
|
|
|
101
101
|
transaction.current_segment.guid
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
|
-
|
|
105
|
-
def connected?
|
|
106
|
-
Agent.instance.connected?
|
|
107
|
-
end
|
|
108
104
|
end
|
|
109
105
|
|
|
110
106
|
attr_accessor :version,
|
|
@@ -156,7 +152,7 @@ module NewRelic
|
|
|
156
152
|
#
|
|
157
153
|
# @api public
|
|
158
154
|
def http_safe
|
|
159
|
-
Base64.strict_encode64(text)
|
|
155
|
+
NewRelic::Base64.strict_encode64(text)
|
|
160
156
|
end
|
|
161
157
|
end
|
|
162
158
|
end
|
|
@@ -39,13 +39,14 @@ module NewRelic
|
|
|
39
39
|
# @return {Transaction} The transaction the headers were inserted from,
|
|
40
40
|
# or +nil+ if headers were not inserted.
|
|
41
41
|
#
|
|
42
|
+
# @!scope class
|
|
42
43
|
# @api public
|
|
43
44
|
#
|
|
44
45
|
def insert_distributed_trace_headers(headers = {})
|
|
45
46
|
record_api_supportability_metric(:insert_distributed_trace_headers)
|
|
46
47
|
|
|
47
48
|
unless Agent.config[:'distributed_tracing.enabled']
|
|
48
|
-
NewRelic::Agent.logger.
|
|
49
|
+
NewRelic::Agent.logger.debug('Not configured to insert distributed trace headers')
|
|
49
50
|
return nil
|
|
50
51
|
end
|
|
51
52
|
|
|
@@ -87,19 +88,20 @@ module NewRelic
|
|
|
87
88
|
# header-friendly string returned from
|
|
88
89
|
# {DistributedTracePayload#http_safe}
|
|
89
90
|
#
|
|
90
|
-
# @param
|
|
91
|
+
# @param transport_type [String] May be one of: +HTTP+, +HTTPS+, +Kafka+, +JMS+,
|
|
91
92
|
# +IronMQ+, +AMQP+, +Queue+, +Other+. Values are
|
|
92
93
|
# case sensitive. All other values result in +Unknown+
|
|
93
94
|
#
|
|
94
95
|
# @return {Transaction} if successful, +nil+ otherwise
|
|
95
96
|
#
|
|
97
|
+
# @!scope class
|
|
96
98
|
# @api public
|
|
97
99
|
#
|
|
98
100
|
def accept_distributed_trace_headers(headers, transport_type = NewRelic::HTTP)
|
|
99
101
|
record_api_supportability_metric(:accept_distributed_trace_headers)
|
|
100
102
|
|
|
101
103
|
unless Agent.config[:'distributed_tracing.enabled']
|
|
102
|
-
NewRelic::Agent.logger.
|
|
104
|
+
NewRelic::Agent.logger.debug('Not configured to accept distributed trace headers')
|
|
103
105
|
return nil
|
|
104
106
|
end
|
|
105
107
|
|
|
@@ -110,6 +110,29 @@ module NewRelic
|
|
|
110
110
|
false
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
+
# Neither ignored nor expected errors impact apdex.
|
|
114
|
+
#
|
|
115
|
+
# Ignored errors are checked via `#error_is_ignored?`
|
|
116
|
+
# Expected errors are checked in 2 separate ways:
|
|
117
|
+
# 1. The presence of an `expected: true` attribute key/value pair in the
|
|
118
|
+
# options hash, which will be set if that key/value pair was used in
|
|
119
|
+
# the `notice_error` public API.
|
|
120
|
+
# 2. By calling `#expected?` which in turn calls `ErrorFilter#expected?`
|
|
121
|
+
# which checks for 3 things:
|
|
122
|
+
# - A match for user-defined HTTP status codes to expect
|
|
123
|
+
# - A match for user-defined error classes to expect
|
|
124
|
+
# - A match for user-defined error messages to expect
|
|
125
|
+
def error_affects_apdex?(error, options)
|
|
126
|
+
return false if error_is_ignored?(error)
|
|
127
|
+
return false if options[:expected]
|
|
128
|
+
|
|
129
|
+
!expected?(error, ::NewRelic::Agent::Tracer.state.current_transaction&.http_response_code)
|
|
130
|
+
rescue => e
|
|
131
|
+
NewRelic::Agent.logger.error("Could not determine if error '#{error}' should impact Apdex - " \
|
|
132
|
+
"#{e.class}: #{e.message}. Defaulting to 'true' (it should impact Apdex).")
|
|
133
|
+
true
|
|
134
|
+
end
|
|
135
|
+
|
|
113
136
|
# Calling instance_variable_set on a wrapped Java object in JRuby will
|
|
114
137
|
# generate a warning unless that object's class has already been marked
|
|
115
138
|
# as persistent, so we skip tagging of exception objects that are actually
|
|
@@ -214,7 +237,10 @@ module NewRelic
|
|
|
214
237
|
end
|
|
215
238
|
|
|
216
239
|
def notice_segment_error(segment, exception, options = {})
|
|
217
|
-
|
|
240
|
+
status_code = process_http_status_code(exception, options)
|
|
241
|
+
return if skip_notice_error?(exception, status_code)
|
|
242
|
+
|
|
243
|
+
options.merge!(segment.llm_event.error_attributes(exception)) if segment.llm_event
|
|
218
244
|
|
|
219
245
|
segment.set_noticed_error(create_noticed_error(exception, options))
|
|
220
246
|
exception
|
|
@@ -225,15 +251,13 @@ module NewRelic
|
|
|
225
251
|
|
|
226
252
|
# See NewRelic::Agent.notice_error for options and commentary
|
|
227
253
|
def notice_error(exception, options = {}, span_id = nil)
|
|
228
|
-
|
|
229
|
-
transaction = state.current_transaction
|
|
230
|
-
status_code = transaction&.http_response_code
|
|
231
|
-
|
|
254
|
+
status_code = process_http_status_code(exception, options)
|
|
232
255
|
return if skip_notice_error?(exception, status_code)
|
|
233
256
|
|
|
234
257
|
tag_exception(exception)
|
|
235
258
|
|
|
236
|
-
|
|
259
|
+
state = ::NewRelic::Agent::Tracer.state
|
|
260
|
+
if options[:expected]
|
|
237
261
|
increment_expected_error_count!(state, exception)
|
|
238
262
|
else
|
|
239
263
|
increment_error_count!(state, exception, options)
|
|
@@ -241,10 +265,8 @@ module NewRelic
|
|
|
241
265
|
|
|
242
266
|
noticed_error = create_noticed_error(exception, options)
|
|
243
267
|
error_trace_aggregator.add_to_error_queue(noticed_error)
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
span_id ||= transaction&.current_segment ? transaction.current_segment.guid : nil
|
|
247
|
-
error_event_aggregator.record(noticed_error, payload, span_id)
|
|
268
|
+
span_id ||= state.current_transaction&.current_segment&.guid
|
|
269
|
+
error_event_aggregator.record(noticed_error, state.current_transaction&.payload, span_id)
|
|
248
270
|
exception
|
|
249
271
|
rescue => e
|
|
250
272
|
::NewRelic::Agent.logger.warn("Failure when capturing error '#{exception}':", e)
|
|
@@ -277,7 +299,7 @@ module NewRelic
|
|
|
277
299
|
noticed_error.line_number = sense_method(exception, :line_number)
|
|
278
300
|
noticed_error.stack_trace = truncate_trace(extract_stack_trace(exception))
|
|
279
301
|
|
|
280
|
-
noticed_error.expected =
|
|
302
|
+
noticed_error.expected = !!options.delete(:expected) || expected?(exception) # rubocop:disable Style/DoubleNegation
|
|
281
303
|
|
|
282
304
|
noticed_error.attributes_from_notice_error = options.delete(:custom_params) || {}
|
|
283
305
|
|
|
@@ -334,6 +356,13 @@ module NewRelic
|
|
|
334
356
|
def error_group_callback
|
|
335
357
|
NewRelic::Agent.error_group_callback
|
|
336
358
|
end
|
|
359
|
+
|
|
360
|
+
def process_http_status_code(exception, options)
|
|
361
|
+
status_code = ::NewRelic::Agent::Tracer.state.current_transaction&.http_response_code
|
|
362
|
+
options[:expected] = true if !options[:expected] && @error_filter.expected?(exception, status_code)
|
|
363
|
+
|
|
364
|
+
status_code
|
|
365
|
+
end
|
|
337
366
|
end
|
|
338
367
|
end
|
|
339
368
|
end
|