newrelic_rpm 9.9.0 → 9.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.build_ignore +1 -0
- data/CHANGELOG.md +463 -1
- data/CONTRIBUTING.md +2 -2
- data/README.md +16 -17
- data/Rakefile +1 -1
- data/lib/boot/strap.rb +102 -0
- data/lib/new_relic/agent/agent.rb +6 -0
- data/lib/new_relic/agent/agent_helpers/connect.rb +3 -0
- data/lib/new_relic/agent/agent_helpers/harvest.rb +3 -0
- data/lib/new_relic/agent/agent_helpers/shutdown.rb +3 -0
- data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +1 -0
- data/lib/new_relic/agent/agent_helpers/startup.rb +7 -0
- data/lib/new_relic/agent/agent_logger.rb +1 -0
- data/lib/new_relic/agent/aws.rb +68 -0
- data/lib/new_relic/agent/configuration/default_source.rb +603 -105
- data/lib/new_relic/agent/configuration/environment_source.rb +5 -1
- data/lib/new_relic/agent/configuration/manager.rb +28 -2
- data/lib/new_relic/agent/configuration/yaml_source.rb +7 -2
- data/lib/new_relic/agent/database/obfuscation_helpers.rb +11 -11
- data/lib/new_relic/agent/database/obfuscator.rb +1 -0
- data/lib/new_relic/agent/database.rb +41 -1
- data/lib/new_relic/agent/database_adapter.rb +1 -1
- data/lib/new_relic/agent/datastores/redis.rb +1 -1
- data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +1 -1
- data/lib/new_relic/agent/distributed_tracing.rb +4 -2
- data/lib/new_relic/agent/error_collector.rb +37 -10
- data/lib/new_relic/agent/external.rb +2 -0
- data/lib/new_relic/agent/health_check.rb +136 -0
- data/lib/new_relic/agent/http_clients/uri_util.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_dispatch.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_mailbox.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_mailer.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_job.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +6 -2
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +0 -13
- data/lib/new_relic/agent/instrumentation/active_record.rb +7 -12
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +7 -3
- data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +11 -9
- data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +2 -2
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +9 -16
- data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger.rb +0 -2
- data/lib/new_relic/agent/instrumentation/active_support_logger.rb +0 -2
- data/lib/new_relic/agent/instrumentation/async_http.rb +2 -3
- data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/instrumentation.rb +66 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/prepend.rb +15 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_firehose.rb +22 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/instrumentation.rb +91 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/prepend.rb +15 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis.rb +22 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/chain.rb +33 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/instrumentation.rb +93 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/prepend.rb +23 -0
- data/lib/new_relic/agent/instrumentation/aws_sdk_lambda.rb +23 -0
- data/lib/new_relic/agent/instrumentation/aws_sqs/chain.rb +37 -0
- data/lib/new_relic/agent/instrumentation/aws_sqs/instrumentation.rb +67 -0
- data/lib/new_relic/agent/instrumentation/aws_sqs/prepend.rb +21 -0
- data/lib/new_relic/agent/instrumentation/aws_sqs.rb +23 -0
- data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +14 -0
- data/lib/new_relic/agent/instrumentation/bunny.rb +3 -4
- data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +1 -3
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/curb.rb +4 -5
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +0 -23
- data/lib/new_relic/agent/instrumentation/dynamodb/chain.rb +27 -0
- data/lib/new_relic/agent/instrumentation/dynamodb/instrumentation.rb +64 -0
- data/lib/new_relic/agent/instrumentation/dynamodb/prepend.rb +19 -0
- data/lib/new_relic/agent/instrumentation/dynamodb.rb +23 -0
- data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +1 -2
- data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +53 -7
- data/lib/new_relic/agent/instrumentation/elasticsearch.rb +1 -3
- data/lib/new_relic/agent/instrumentation/ethon.rb +1 -5
- data/lib/new_relic/agent/instrumentation/excon.rb +1 -17
- data/lib/new_relic/agent/instrumentation/fiber/chain.rb +1 -1
- data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +1 -1
- data/lib/new_relic/agent/instrumentation/fiber.rb +0 -2
- data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +0 -3
- data/lib/new_relic/agent/instrumentation/grape.rb +1 -1
- data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +0 -1
- data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -5
- data/lib/new_relic/agent/instrumentation/httprb.rb +0 -1
- data/lib/new_relic/agent/instrumentation/httpx/instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/httpx.rb +1 -5
- data/lib/new_relic/agent/instrumentation/logger.rb +1 -3
- data/lib/new_relic/agent/instrumentation/logstasher/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/logstasher/instrumentation.rb +24 -0
- data/lib/new_relic/agent/instrumentation/logstasher/prepend.rb +13 -0
- data/lib/new_relic/agent/instrumentation/logstasher.rb +25 -0
- data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache/helper.rb +2 -2
- data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache.rb +0 -1
- data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +3 -3
- data/lib/new_relic/agent/instrumentation/net_http.rb +2 -1
- data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +0 -2
- data/lib/new_relic/agent/instrumentation/opensearch/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/opensearch/instrumentation.rb +66 -0
- data/lib/{tasks/instrumentation_generator/templates/instrumentation.tt → new_relic/agent/instrumentation/opensearch/prepend.rb} +4 -4
- data/lib/new_relic/agent/instrumentation/opensearch.rb +23 -0
- data/lib/new_relic/agent/instrumentation/padrino.rb +3 -3
- data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +3 -0
- data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +9 -5
- data/lib/new_relic/agent/instrumentation/rake.rb +1 -2
- data/lib/new_relic/agent/instrumentation/rdkafka/chain.rb +72 -0
- data/lib/new_relic/agent/instrumentation/rdkafka/instrumentation.rb +70 -0
- data/lib/new_relic/agent/instrumentation/rdkafka/prepend.rb +67 -0
- data/lib/new_relic/agent/instrumentation/rdkafka.rb +25 -0
- data/lib/new_relic/agent/instrumentation/redis/cluster_middleware.rb +26 -0
- data/lib/new_relic/agent/instrumentation/redis/constants.rb +2 -2
- data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +14 -11
- data/lib/new_relic/agent/instrumentation/redis/middleware.rb +3 -0
- data/lib/new_relic/agent/instrumentation/redis.rb +11 -5
- data/lib/new_relic/agent/instrumentation/resque.rb +8 -6
- data/lib/new_relic/agent/instrumentation/roda.rb +5 -5
- data/lib/new_relic/agent/instrumentation/ruby_kafka/chain.rb +55 -0
- data/lib/new_relic/agent/instrumentation/ruby_kafka/instrumentation.rb +67 -0
- data/lib/new_relic/agent/instrumentation/ruby_kafka/prepend.rb +60 -0
- data/lib/new_relic/agent/instrumentation/ruby_kafka.rb +25 -0
- data/lib/new_relic/agent/instrumentation/ruby_openai.rb +2 -2
- data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delay_extensions.rb +24 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +2 -2
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +9 -15
- data/lib/new_relic/agent/instrumentation/sinatra.rb +3 -19
- data/lib/new_relic/agent/instrumentation/stripe.rb +1 -1
- data/lib/new_relic/agent/instrumentation/stripe_subscriber.rb +22 -1
- data/lib/new_relic/agent/instrumentation/thread.rb +0 -2
- data/lib/new_relic/agent/instrumentation/tilt.rb +0 -4
- data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +2 -2
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +0 -1
- data/lib/new_relic/agent/instrumentation/view_component/instrumentation.rb +11 -5
- data/lib/new_relic/agent/instrumentation/view_component.rb +0 -2
- data/lib/new_relic/agent/javascript_instrumentor.rb +2 -3
- data/lib/new_relic/agent/llm/chat_completion_summary.rb +1 -1
- data/lib/new_relic/agent/llm/embedding.rb +1 -1
- data/lib/new_relic/agent/local_log_decorator.rb +20 -3
- data/lib/new_relic/agent/log_event_aggregator.rb +119 -28
- data/lib/new_relic/agent/logging.rb +1 -1
- data/lib/new_relic/agent/messaging.rb +16 -5
- data/lib/new_relic/agent/method_tracer.rb +3 -0
- data/lib/new_relic/agent/monitors/inbound_request_monitor.rb +1 -1
- data/lib/new_relic/agent/monitors/synthetics_monitor.rb +1 -1
- data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +2 -2
- data/lib/new_relic/agent/new_relic_service.rb +8 -2
- data/lib/new_relic/agent/opentelemetry/context/propagation/trace_propagator.rb +66 -0
- data/lib/new_relic/agent/opentelemetry/context/propagation.rb +15 -0
- data/lib/{tasks/instrumentation_generator/templates/Envfile.tt → new_relic/agent/opentelemetry/context.rb} +9 -5
- data/lib/new_relic/agent/opentelemetry/trace/span.rb +31 -0
- data/lib/new_relic/agent/opentelemetry/trace/tracer.rb +129 -0
- data/lib/new_relic/agent/opentelemetry/trace/tracer_provider.rb +18 -0
- data/lib/new_relic/agent/opentelemetry/trace.rb +15 -0
- data/lib/new_relic/agent/opentelemetry/transaction_patch.rb +69 -0
- data/lib/new_relic/agent/opentelemetry_bridge.rb +32 -0
- data/lib/new_relic/agent/parameter_filtering.rb +1 -1
- data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -1
- data/lib/new_relic/agent/samplers/memory_sampler.rb +1 -1
- data/lib/new_relic/agent/serverless_handler.rb +247 -12
- data/lib/new_relic/agent/serverless_handler_event_sources.json +155 -0
- data/lib/new_relic/agent/serverless_handler_event_sources.rb +49 -0
- data/lib/new_relic/agent/span_event_primitive.rb +16 -11
- data/lib/new_relic/agent/system_info.rb +14 -0
- data/lib/new_relic/agent/threading/backtrace_node.rb +10 -1
- data/lib/new_relic/agent/tracer.rb +1 -1
- data/lib/new_relic/agent/transaction/abstract_segment.rb +2 -1
- data/lib/new_relic/agent/transaction/datastore_segment.rb +1 -1
- data/lib/new_relic/agent/transaction/distributed_tracer.rb +3 -3
- data/lib/new_relic/agent/transaction/external_request_segment.rb +0 -10
- data/lib/new_relic/agent/transaction/message_broker_segment.rb +4 -1
- data/lib/new_relic/agent/transaction/request_attributes.rb +14 -7
- data/lib/new_relic/agent/transaction/trace_context.rb +34 -5
- data/lib/new_relic/agent/transaction/tracing.rb +3 -3
- data/lib/new_relic/agent/transaction.rb +4 -7
- data/lib/new_relic/agent/transaction_time_aggregator.rb +1 -1
- data/lib/new_relic/agent/utilization/ecs.rb +22 -0
- data/lib/new_relic/agent/utilization/ecs_v4.rb +22 -0
- data/lib/new_relic/agent/utilization_data.rb +40 -5
- data/lib/new_relic/agent/vm/c_ruby_vm.rb +3 -3
- data/lib/new_relic/agent.rb +124 -2
- data/lib/new_relic/constants.rb +1 -0
- data/lib/new_relic/control/frameworks/grape.rb +14 -0
- data/lib/new_relic/control/frameworks/padrino.rb +14 -0
- data/lib/new_relic/control/frameworks/rails4.rb +1 -3
- data/lib/new_relic/control/instance_methods.rb +6 -0
- data/lib/new_relic/control/instrumentation.rb +1 -1
- data/lib/new_relic/control/private_instance_methods.rb +4 -0
- data/lib/new_relic/control/security_interface.rb +57 -0
- data/lib/new_relic/control.rb +1 -1
- data/lib/new_relic/dependency_detection.rb +11 -14
- data/lib/new_relic/environment_report.rb +2 -2
- data/lib/new_relic/helper.rb +22 -0
- data/lib/new_relic/language_support.rb +3 -1
- data/lib/new_relic/local_environment.rb +1 -4
- data/lib/new_relic/rack/browser_monitoring.rb +20 -8
- data/lib/new_relic/version.rb +1 -1
- data/lib/sequel/extensions/new_relic_instrumentation.rb +3 -2
- data/lib/tasks/config.rake +7 -3
- data/lib/tasks/gha.rake +31 -0
- data/lib/tasks/helpers/config.html.erb +3 -2
- data/lib/tasks/helpers/format.rb +1 -1
- data/lib/tasks/helpers/newrelicyml.rb +80 -13
- data/newrelic.yml +425 -162
- data/newrelic_rpm.gemspec +3 -1
- data/test/agent_helper.rb +24 -2
- metadata +91 -22
- data/lib/tasks/instrumentation_generator/README.md +0 -63
- data/lib/tasks/instrumentation_generator/TODO.md +0 -33
- data/lib/tasks/instrumentation_generator/instrumentation.thor +0 -121
- data/lib/tasks/instrumentation_generator/templates/chain.tt +0 -21
- data/lib/tasks/instrumentation_generator/templates/chain_method.tt +0 -7
- data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +0 -29
- data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +0 -3
- data/lib/tasks/instrumentation_generator/templates/newrelic.yml.tt +0 -19
- data/lib/tasks/instrumentation_generator/templates/prepend.tt +0 -13
- data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +0 -3
- data/lib/tasks/instrumentation_generator/templates/test.tt +0 -15
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
<a href="https://opensource.newrelic.com/oss-category/#community-plus"><picture><source media="(prefers-color-scheme: dark)" srcset="https://github.com/newrelic/opensource-website/raw/main/src/images/categories/dark/Community_Plus.png"><source media="(prefers-color-scheme: light)" srcset="https://github.com/newrelic/opensource-website/raw/main/src/images/categories/Community_Plus.png"><img alt="New Relic Open Source community plus project banner." src="https://github.com/newrelic/opensource-website/raw/main/src/images/categories/Community_Plus.png"></picture></a>
|
2
2
|
|
3
|
-
# New Relic Ruby
|
3
|
+
# New Relic Ruby agent
|
4
4
|
|
5
5
|
The New Relic Ruby agent monitors your applications to help you
|
6
6
|
[identify and solve performance issues](https://docs.newrelic.com/docs/agents/ruby-agent/getting-started/introduction-new-relic-ruby#monitor-performance).
|
@@ -15,7 +15,7 @@ This code is actively maintained by New Relic engineering teams and delivered he
|
|
15
15
|
|
16
16
|
[](https://badge.fury.io/rb/newrelic_rpm)
|
17
17
|
|
18
|
-
## Supported
|
18
|
+
## Supported environments
|
19
19
|
|
20
20
|
An up-to-date list of Ruby versions and frameworks for the latest agent
|
21
21
|
can be found on [our docs site](http://docs.newrelic.com/docs/ruby/supported-frameworks).
|
@@ -23,11 +23,11 @@ can be found on [our docs site](http://docs.newrelic.com/docs/ruby/supported-fra
|
|
23
23
|
You can also monitor non-web applications. Refer to the "Other
|
24
24
|
Environments" section below.
|
25
25
|
|
26
|
-
## Installing and
|
26
|
+
## Installing and using
|
27
27
|
|
28
28
|
The latest released gem for the Ruby agent can be found at [RubyGems.org](https://rubygems.org/gems/newrelic_rpm)
|
29
29
|
|
30
|
-
### Quick
|
30
|
+
### Quick start
|
31
31
|
|
32
32
|
#### With Bundler
|
33
33
|
|
@@ -53,7 +53,7 @@ and then require the New Relic Ruby agent in your Ruby start-up sequence:
|
|
53
53
|
require 'newrelic_rpm'
|
54
54
|
```
|
55
55
|
|
56
|
-
#### Other
|
56
|
+
#### Other environments
|
57
57
|
|
58
58
|
Assuming you have installed the agent per above, you may also need to tell the Ruby agent to start for some frameworks and non-framework environments. To do so, add the following to your Ruby start-up sequence start the agent:
|
59
59
|
|
@@ -61,29 +61,29 @@ Assuming you have installed the agent per above, you may also need to tell the R
|
|
61
61
|
NewRelic::Agent.manual_start
|
62
62
|
```
|
63
63
|
|
64
|
-
### Complete
|
64
|
+
### Complete install instructions
|
65
65
|
|
66
66
|
For complete documentation on installing the New Relic Ruby agent, see the following links:
|
67
67
|
|
68
68
|
* [Introduction](https://docs.newrelic.com/docs/agents/ruby-agent/getting-started/introduction-new-relic-ruby)
|
69
|
-
* [Install the New Relic Ruby agent](https://docs.newrelic.com/docs/agents/ruby-agent/installation/install-new-relic-ruby-agent)
|
69
|
+
* [Install the New Relic Ruby agent](https://docs.newrelic.com/docs/agents/ruby-agent/installation/install-new-relic-ruby-agent). See also these docs that cover specific install scenarios:
|
70
|
+
* [Rails plugin installation](https://docs.newrelic.com/docs/agents/ruby-agent/installation/ruby-agent-installation-rails-plugin)
|
71
|
+
* [AWS Lambda](https://docs.newrelic.com/docs/serverless-function-monitoring/aws-lambda-monitoring/instrument-lambda-function/instrument-your-own/)
|
72
|
+
* [GAE Flexible Environment](https://docs.newrelic.com/docs/agents/ruby-agent/installation/install-new-relic-ruby-agent-gae-flexible-environment)
|
73
|
+
* [Pure Rack apps](http://docs.newrelic.com/docs/ruby/rack-middlewares)
|
74
|
+
* [Ruby agent and Heroku](https://docs.newrelic.com/docs/agents/ruby-agent/installation/ruby-agent-heroku)
|
75
|
+
* [Background jobs](https://docs.newrelic.com/docs/agents/ruby-agent/background-jobs/monitor-ruby-background-processes)
|
70
76
|
* [Configure the agent](https://docs.newrelic.com/docs/agents/ruby-agent/configuration/ruby-agent-configuration)
|
71
77
|
* [Update the agent](https://docs.newrelic.com/docs/agents/ruby-agent/installation/update-ruby-agent)
|
72
|
-
* [Rails plugin installation](https://docs.newrelic.com/docs/agents/ruby-agent/installation/ruby-agent-installation-rails-plugin)
|
73
|
-
* [GAE Flexible Environment](https://docs.newrelic.com/docs/agents/ruby-agent/installation/install-new-relic-ruby-agent-gae-flexible-environment)
|
74
|
-
* [Pure Rack Apps](http://docs.newrelic.com/docs/ruby/rack-middlewares)
|
75
|
-
* [Ruby agent and Heroku](https://docs.newrelic.com/docs/agents/ruby-agent/installation/ruby-agent-heroku)
|
76
|
-
* [Background Jobs](https://docs.newrelic.com/docs/agents/ruby-agent/background-jobs/monitor-ruby-background-processes)
|
77
78
|
* [Uninstall the Ruby agent](https://docs.newrelic.com/docs/agents/ruby-agent/installation/uninstall-ruby-agent)
|
78
79
|
|
79
|
-
### Recording
|
80
|
+
### Recording deploys
|
80
81
|
|
81
82
|
The Ruby agent supports recording deployments in New Relic via a command line
|
82
83
|
tool or Capistrano recipes. For more information on these features, see
|
83
84
|
[our deployment documentation](http://docs.newrelic.com/docs/ruby/recording-deployments-with-the-ruby-agent)
|
84
85
|
for more information.
|
85
86
|
|
86
|
-
|
87
87
|
## Support
|
88
88
|
|
89
89
|
Should you need assistance with New Relic products, you are in good hands with several support diagnostic tools and support channels.
|
@@ -94,11 +94,10 @@ New Relic offers NRDiag, [a client-side diagnostic utility](https://docs.newreli
|
|
94
94
|
|
95
95
|
If the issue has been confirmed as a bug or is a Feature request, please file a GitHub issue.
|
96
96
|
|
97
|
-
**Support
|
97
|
+
**Support channels**
|
98
98
|
|
99
99
|
* [New Relic Documentation](https://docs.newrelic.com/docs/agents/ruby-agent): Comprehensive guidance for using our platform
|
100
100
|
* [New Relic Community](https://forum.newrelic.com): The best place to engage in troubleshooting questions
|
101
|
-
* [New Relic Developer](https://developer.newrelic.com/): Resources for building a custom observability applications
|
102
101
|
* [New Relic University](https://learn.newrelic.com/): A range of online training for New Relic users of every level
|
103
102
|
* [New Relic Technical Support](https://support.newrelic.com/) 24/7/365 ticketed support. Read more about our [Technical Support Offerings](https://docs.newrelic.com/docs/licenses/license-information/general-usage-licenses/support-plan).
|
104
103
|
|
@@ -132,7 +131,7 @@ As of version 6.12 (released July 16, 2020), the New Relic Ruby agent is license
|
|
132
131
|
|
133
132
|
The New Relic Ruby agent may use source code from third-party libraries. When used, these libraries will be outlined in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
|
134
133
|
|
135
|
-
## Thank
|
134
|
+
## Thank you
|
136
135
|
|
137
136
|
We always look forward to connecting with the community. We welcome [contributions](https://github.com/newrelic/newrelic-ruby-agent#contributing) to our source code and suggestions for improvements, and would love to hear about what you like and want to see in the future.
|
138
137
|
|
data/Rakefile
CHANGED
data/lib/boot/strap.rb
ADDED
@@ -0,0 +1,102 @@
|
|
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
|
+
# This file is designed to bootstrap a `Bundler.require`-based Ruby app (such as
|
6
|
+
# a Ruby on Rails app) so the app can be instrumented and observed by the
|
7
|
+
# New Relic Ruby agent without the agent being added to the app as a dependency.
|
8
|
+
# NOTE: introducing the agent into your application via bootstrap is in beta.
|
9
|
+
# Use at your own risk.
|
10
|
+
#
|
11
|
+
# Given a production-ready Ruby app that optionally has a pre-packaged "frozen"
|
12
|
+
# or "deployment"–gem bundle, the New Relic Ruby agent can be introduced
|
13
|
+
# to the app without modifying the app and keeping all of the app's content
|
14
|
+
# read-only.
|
15
|
+
#
|
16
|
+
# Prerequisites:
|
17
|
+
# - Ruby (tested v2.4+)
|
18
|
+
# - Bundler (included with Ruby, tested v1.17+)
|
19
|
+
#
|
20
|
+
# Instructions:
|
21
|
+
# - First, make sure the New Relic Ruby agent exists on disk. For these
|
22
|
+
# instructions, we'll assume the agent exists at `/newrelic`.
|
23
|
+
# - The agent can be downloaded as the "newrelic_rpm" gem from RubyGems.org
|
24
|
+
# and unpacked with "gem unpack"
|
25
|
+
# - The agent can be cloned from the New Relic public GitHub repo:
|
26
|
+
# https://github.com/newrelic/newrelic-ruby-agent
|
27
|
+
# - Next, use the "RUBYOPT" environment variable to require ("-r") this
|
28
|
+
# file (note that the ".rb" extension is dropped):
|
29
|
+
# ```
|
30
|
+
# export RUBYOPT="-r /newrelic/lib/boot/strap"
|
31
|
+
# ```
|
32
|
+
# - Add your New Relic license key as an environment variable.
|
33
|
+
# ```
|
34
|
+
# export NEW_RELIC_LICENSE_KEY=1a2b3c4d5e67f8g9h0i
|
35
|
+
# ```
|
36
|
+
# - Launch an existing Ruby app as usual. For a Ruby on Rails app, this might
|
37
|
+
# involve running `bin/rails server`.
|
38
|
+
# - In the Ruby app's directory, look for and inspect
|
39
|
+
# `log/newrelic_agent.log`. If this file exists and there are no "WARN" or
|
40
|
+
# "ERROR" entries within it, then the agent was successfully introduced to
|
41
|
+
# the Ruby application.
|
42
|
+
|
43
|
+
module NRBundlerPatch
|
44
|
+
NR_AGENT_GEM = 'newrelic_rpm'
|
45
|
+
|
46
|
+
def require(*_groups)
|
47
|
+
require_newrelic
|
48
|
+
|
49
|
+
super
|
50
|
+
end
|
51
|
+
|
52
|
+
def require_newrelic
|
53
|
+
lib = File.expand_path('../..', __FILE__)
|
54
|
+
$LOAD_PATH.reject! { |path| path.include?('newrelic_rpm') }
|
55
|
+
$LOAD_PATH.unshift(lib)
|
56
|
+
Kernel.require NR_AGENT_GEM
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class NRBundlerPatcher
|
61
|
+
BUNDLER = 'bundler'
|
62
|
+
RUBYOPT = 'RUBYOPT'
|
63
|
+
|
64
|
+
def self.patch
|
65
|
+
check_for_require
|
66
|
+
check_for_rubyopt
|
67
|
+
check_for_bundler
|
68
|
+
Bundler::Runtime.prepend(NRBundlerPatch)
|
69
|
+
rescue StandardError => e
|
70
|
+
Kernel.warn "New Relic entrypoint at #{__FILE__} encountered an issue:\n #{e.message}"
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def self.check_for_require
|
76
|
+
raise "#{__FILE__} is meant to be required, not invoked directly" if $PROGRAM_NAME == __FILE__
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.check_for_rubyopt
|
80
|
+
unless ENV[RUBYOPT].to_s.match?("-r #{__FILE__.rpartition('.').first}")
|
81
|
+
raise "#{__FILE__} is meant to be required via the RUBYOPT env var"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.check_for_bundler
|
86
|
+
require_bundler
|
87
|
+
|
88
|
+
raise 'Required Ruby Bundler class Bundler::Runtime not defined!' unless defined?(Bundler::Runtime)
|
89
|
+
|
90
|
+
unless Bundler::Runtime.method_defined?(:require)
|
91
|
+
raise "The active Ruby Bundler instance doesn't offer Bundler::Runtime#require"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.require_bundler
|
96
|
+
require BUNDLER
|
97
|
+
rescue LoadError => e
|
98
|
+
raise "Required Ruby library '#{BUNDLER}' could not be required - #{e}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
NRBundlerPatcher.patch
|
@@ -13,6 +13,7 @@ require 'new_relic/traced_thread'
|
|
13
13
|
require 'new_relic/coerce'
|
14
14
|
require 'new_relic/agent/autostart'
|
15
15
|
require 'new_relic/agent/harvester'
|
16
|
+
require 'new_relic/agent/health_check'
|
16
17
|
require 'new_relic/agent/hostname'
|
17
18
|
require 'new_relic/agent/new_relic_service'
|
18
19
|
require 'new_relic/agent/pipe_service'
|
@@ -37,6 +38,7 @@ require 'new_relic/agent/adaptive_sampler'
|
|
37
38
|
require 'new_relic/agent/serverless_handler'
|
38
39
|
require 'new_relic/agent/connect/request_builder'
|
39
40
|
require 'new_relic/agent/connect/response_handler'
|
41
|
+
require 'new_relic/agent/opentelemetry_bridge'
|
40
42
|
|
41
43
|
require 'new_relic/agent/agent_helpers/connect'
|
42
44
|
require 'new_relic/agent/agent_helpers/harvest'
|
@@ -88,6 +90,7 @@ module NewRelic
|
|
88
90
|
end
|
89
91
|
|
90
92
|
def init_components
|
93
|
+
@health_check = HealthCheck.new
|
91
94
|
@service = NewRelicService.new
|
92
95
|
@events = EventListener.new
|
93
96
|
@stats_engine = StatsEngine.new
|
@@ -98,6 +101,7 @@ module NewRelic
|
|
98
101
|
@adaptive_sampler = AdaptiveSampler.new(Agent.config[:sampling_target],
|
99
102
|
Agent.config[:sampling_target_period_in_seconds])
|
100
103
|
@serverless_handler = ServerlessHandler.new
|
104
|
+
@opentelemetry_bridge = OpenTelemetryBridge.new
|
101
105
|
end
|
102
106
|
|
103
107
|
def init_event_handlers
|
@@ -139,6 +143,8 @@ module NewRelic
|
|
139
143
|
# Holds all the methods defined on NewRelic::Agent::Agent
|
140
144
|
# instances
|
141
145
|
module InstanceMethods
|
146
|
+
# the agent control health check file generator
|
147
|
+
attr_reader :health_check
|
142
148
|
# the statistics engine that holds all the timeslice data
|
143
149
|
attr_reader :stats_engine
|
144
150
|
# the transaction sampler that handles recording transactions
|
@@ -68,6 +68,7 @@ module NewRelic
|
|
68
68
|
def handle_license_error(error)
|
69
69
|
::NewRelic::Agent.logger.error(error.message,
|
70
70
|
'Visit newrelic.com to obtain a valid license key, or to upgrade your account.')
|
71
|
+
NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::INVALID_LICENSE_KEY)
|
71
72
|
disconnect
|
72
73
|
end
|
73
74
|
|
@@ -191,6 +192,7 @@ module NewRelic
|
|
191
192
|
@connected_pid = $$
|
192
193
|
@connect_state = :connected
|
193
194
|
signal_connected
|
195
|
+
NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::HEALTHY)
|
194
196
|
rescue NewRelic::Agent::ForceDisconnectException => e
|
195
197
|
handle_force_disconnect(e)
|
196
198
|
rescue NewRelic::Agent::LicenseException => e
|
@@ -198,6 +200,7 @@ module NewRelic
|
|
198
200
|
rescue NewRelic::Agent::UnrecoverableAgentException => e
|
199
201
|
handle_unrecoverable_agent_error(e)
|
200
202
|
rescue StandardError, Timeout::Error, NewRelic::Agent::ServerConnectionException => e
|
203
|
+
NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::FAILED_TO_CONNECT)
|
201
204
|
retry if retry_from_error?(e, opts)
|
202
205
|
rescue Exception => e
|
203
206
|
::NewRelic::Agent.logger.error('Exception of unexpected type during Agent#connect():', e)
|
@@ -119,6 +119,7 @@ module NewRelic
|
|
119
119
|
rescue UnrecoverableServerException => e
|
120
120
|
NewRelic::Agent.logger.warn("#{endpoint} data was rejected by remote service, discarding. Error: ", e)
|
121
121
|
rescue ServerConnectionException => e
|
122
|
+
NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::FAILED_TO_CONNECT)
|
122
123
|
log_remote_unavailable(endpoint, e)
|
123
124
|
container.merge!(payload)
|
124
125
|
rescue => e
|
@@ -133,9 +134,11 @@ module NewRelic
|
|
133
134
|
rescue ForceRestartException, ForceDisconnectException
|
134
135
|
raise
|
135
136
|
rescue UnrecoverableServerException => e
|
137
|
+
NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::FAILED_TO_CONNECT)
|
136
138
|
NewRelic::Agent.logger.warn('get_agent_commands message was rejected by remote service, discarding. ' \
|
137
139
|
'Error: ', e)
|
138
140
|
rescue ServerConnectionException => e
|
141
|
+
NewRelic::agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::FAILED_TO_CONNECT)
|
139
142
|
log_remote_unavailable(:get_agent_commands, e)
|
140
143
|
rescue => e
|
141
144
|
NewRelic::Agent.logger.info('Error during check_for_and_handle_agent_commands, will retry later: ', e)
|
@@ -86,6 +86,7 @@ module NewRelic
|
|
86
86
|
# is the worker thread that gathers data and talks to the
|
87
87
|
# server.
|
88
88
|
def handle_force_disconnect(error)
|
89
|
+
NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::FORCED_DISCONNECT)
|
89
90
|
::NewRelic::Agent.logger.warn('Agent received a ForceDisconnectException from the server, disconnecting. ' \
|
90
91
|
"(#{error.message})")
|
91
92
|
disconnect
|
@@ -36,6 +36,9 @@ module NewRelic
|
|
36
36
|
# setting up the worker thread and the exit handler to shut
|
37
37
|
# down the agent
|
38
38
|
def check_config_and_start_agent
|
39
|
+
# some health statuses, such as invalid license key, are ran before
|
40
|
+
# the agent officially starts
|
41
|
+
@health_check.create_and_run_health_check_loop
|
39
42
|
return unless monitoring? && has_correct_license_key?
|
40
43
|
return if using_forking_dispatcher?
|
41
44
|
|
@@ -129,6 +132,7 @@ module NewRelic
|
|
129
132
|
if Agent.config[:monitor_mode]
|
130
133
|
true
|
131
134
|
else
|
135
|
+
NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::AGENT_DISABLED)
|
132
136
|
::NewRelic::Agent.logger.warn('Agent configured not to send data in this environment.')
|
133
137
|
false
|
134
138
|
end
|
@@ -140,6 +144,7 @@ module NewRelic
|
|
140
144
|
if Agent.config[:license_key] && Agent.config[:license_key].length > 0
|
141
145
|
true
|
142
146
|
else
|
147
|
+
NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::MISSING_LICENSE_KEY)
|
143
148
|
::NewRelic::Agent.logger.warn('No license key found. ' +
|
144
149
|
'This often means your newrelic.yml file was not found, or it lacks a section for the running ' \
|
145
150
|
"environment, '#{NewRelic::Control.instance.env}'. You may also want to try linting your newrelic.yml " \
|
@@ -160,6 +165,7 @@ module NewRelic
|
|
160
165
|
if key.length == 40
|
161
166
|
true
|
162
167
|
else
|
168
|
+
NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::INVALID_LICENSE_KEY)
|
163
169
|
::NewRelic::Agent.logger.error("Invalid license key: #{key}")
|
164
170
|
false
|
165
171
|
end
|
@@ -180,6 +186,7 @@ module NewRelic
|
|
180
186
|
end
|
181
187
|
|
182
188
|
unless app_name_configured?
|
189
|
+
NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::MISSING_APP_NAME)
|
183
190
|
NewRelic::Agent.logger.error('No application name configured.',
|
184
191
|
'The agent cannot start without at least one. Please check your ',
|
185
192
|
'newrelic.yml and ensure that it is valid and has at least one ',
|
@@ -0,0 +1,68 @@
|
|
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
|
6
|
+
module Agent
|
7
|
+
module Aws
|
8
|
+
CHARACTERS = %w[A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 2 3 4 5 6 7].freeze
|
9
|
+
HEX_MASK = '7fffffffff80'
|
10
|
+
|
11
|
+
def self.create_arn(service, resource, region, account_id)
|
12
|
+
# if any of the values are nil, we can't create an ARN
|
13
|
+
return unless service && resource && region && account_id
|
14
|
+
|
15
|
+
"arn:aws:#{service}:#{region}:#{account_id}:#{resource}"
|
16
|
+
rescue => e
|
17
|
+
NewRelic::Agent.logger.warn("Failed to create ARN: #{e}")
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.get_account_id(config)
|
21
|
+
# if it is set in the agent config, use that first
|
22
|
+
return NewRelic::Agent.config[:'cloud.aws.account_id'] if NewRelic::Agent.config[:'cloud.aws.account_id']
|
23
|
+
|
24
|
+
access_key_id = config.credentials.credentials.access_key_id if config&.credentials&.credentials&.respond_to?(:access_key_id)
|
25
|
+
return unless access_key_id
|
26
|
+
|
27
|
+
NewRelic::Agent::Aws.convert_access_key_to_account_id(access_key_id)
|
28
|
+
rescue => e
|
29
|
+
NewRelic::Agent.logger.debug("Failed to create account id: #{e}")
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.convert_access_key_to_account_id(access_key)
|
33
|
+
decoded_key = Integer(decode_to_hex(access_key[4..-1]), 16)
|
34
|
+
mask = Integer(HEX_MASK, 16)
|
35
|
+
(decoded_key & mask) >> 7
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.decode_to_hex(access_key)
|
39
|
+
bytes = access_key.delete('=').each_char.map { |c| CHARACTERS.index(c) }
|
40
|
+
|
41
|
+
bytes.each_slice(8).map do |section|
|
42
|
+
convert_section(section)
|
43
|
+
end.flatten[0...6].join
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.convert_section(section)
|
47
|
+
buffer = 0
|
48
|
+
section.each do |chunk|
|
49
|
+
buffer = (buffer << 5) + chunk
|
50
|
+
end
|
51
|
+
|
52
|
+
chunk_count = (section.length * 5.0 / 8.0).floor
|
53
|
+
|
54
|
+
if section.length < 8
|
55
|
+
buffer >>= (5 - (chunk_count * 8)) % 5
|
56
|
+
end
|
57
|
+
|
58
|
+
decoded = []
|
59
|
+
chunk_count.times do |i|
|
60
|
+
shift = 8 * (chunk_count - 1 - i)
|
61
|
+
decoded << ((buffer >> shift) & 255).to_s(16)
|
62
|
+
end
|
63
|
+
|
64
|
+
decoded
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|