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.
Files changed (219) hide show
  1. checksums.yaml +4 -4
  2. data/.build_ignore +1 -0
  3. data/CHANGELOG.md +463 -1
  4. data/CONTRIBUTING.md +2 -2
  5. data/README.md +16 -17
  6. data/Rakefile +1 -1
  7. data/lib/boot/strap.rb +102 -0
  8. data/lib/new_relic/agent/agent.rb +6 -0
  9. data/lib/new_relic/agent/agent_helpers/connect.rb +3 -0
  10. data/lib/new_relic/agent/agent_helpers/harvest.rb +3 -0
  11. data/lib/new_relic/agent/agent_helpers/shutdown.rb +3 -0
  12. data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +1 -0
  13. data/lib/new_relic/agent/agent_helpers/startup.rb +7 -0
  14. data/lib/new_relic/agent/agent_logger.rb +1 -0
  15. data/lib/new_relic/agent/aws.rb +68 -0
  16. data/lib/new_relic/agent/configuration/default_source.rb +603 -105
  17. data/lib/new_relic/agent/configuration/environment_source.rb +5 -1
  18. data/lib/new_relic/agent/configuration/manager.rb +28 -2
  19. data/lib/new_relic/agent/configuration/yaml_source.rb +7 -2
  20. data/lib/new_relic/agent/database/obfuscation_helpers.rb +11 -11
  21. data/lib/new_relic/agent/database/obfuscator.rb +1 -0
  22. data/lib/new_relic/agent/database.rb +41 -1
  23. data/lib/new_relic/agent/database_adapter.rb +1 -1
  24. data/lib/new_relic/agent/datastores/redis.rb +1 -1
  25. data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +1 -1
  26. data/lib/new_relic/agent/distributed_tracing.rb +4 -2
  27. data/lib/new_relic/agent/error_collector.rb +37 -10
  28. data/lib/new_relic/agent/external.rb +2 -0
  29. data/lib/new_relic/agent/health_check.rb +136 -0
  30. data/lib/new_relic/agent/http_clients/uri_util.rb +1 -1
  31. data/lib/new_relic/agent/instrumentation/action_dispatch.rb +1 -1
  32. data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +1 -1
  33. data/lib/new_relic/agent/instrumentation/action_mailbox.rb +1 -1
  34. data/lib/new_relic/agent/instrumentation/action_mailer.rb +1 -1
  35. data/lib/new_relic/agent/instrumentation/active_job.rb +1 -1
  36. data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +6 -2
  37. data/lib/new_relic/agent/instrumentation/active_merchant.rb +0 -13
  38. data/lib/new_relic/agent/instrumentation/active_record.rb +7 -12
  39. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +7 -3
  40. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +11 -9
  41. data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +2 -2
  42. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +9 -16
  43. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger.rb +0 -2
  44. data/lib/new_relic/agent/instrumentation/active_support_logger.rb +0 -2
  45. data/lib/new_relic/agent/instrumentation/async_http.rb +2 -3
  46. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/chain.rb +21 -0
  47. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/instrumentation.rb +66 -0
  48. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/prepend.rb +15 -0
  49. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose.rb +22 -0
  50. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/chain.rb +21 -0
  51. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/instrumentation.rb +91 -0
  52. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/prepend.rb +15 -0
  53. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis.rb +22 -0
  54. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/chain.rb +33 -0
  55. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/instrumentation.rb +93 -0
  56. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/prepend.rb +23 -0
  57. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda.rb +23 -0
  58. data/lib/new_relic/agent/instrumentation/aws_sqs/chain.rb +37 -0
  59. data/lib/new_relic/agent/instrumentation/aws_sqs/instrumentation.rb +67 -0
  60. data/lib/new_relic/agent/instrumentation/aws_sqs/prepend.rb +21 -0
  61. data/lib/new_relic/agent/instrumentation/aws_sqs.rb +23 -0
  62. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +14 -0
  63. data/lib/new_relic/agent/instrumentation/bunny.rb +3 -4
  64. data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +1 -3
  65. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +4 -0
  66. data/lib/new_relic/agent/instrumentation/curb.rb +4 -5
  67. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +0 -23
  68. data/lib/new_relic/agent/instrumentation/dynamodb/chain.rb +27 -0
  69. data/lib/new_relic/agent/instrumentation/dynamodb/instrumentation.rb +64 -0
  70. data/lib/new_relic/agent/instrumentation/dynamodb/prepend.rb +19 -0
  71. data/lib/new_relic/agent/instrumentation/dynamodb.rb +23 -0
  72. data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +1 -2
  73. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +53 -7
  74. data/lib/new_relic/agent/instrumentation/elasticsearch.rb +1 -3
  75. data/lib/new_relic/agent/instrumentation/ethon.rb +1 -5
  76. data/lib/new_relic/agent/instrumentation/excon.rb +1 -17
  77. data/lib/new_relic/agent/instrumentation/fiber/chain.rb +1 -1
  78. data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +1 -1
  79. data/lib/new_relic/agent/instrumentation/fiber.rb +0 -2
  80. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +0 -3
  81. data/lib/new_relic/agent/instrumentation/grape.rb +1 -1
  82. data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +0 -1
  83. data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -5
  84. data/lib/new_relic/agent/instrumentation/httprb.rb +0 -1
  85. data/lib/new_relic/agent/instrumentation/httpx/instrumentation.rb +1 -1
  86. data/lib/new_relic/agent/instrumentation/httpx.rb +1 -5
  87. data/lib/new_relic/agent/instrumentation/logger.rb +1 -3
  88. data/lib/new_relic/agent/instrumentation/logstasher/chain.rb +21 -0
  89. data/lib/new_relic/agent/instrumentation/logstasher/instrumentation.rb +24 -0
  90. data/lib/new_relic/agent/instrumentation/logstasher/prepend.rb +13 -0
  91. data/lib/new_relic/agent/instrumentation/logstasher.rb +25 -0
  92. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +1 -1
  93. data/lib/new_relic/agent/instrumentation/memcache/helper.rb +2 -2
  94. data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +1 -1
  95. data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +1 -1
  96. data/lib/new_relic/agent/instrumentation/memcache.rb +0 -1
  97. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +1 -1
  98. data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +3 -3
  99. data/lib/new_relic/agent/instrumentation/net_http.rb +2 -1
  100. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +0 -2
  101. data/lib/new_relic/agent/instrumentation/opensearch/chain.rb +21 -0
  102. data/lib/new_relic/agent/instrumentation/opensearch/instrumentation.rb +66 -0
  103. data/lib/{tasks/instrumentation_generator/templates/instrumentation.tt → new_relic/agent/instrumentation/opensearch/prepend.rb} +4 -4
  104. data/lib/new_relic/agent/instrumentation/opensearch.rb +23 -0
  105. data/lib/new_relic/agent/instrumentation/padrino.rb +3 -3
  106. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +3 -0
  107. data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +9 -5
  108. data/lib/new_relic/agent/instrumentation/rake.rb +1 -2
  109. data/lib/new_relic/agent/instrumentation/rdkafka/chain.rb +72 -0
  110. data/lib/new_relic/agent/instrumentation/rdkafka/instrumentation.rb +70 -0
  111. data/lib/new_relic/agent/instrumentation/rdkafka/prepend.rb +67 -0
  112. data/lib/new_relic/agent/instrumentation/rdkafka.rb +25 -0
  113. data/lib/new_relic/agent/instrumentation/redis/cluster_middleware.rb +26 -0
  114. data/lib/new_relic/agent/instrumentation/redis/constants.rb +2 -2
  115. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +14 -11
  116. data/lib/new_relic/agent/instrumentation/redis/middleware.rb +3 -0
  117. data/lib/new_relic/agent/instrumentation/redis.rb +11 -5
  118. data/lib/new_relic/agent/instrumentation/resque.rb +8 -6
  119. data/lib/new_relic/agent/instrumentation/roda.rb +5 -5
  120. data/lib/new_relic/agent/instrumentation/ruby_kafka/chain.rb +55 -0
  121. data/lib/new_relic/agent/instrumentation/ruby_kafka/instrumentation.rb +67 -0
  122. data/lib/new_relic/agent/instrumentation/ruby_kafka/prepend.rb +60 -0
  123. data/lib/new_relic/agent/instrumentation/ruby_kafka.rb +25 -0
  124. data/lib/new_relic/agent/instrumentation/ruby_openai.rb +2 -2
  125. data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delay_extensions.rb +24 -0
  126. data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +2 -2
  127. data/lib/new_relic/agent/instrumentation/sidekiq.rb +9 -15
  128. data/lib/new_relic/agent/instrumentation/sinatra.rb +3 -19
  129. data/lib/new_relic/agent/instrumentation/stripe.rb +1 -1
  130. data/lib/new_relic/agent/instrumentation/stripe_subscriber.rb +22 -1
  131. data/lib/new_relic/agent/instrumentation/thread.rb +0 -2
  132. data/lib/new_relic/agent/instrumentation/tilt.rb +0 -4
  133. data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +2 -2
  134. data/lib/new_relic/agent/instrumentation/typhoeus.rb +0 -1
  135. data/lib/new_relic/agent/instrumentation/view_component/instrumentation.rb +11 -5
  136. data/lib/new_relic/agent/instrumentation/view_component.rb +0 -2
  137. data/lib/new_relic/agent/javascript_instrumentor.rb +2 -3
  138. data/lib/new_relic/agent/llm/chat_completion_summary.rb +1 -1
  139. data/lib/new_relic/agent/llm/embedding.rb +1 -1
  140. data/lib/new_relic/agent/local_log_decorator.rb +20 -3
  141. data/lib/new_relic/agent/log_event_aggregator.rb +119 -28
  142. data/lib/new_relic/agent/logging.rb +1 -1
  143. data/lib/new_relic/agent/messaging.rb +16 -5
  144. data/lib/new_relic/agent/method_tracer.rb +3 -0
  145. data/lib/new_relic/agent/monitors/inbound_request_monitor.rb +1 -1
  146. data/lib/new_relic/agent/monitors/synthetics_monitor.rb +1 -1
  147. data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +2 -2
  148. data/lib/new_relic/agent/new_relic_service.rb +8 -2
  149. data/lib/new_relic/agent/opentelemetry/context/propagation/trace_propagator.rb +66 -0
  150. data/lib/new_relic/agent/opentelemetry/context/propagation.rb +15 -0
  151. data/lib/{tasks/instrumentation_generator/templates/Envfile.tt → new_relic/agent/opentelemetry/context.rb} +9 -5
  152. data/lib/new_relic/agent/opentelemetry/trace/span.rb +31 -0
  153. data/lib/new_relic/agent/opentelemetry/trace/tracer.rb +129 -0
  154. data/lib/new_relic/agent/opentelemetry/trace/tracer_provider.rb +18 -0
  155. data/lib/new_relic/agent/opentelemetry/trace.rb +15 -0
  156. data/lib/new_relic/agent/opentelemetry/transaction_patch.rb +69 -0
  157. data/lib/new_relic/agent/opentelemetry_bridge.rb +32 -0
  158. data/lib/new_relic/agent/parameter_filtering.rb +1 -1
  159. data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -1
  160. data/lib/new_relic/agent/samplers/memory_sampler.rb +1 -1
  161. data/lib/new_relic/agent/serverless_handler.rb +247 -12
  162. data/lib/new_relic/agent/serverless_handler_event_sources.json +155 -0
  163. data/lib/new_relic/agent/serverless_handler_event_sources.rb +49 -0
  164. data/lib/new_relic/agent/span_event_primitive.rb +16 -11
  165. data/lib/new_relic/agent/system_info.rb +14 -0
  166. data/lib/new_relic/agent/threading/backtrace_node.rb +10 -1
  167. data/lib/new_relic/agent/tracer.rb +1 -1
  168. data/lib/new_relic/agent/transaction/abstract_segment.rb +2 -1
  169. data/lib/new_relic/agent/transaction/datastore_segment.rb +1 -1
  170. data/lib/new_relic/agent/transaction/distributed_tracer.rb +3 -3
  171. data/lib/new_relic/agent/transaction/external_request_segment.rb +0 -10
  172. data/lib/new_relic/agent/transaction/message_broker_segment.rb +4 -1
  173. data/lib/new_relic/agent/transaction/request_attributes.rb +14 -7
  174. data/lib/new_relic/agent/transaction/trace_context.rb +34 -5
  175. data/lib/new_relic/agent/transaction/tracing.rb +3 -3
  176. data/lib/new_relic/agent/transaction.rb +4 -7
  177. data/lib/new_relic/agent/transaction_time_aggregator.rb +1 -1
  178. data/lib/new_relic/agent/utilization/ecs.rb +22 -0
  179. data/lib/new_relic/agent/utilization/ecs_v4.rb +22 -0
  180. data/lib/new_relic/agent/utilization_data.rb +40 -5
  181. data/lib/new_relic/agent/vm/c_ruby_vm.rb +3 -3
  182. data/lib/new_relic/agent.rb +124 -2
  183. data/lib/new_relic/constants.rb +1 -0
  184. data/lib/new_relic/control/frameworks/grape.rb +14 -0
  185. data/lib/new_relic/control/frameworks/padrino.rb +14 -0
  186. data/lib/new_relic/control/frameworks/rails4.rb +1 -3
  187. data/lib/new_relic/control/instance_methods.rb +6 -0
  188. data/lib/new_relic/control/instrumentation.rb +1 -1
  189. data/lib/new_relic/control/private_instance_methods.rb +4 -0
  190. data/lib/new_relic/control/security_interface.rb +57 -0
  191. data/lib/new_relic/control.rb +1 -1
  192. data/lib/new_relic/dependency_detection.rb +11 -14
  193. data/lib/new_relic/environment_report.rb +2 -2
  194. data/lib/new_relic/helper.rb +22 -0
  195. data/lib/new_relic/language_support.rb +3 -1
  196. data/lib/new_relic/local_environment.rb +1 -4
  197. data/lib/new_relic/rack/browser_monitoring.rb +20 -8
  198. data/lib/new_relic/version.rb +1 -1
  199. data/lib/sequel/extensions/new_relic_instrumentation.rb +3 -2
  200. data/lib/tasks/config.rake +7 -3
  201. data/lib/tasks/gha.rake +31 -0
  202. data/lib/tasks/helpers/config.html.erb +3 -2
  203. data/lib/tasks/helpers/format.rb +1 -1
  204. data/lib/tasks/helpers/newrelicyml.rb +80 -13
  205. data/newrelic.yml +425 -162
  206. data/newrelic_rpm.gemspec +3 -1
  207. data/test/agent_helper.rb +24 -2
  208. metadata +91 -22
  209. data/lib/tasks/instrumentation_generator/README.md +0 -63
  210. data/lib/tasks/instrumentation_generator/TODO.md +0 -33
  211. data/lib/tasks/instrumentation_generator/instrumentation.thor +0 -121
  212. data/lib/tasks/instrumentation_generator/templates/chain.tt +0 -21
  213. data/lib/tasks/instrumentation_generator/templates/chain_method.tt +0 -7
  214. data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +0 -29
  215. data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +0 -3
  216. data/lib/tasks/instrumentation_generator/templates/newrelic.yml.tt +0 -19
  217. data/lib/tasks/instrumentation_generator/templates/prepend.tt +0 -13
  218. data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +0 -3
  219. 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 Agent
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
  [![Gem Version](https://badge.fury.io/rb/newrelic_rpm.svg)](https://badge.fury.io/rb/newrelic_rpm)
17
17
 
18
- ## Supported Environments
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 Using
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 Start
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 Environments
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 Install Instructions
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 Deploys
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 Channels**
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 You
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
@@ -134,5 +134,5 @@ task :console do
134
134
  require 'pry' if ENV['ENABLE_PRY']
135
135
  require 'newrelic_rpm'
136
136
  ARGV.clear
137
- Pry.start
137
+ ENV['ENABLE_PRY'] ? Pry.start : binding.irb # rubocop:disable Lint/Debugger
138
138
  end
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)
@@ -19,6 +19,9 @@ module NewRelic
19
19
  revert_to_default_configuration
20
20
 
21
21
  @started = nil
22
+
23
+ NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::SHUTDOWN) if NewRelic::Agent.agent&.health_check&.healthy?
24
+
22
25
  Control.reset
23
26
  end
24
27
 
@@ -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 ',
@@ -4,6 +4,7 @@
4
4
 
5
5
  require 'thread'
6
6
  require 'logger'
7
+ require 'singleton'
7
8
  require 'new_relic/agent/hostname'
8
9
  require 'new_relic/agent/log_once'
9
10
  require 'new_relic/agent/instrumentation/logger/instrumentation'
@@ -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