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.
Files changed (360) hide show
  1. checksums.yaml +4 -4
  2. data/.build_ignore +27 -0
  3. data/CHANGELOG.md +841 -7
  4. data/CONTRIBUTING.md +2 -9
  5. data/README.md +25 -22
  6. data/Rakefile +2 -2
  7. data/bin/newrelic +3 -9
  8. data/bin/newrelic_rpm +15 -0
  9. data/init.rb +2 -2
  10. data/lib/boot/strap.rb +102 -0
  11. data/lib/new_relic/agent/agent.rb +11 -2
  12. data/lib/new_relic/agent/agent_helpers/connect.rb +13 -8
  13. data/lib/new_relic/agent/agent_helpers/harvest.rb +3 -0
  14. data/lib/new_relic/agent/agent_helpers/shutdown.rb +4 -1
  15. data/lib/new_relic/agent/agent_helpers/special_startup.rb +1 -1
  16. data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +4 -3
  17. data/lib/new_relic/agent/agent_helpers/startup.rb +11 -3
  18. data/lib/new_relic/agent/agent_logger.rb +3 -1
  19. data/lib/new_relic/agent/attribute_filter.rb +3 -3
  20. data/lib/new_relic/agent/attribute_pre_filtering.rb +109 -0
  21. data/lib/new_relic/agent/aws.rb +68 -0
  22. data/lib/new_relic/agent/configuration/default_source.rb +918 -166
  23. data/lib/new_relic/agent/configuration/environment_source.rb +15 -3
  24. data/lib/new_relic/agent/configuration/high_security_source.rb +1 -0
  25. data/lib/new_relic/agent/configuration/manager.rb +72 -11
  26. data/lib/new_relic/agent/configuration/security_policy_source.rb +11 -0
  27. data/lib/new_relic/agent/configuration/yaml_source.rb +22 -2
  28. data/lib/new_relic/agent/connect/request_builder.rb +1 -1
  29. data/lib/new_relic/agent/custom_event_aggregator.rb +27 -1
  30. data/lib/new_relic/agent/database/obfuscation_helpers.rb +11 -11
  31. data/lib/new_relic/agent/database/obfuscator.rb +1 -0
  32. data/lib/new_relic/agent/database.rb +41 -1
  33. data/lib/new_relic/agent/database_adapter.rb +1 -1
  34. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +1 -1
  35. data/lib/new_relic/agent/datastores/redis.rb +1 -1
  36. data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +1 -1
  37. data/lib/new_relic/agent/distributed_tracing/distributed_trace_payload.rb +4 -8
  38. data/lib/new_relic/agent/distributed_tracing.rb +5 -3
  39. data/lib/new_relic/agent/error_collector.rb +40 -11
  40. data/lib/new_relic/agent/event_loop.rb +1 -1
  41. data/lib/new_relic/agent/external.rb +2 -0
  42. data/lib/new_relic/agent/harvester.rb +1 -1
  43. data/lib/new_relic/agent/health_check.rb +136 -0
  44. data/lib/new_relic/agent/http_clients/abstract.rb +4 -0
  45. data/lib/new_relic/agent/http_clients/async_http_wrappers.rb +80 -0
  46. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +1 -3
  47. data/lib/new_relic/agent/http_clients/ethon_wrappers.rb +109 -0
  48. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +0 -3
  49. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +1 -3
  50. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +0 -3
  51. data/lib/new_relic/agent/http_clients/httpx_wrappers.rb +91 -0
  52. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +1 -4
  53. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +0 -3
  54. data/lib/new_relic/agent/http_clients/uri_util.rb +1 -1
  55. data/lib/new_relic/agent/instrumentation/action_controller_other_subscriber.rb +1 -1
  56. data/lib/new_relic/agent/instrumentation/action_dispatch.rb +1 -1
  57. data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +1 -1
  58. data/lib/new_relic/agent/instrumentation/action_mailbox.rb +1 -1
  59. data/lib/new_relic/agent/instrumentation/action_mailer.rb +1 -1
  60. data/lib/new_relic/agent/instrumentation/active_job.rb +1 -1
  61. data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +6 -2
  62. data/lib/new_relic/agent/instrumentation/active_merchant.rb +3 -16
  63. data/lib/new_relic/agent/instrumentation/active_record.rb +8 -13
  64. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +8 -5
  65. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +13 -10
  66. data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +2 -2
  67. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +9 -16
  68. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/chain.rb +69 -0
  69. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/instrumentation.rb +17 -0
  70. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/prepend.rb +37 -0
  71. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger.rb +21 -0
  72. data/lib/new_relic/agent/instrumentation/active_support_logger/instrumentation.rb +4 -0
  73. data/lib/new_relic/agent/instrumentation/active_support_logger.rb +3 -3
  74. data/lib/new_relic/agent/instrumentation/async_http/chain.rb +23 -0
  75. data/lib/new_relic/agent/instrumentation/async_http/instrumentation.rb +37 -0
  76. data/lib/new_relic/agent/instrumentation/async_http/prepend.rb +15 -0
  77. data/lib/new_relic/agent/instrumentation/async_http.rb +27 -0
  78. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/chain.rb +21 -0
  79. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/instrumentation.rb +66 -0
  80. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/prepend.rb +15 -0
  81. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose.rb +22 -0
  82. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/chain.rb +21 -0
  83. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/instrumentation.rb +91 -0
  84. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/prepend.rb +15 -0
  85. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis.rb +22 -0
  86. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/chain.rb +33 -0
  87. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/instrumentation.rb +93 -0
  88. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/prepend.rb +23 -0
  89. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda.rb +23 -0
  90. data/lib/new_relic/agent/instrumentation/aws_sqs/chain.rb +37 -0
  91. data/lib/new_relic/agent/instrumentation/aws_sqs/instrumentation.rb +67 -0
  92. data/lib/new_relic/agent/instrumentation/aws_sqs/prepend.rb +21 -0
  93. data/lib/new_relic/agent/instrumentation/aws_sqs.rb +23 -0
  94. data/lib/new_relic/agent/instrumentation/bunny/chain.rb +1 -1
  95. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +23 -0
  96. data/lib/new_relic/agent/instrumentation/bunny.rb +4 -5
  97. data/lib/new_relic/agent/instrumentation/concurrent_ruby/chain.rb +1 -1
  98. data/lib/new_relic/agent/instrumentation/concurrent_ruby/instrumentation.rb +3 -4
  99. data/lib/new_relic/agent/instrumentation/concurrent_ruby/prepend.rb +1 -1
  100. data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +2 -3
  101. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +5 -2
  102. data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +4 -0
  103. data/lib/new_relic/agent/instrumentation/curb.rb +4 -5
  104. data/lib/new_relic/agent/instrumentation/delayed_job/chain.rb +1 -0
  105. data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +3 -0
  106. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +0 -23
  107. data/lib/new_relic/agent/instrumentation/dynamodb/chain.rb +27 -0
  108. data/lib/new_relic/agent/instrumentation/dynamodb/instrumentation.rb +64 -0
  109. data/lib/new_relic/agent/instrumentation/dynamodb/prepend.rb +19 -0
  110. data/lib/new_relic/agent/instrumentation/dynamodb.rb +23 -0
  111. data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +2 -3
  112. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +65 -10
  113. data/lib/new_relic/agent/instrumentation/elasticsearch.rb +2 -4
  114. data/lib/new_relic/agent/instrumentation/ethon/chain.rb +39 -0
  115. data/lib/new_relic/agent/instrumentation/ethon/instrumentation.rb +105 -0
  116. data/lib/new_relic/agent/instrumentation/ethon/prepend.rb +35 -0
  117. data/lib/new_relic/agent/instrumentation/ethon.rb +35 -0
  118. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +3 -0
  119. data/lib/new_relic/agent/instrumentation/excon.rb +1 -17
  120. data/lib/new_relic/agent/instrumentation/fiber/chain.rb +11 -4
  121. data/lib/new_relic/agent/instrumentation/fiber/instrumentation.rb +2 -6
  122. data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +10 -3
  123. data/lib/new_relic/agent/instrumentation/fiber.rb +1 -3
  124. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +4 -3
  125. data/lib/new_relic/agent/instrumentation/grape.rb +1 -1
  126. data/lib/new_relic/agent/instrumentation/grpc/client/chain.rb +1 -1
  127. data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +5 -2
  128. data/lib/new_relic/agent/instrumentation/grpc/client/prepend.rb +1 -1
  129. data/lib/new_relic/agent/instrumentation/grpc/client/request_wrapper.rb +1 -1
  130. data/lib/new_relic/agent/instrumentation/grpc/server/instrumentation.rb +5 -1
  131. data/lib/new_relic/agent/instrumentation/grpc_client.rb +2 -2
  132. data/lib/new_relic/agent/instrumentation/grpc_server.rb +2 -2
  133. data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +4 -0
  134. data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -5
  135. data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +4 -0
  136. data/lib/new_relic/agent/instrumentation/httprb.rb +0 -1
  137. data/lib/new_relic/agent/instrumentation/httpx/chain.rb +20 -0
  138. data/lib/new_relic/agent/instrumentation/httpx/instrumentation.rb +51 -0
  139. data/lib/new_relic/agent/instrumentation/httpx/prepend.rb +15 -0
  140. data/lib/new_relic/agent/instrumentation/httpx.rb +23 -0
  141. data/lib/new_relic/agent/instrumentation/logger/instrumentation.rb +3 -0
  142. data/lib/new_relic/agent/instrumentation/logger.rb +1 -3
  143. data/lib/new_relic/agent/instrumentation/logstasher/chain.rb +21 -0
  144. data/lib/new_relic/agent/instrumentation/logstasher/instrumentation.rb +24 -0
  145. data/lib/new_relic/agent/instrumentation/logstasher/prepend.rb +13 -0
  146. data/lib/new_relic/agent/instrumentation/logstasher.rb +25 -0
  147. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +4 -2
  148. data/lib/new_relic/agent/instrumentation/memcache/helper.rb +2 -2
  149. data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +13 -4
  150. data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +4 -2
  151. data/lib/new_relic/agent/instrumentation/memcache.rb +4 -5
  152. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +3 -5
  153. data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +13 -3
  154. data/lib/new_relic/agent/instrumentation/net_http.rb +2 -1
  155. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +4 -2
  156. data/lib/new_relic/agent/instrumentation/opensearch/chain.rb +21 -0
  157. data/lib/new_relic/agent/instrumentation/opensearch/instrumentation.rb +66 -0
  158. data/lib/new_relic/agent/instrumentation/opensearch/prepend.rb +13 -0
  159. data/lib/new_relic/agent/instrumentation/opensearch.rb +23 -0
  160. data/lib/new_relic/agent/instrumentation/padrino/instrumentation.rb +4 -0
  161. data/lib/new_relic/agent/instrumentation/padrino.rb +3 -3
  162. data/lib/new_relic/agent/instrumentation/queue_time.rb +1 -1
  163. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +9 -0
  164. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +4 -0
  165. data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +1 -1
  166. data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +10 -5
  167. data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +4 -0
  168. data/lib/new_relic/agent/instrumentation/rake.rb +1 -2
  169. data/lib/new_relic/agent/instrumentation/rdkafka/chain.rb +72 -0
  170. data/lib/new_relic/agent/instrumentation/rdkafka/instrumentation.rb +70 -0
  171. data/lib/new_relic/agent/instrumentation/rdkafka/prepend.rb +67 -0
  172. data/lib/new_relic/agent/instrumentation/rdkafka.rb +25 -0
  173. data/lib/new_relic/agent/instrumentation/redis/cluster_middleware.rb +26 -0
  174. data/lib/new_relic/agent/instrumentation/redis/constants.rb +2 -2
  175. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +18 -11
  176. data/lib/new_relic/agent/instrumentation/redis/middleware.rb +3 -0
  177. data/lib/new_relic/agent/instrumentation/redis.rb +11 -5
  178. data/lib/new_relic/agent/instrumentation/resque/instrumentation.rb +4 -0
  179. data/lib/new_relic/agent/instrumentation/resque.rb +8 -6
  180. data/lib/new_relic/agent/instrumentation/roda/chain.rb +43 -0
  181. data/lib/new_relic/agent/instrumentation/roda/ignorer.rb +45 -0
  182. data/lib/new_relic/agent/instrumentation/roda/instrumentation.rb +68 -0
  183. data/lib/new_relic/agent/instrumentation/roda/prepend.rb +24 -0
  184. data/lib/new_relic/agent/instrumentation/roda/roda_transaction_namer.rb +29 -0
  185. data/lib/new_relic/agent/instrumentation/roda.rb +36 -0
  186. data/lib/new_relic/agent/instrumentation/ruby_kafka/chain.rb +55 -0
  187. data/lib/new_relic/agent/instrumentation/ruby_kafka/instrumentation.rb +67 -0
  188. data/lib/new_relic/agent/instrumentation/ruby_kafka/prepend.rb +60 -0
  189. data/lib/new_relic/agent/instrumentation/ruby_kafka.rb +25 -0
  190. data/lib/new_relic/agent/instrumentation/ruby_openai/chain.rb +36 -0
  191. data/lib/new_relic/agent/instrumentation/ruby_openai/instrumentation.rb +196 -0
  192. data/lib/new_relic/agent/instrumentation/ruby_openai/prepend.rb +20 -0
  193. data/lib/new_relic/agent/instrumentation/ruby_openai.rb +35 -0
  194. data/lib/new_relic/agent/instrumentation/sequel.rb +1 -1
  195. data/lib/new_relic/agent/instrumentation/sidekiq/client.rb +4 -0
  196. data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delay_extensions.rb +24 -0
  197. data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +2 -2
  198. data/lib/new_relic/agent/instrumentation/sidekiq/server.rb +26 -3
  199. data/lib/new_relic/agent/instrumentation/sidekiq.rb +13 -16
  200. data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +1 -1
  201. data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +4 -0
  202. data/lib/new_relic/agent/instrumentation/sinatra/transaction_namer.rb +1 -3
  203. data/lib/new_relic/agent/instrumentation/sinatra.rb +3 -19
  204. data/lib/new_relic/agent/instrumentation/stripe.rb +28 -0
  205. data/lib/new_relic/agent/instrumentation/stripe_subscriber.rb +98 -0
  206. data/lib/new_relic/agent/instrumentation/thread/chain.rb +1 -1
  207. data/lib/new_relic/agent/instrumentation/thread/instrumentation.rb +1 -5
  208. data/lib/new_relic/agent/instrumentation/thread/prepend.rb +1 -1
  209. data/lib/new_relic/agent/instrumentation/thread.rb +0 -2
  210. data/lib/new_relic/agent/instrumentation/tilt/instrumentation.rb +4 -0
  211. data/lib/new_relic/agent/instrumentation/tilt.rb +0 -4
  212. data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +7 -3
  213. data/lib/new_relic/agent/instrumentation/typhoeus.rb +0 -1
  214. data/lib/new_relic/agent/instrumentation/view_component/chain.rb +21 -0
  215. data/lib/new_relic/agent/instrumentation/view_component/instrumentation.rb +45 -0
  216. data/lib/{tasks/instrumentation_generator/templates/instrumentation.tt → new_relic/agent/instrumentation/view_component/prepend.rb} +4 -4
  217. data/lib/new_relic/agent/instrumentation/view_component.rb +24 -0
  218. data/lib/new_relic/agent/javascript_instrumentor.rb +2 -4
  219. data/lib/new_relic/agent/llm/chat_completion_message.rb +25 -0
  220. data/lib/new_relic/agent/llm/chat_completion_summary.rb +66 -0
  221. data/lib/new_relic/agent/llm/embedding.rb +60 -0
  222. data/lib/new_relic/agent/llm/llm_event.rb +95 -0
  223. data/lib/new_relic/agent/llm/response_headers.rb +80 -0
  224. data/lib/new_relic/agent/llm.rb +49 -0
  225. data/lib/new_relic/agent/local_log_decorator.rb +20 -3
  226. data/lib/new_relic/agent/log_event_aggregator.rb +149 -26
  227. data/lib/new_relic/agent/log_event_attributes.rb +115 -0
  228. data/lib/new_relic/agent/logging.rb +5 -5
  229. data/lib/new_relic/agent/messaging.rb +18 -7
  230. data/lib/new_relic/agent/method_tracer.rb +4 -1
  231. data/lib/new_relic/agent/method_tracer_helpers.rb +26 -5
  232. data/lib/new_relic/agent/monitors/inbound_request_monitor.rb +1 -1
  233. data/lib/new_relic/agent/monitors/synthetics_monitor.rb +12 -1
  234. data/lib/new_relic/agent/new_relic_service/encoders.rb +2 -2
  235. data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +2 -2
  236. data/lib/new_relic/agent/new_relic_service.rb +61 -28
  237. data/lib/new_relic/agent/obfuscator.rb +0 -2
  238. data/lib/new_relic/agent/opentelemetry/context/propagation/trace_propagator.rb +66 -0
  239. data/lib/new_relic/agent/opentelemetry/context/propagation.rb +15 -0
  240. data/lib/{tasks/instrumentation_generator/templates/Envfile.tt → new_relic/agent/opentelemetry/context.rb} +9 -5
  241. data/lib/new_relic/agent/opentelemetry/trace/span.rb +31 -0
  242. data/lib/new_relic/agent/opentelemetry/trace/tracer.rb +129 -0
  243. data/lib/new_relic/agent/opentelemetry/trace/tracer_provider.rb +18 -0
  244. data/lib/new_relic/agent/opentelemetry/trace.rb +15 -0
  245. data/lib/new_relic/agent/opentelemetry/transaction_patch.rb +69 -0
  246. data/lib/new_relic/agent/opentelemetry_bridge.rb +32 -0
  247. data/lib/new_relic/agent/parameter_filtering.rb +1 -1
  248. data/lib/new_relic/agent/pipe_channel_manager.rb +2 -2
  249. data/lib/new_relic/agent/pipe_service.rb +1 -1
  250. data/lib/new_relic/agent/rules_engine/segment_terms_rule.rb +1 -2
  251. data/lib/new_relic/agent/rules_engine.rb +1 -1
  252. data/lib/new_relic/agent/sampler.rb +1 -0
  253. data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -1
  254. data/lib/new_relic/agent/samplers/memory_sampler.rb +1 -1
  255. data/lib/new_relic/agent/serverless_handler.rb +406 -0
  256. data/lib/new_relic/agent/serverless_handler_event_sources.json +155 -0
  257. data/lib/new_relic/agent/serverless_handler_event_sources.rb +49 -0
  258. data/lib/new_relic/agent/span_event_primitive.rb +32 -15
  259. data/lib/new_relic/agent/sql_sampler.rb +0 -1
  260. data/lib/new_relic/agent/system_info.rb +40 -0
  261. data/lib/new_relic/agent/threading/agent_thread.rb +1 -2
  262. data/lib/new_relic/agent/threading/backtrace_node.rb +10 -1
  263. data/lib/new_relic/agent/tracer.rb +16 -16
  264. data/lib/new_relic/agent/transaction/abstract_segment.rb +103 -41
  265. data/lib/new_relic/agent/transaction/datastore_segment.rb +1 -1
  266. data/lib/new_relic/agent/transaction/distributed_tracer.rb +3 -3
  267. data/lib/new_relic/agent/transaction/distributed_tracing.rb +7 -8
  268. data/lib/new_relic/agent/transaction/external_request_segment.rb +5 -12
  269. data/lib/new_relic/agent/transaction/message_broker_segment.rb +5 -3
  270. data/lib/new_relic/agent/transaction/request_attributes.rb +54 -11
  271. data/lib/new_relic/agent/transaction/trace_context.rb +34 -5
  272. data/lib/new_relic/agent/transaction/tracing.rb +20 -4
  273. data/lib/new_relic/agent/transaction.rb +38 -13
  274. data/lib/new_relic/agent/transaction_error_primitive.rb +39 -19
  275. data/lib/new_relic/agent/transaction_event_primitive.rb +19 -0
  276. data/lib/new_relic/agent/transaction_time_aggregator.rb +1 -1
  277. data/lib/new_relic/agent/utilization/ecs.rb +22 -0
  278. data/lib/new_relic/agent/utilization/ecs_v4.rb +22 -0
  279. data/lib/new_relic/agent/utilization/gcp.rb +1 -3
  280. data/lib/new_relic/agent/utilization/vendor.rb +5 -7
  281. data/lib/new_relic/agent/utilization_data.rb +40 -5
  282. data/lib/new_relic/agent/vm/{mri_vm.rb → c_ruby_vm.rb} +10 -18
  283. data/lib/new_relic/agent/vm.rb +2 -2
  284. data/lib/new_relic/agent/worker_loop.rb +1 -1
  285. data/lib/new_relic/agent.rb +286 -17
  286. data/lib/new_relic/base64.rb +25 -0
  287. data/lib/new_relic/cli/command.rb +6 -3
  288. data/lib/new_relic/constants.rb +8 -0
  289. data/lib/new_relic/control/class_methods.rb +1 -7
  290. data/lib/new_relic/control/frameworks/grape.rb +14 -0
  291. data/lib/new_relic/control/frameworks/padrino.rb +14 -0
  292. data/lib/new_relic/control/frameworks/rails.rb +17 -5
  293. data/lib/new_relic/control/frameworks/rails4.rb +1 -3
  294. data/lib/new_relic/control/frameworks/roda.rb +20 -0
  295. data/lib/new_relic/control/instance_methods.rb +13 -0
  296. data/lib/new_relic/control/instrumentation.rb +2 -16
  297. data/lib/new_relic/control/private_instance_methods.rb +4 -0
  298. data/lib/new_relic/control/security_interface.rb +57 -0
  299. data/lib/new_relic/control.rb +1 -1
  300. data/lib/new_relic/dependency_detection.rb +25 -13
  301. data/lib/new_relic/environment_report.rb +2 -2
  302. data/lib/new_relic/helper.rb +22 -0
  303. data/lib/new_relic/language_support.rb +12 -1
  304. data/lib/new_relic/latest_changes.rb +1 -1
  305. data/lib/new_relic/local_environment.rb +31 -18
  306. data/lib/new_relic/noticed_error.rb +5 -2
  307. data/lib/new_relic/rack/agent_hooks.rb +1 -1
  308. data/lib/new_relic/rack/agent_middleware.rb +0 -16
  309. data/lib/new_relic/rack/browser_monitoring.rb +29 -13
  310. data/lib/new_relic/supportability_helper.rb +5 -1
  311. data/lib/new_relic/thread_local_storage.rb +31 -0
  312. data/lib/new_relic/traced_thread.rb +2 -3
  313. data/lib/new_relic/version.rb +1 -1
  314. data/lib/sequel/extensions/new_relic_instrumentation.rb +4 -3
  315. data/lib/tasks/bump_version.rake +21 -0
  316. data/lib/tasks/config.rake +11 -5
  317. data/lib/tasks/coverage_report.rake +1 -1
  318. data/lib/tasks/gha.rake +31 -0
  319. data/lib/tasks/helpers/config.html.erb +94 -0
  320. data/lib/tasks/helpers/format.rb +11 -7
  321. data/lib/tasks/helpers/newrelicyml.rb +211 -0
  322. data/lib/tasks/helpers/version_bump.rb +62 -0
  323. data/lib/tasks/newrelic.rb +1 -0
  324. data/lib/tasks/newrelicyml.rake +13 -0
  325. data/lib/tasks/tests.rake +71 -0
  326. data/newrelic.yml +657 -251
  327. data/newrelic_rpm.gemspec +17 -10
  328. data/test/agent_helper.rb +38 -4
  329. metadata +230 -44
  330. data/.gitignore +0 -43
  331. data/.project +0 -23
  332. data/.rubocop.yml +0 -1909
  333. data/.rubocop_todo.yml +0 -61
  334. data/.simplecov +0 -15
  335. data/.snyk +0 -11
  336. data/.yardopts +0 -27
  337. data/Brewfile +0 -12
  338. data/DOCKER.md +0 -167
  339. data/Dockerfile +0 -10
  340. data/Guardfile +0 -26
  341. data/bin/newrelic_cmd +0 -6
  342. data/config/database.yml +0 -5
  343. data/config.dot +0 -278
  344. data/docker-compose.yml +0 -107
  345. data/lefthook.yml +0 -9
  346. data/lib/new_relic/agent/range_extensions.rb +0 -27
  347. data/lib/tasks/helpers/removers.rb +0 -33
  348. data/lib/tasks/instrumentation_generator/README.md +0 -63
  349. data/lib/tasks/instrumentation_generator/TODO.md +0 -33
  350. data/lib/tasks/instrumentation_generator/instrumentation.thor +0 -121
  351. data/lib/tasks/instrumentation_generator/templates/chain.tt +0 -22
  352. data/lib/tasks/instrumentation_generator/templates/chain_method.tt +0 -8
  353. data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +0 -29
  354. data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +0 -3
  355. data/lib/tasks/instrumentation_generator/templates/newrelic.yml.tt +0 -19
  356. data/lib/tasks/instrumentation_generator/templates/prepend.tt +0 -13
  357. data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +0 -3
  358. data/lib/tasks/instrumentation_generator/templates/test.tt +0 -15
  359. data/lib/tasks/multiverse.rake +0 -6
  360. data/lib/tasks/multiverse.rb +0 -83
data/CONTRIBUTING.md CHANGED
@@ -178,22 +178,15 @@ opensource@newrelic.com.
178
178
  For more information about CLAs, please check out Alex Russell’s excellent post,
179
179
  [“Why Do I Need to Sign This?”](https://infrequently.org/2008/06/why-do-i-need-to-sign-this/).
180
180
 
181
- ## Slack
182
-
183
- We host a public Slack with a dedicated channel for contributors and maintainers
184
- of open source projects hosted by New Relic. If you are contributing to this
185
- project, you're welcome to request access to the #oss-contributors channel in
186
- the newrelicusers.slack.com workspace. To request access, please use this [link](https://join.slack.com/t/newrelicusers/shared_invite/zt-1ayj69rzm-~go~Eo1whIQGYnu3qi15ng).
187
-
188
181
  ## Explorer's Hub
189
182
 
190
183
  New Relic hosts and moderates an online forum where customers can interact with
191
184
  New Relic employees as well as other customers to get help and share best
192
185
  practices. Like all official New Relic open source projects, there's a related
193
186
  Community topic in the New Relic Explorers Hub. You can find this project's
194
- topic/threads here:
187
+ topic/threads under the "Ruby Agent" category here:
195
188
 
196
- [Explorer's Hub](https://discuss.newrelic.com/tags/rubyagent)
189
+ [Explorer's Hub](https://forum.newrelic.com/s/category/Category__c/Default)
197
190
 
198
191
  ## And Finally...
199
192
 
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).
@@ -9,13 +9,13 @@ You can also extend the agent's performance monitoring to
9
9
  to help you improve the customer experience and make data-driven business decisions.
10
10
 
11
11
  The New Relic Ruby agent is dual-purposed as either a Gem or a Rails plugin,
12
- hosted on [github](https://github.com/newrelic/newrelic-ruby-agent).
12
+ hosted on [GitHub](https://github.com/newrelic/newrelic-ruby-agent).
13
13
 
14
14
  This code is actively maintained by New Relic engineering teams and delivered here in GitHub. See below for troubleshooting and defect reporting instructions.
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
- The latest released gem for the Ruby agent can be found at [Rubygems.org](https://rubygems.org/gems/newrelic_rpm)
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,44 +61,43 @@ 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.
90
90
 
91
- This [troubleshooting framework](https://discuss.newrelic.com/t/ruby-troubleshooting-framework-install/108685) steps you through common troubleshooting questions.
91
+ This [troubleshooting framework](https://forum.newrelic.com/s/hubtopic/aAX8W0000008bSgWAI/ruby-troubleshooting-framework-install) steps you through common troubleshooting questions.
92
92
 
93
93
  New Relic offers NRDiag, [a client-side diagnostic utility](https://docs.newrelic.com/docs/using-new-relic/cross-product-functions/troubleshooting/new-relic-diagnostics) that automatically detects common problems with New Relic agents. If NRDiag detects a problem, it suggests troubleshooting steps. NRDiag can also automatically attach troubleshooting data to a New Relic Support ticket.
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
- * [New Relic Community](https://discuss.newrelic.com/tags/rubyagent): The best place to engage in troubleshooting questions
101
- * [New Relic Developer](https://developer.newrelic.com/): Resources for building a custom observability applications
100
+ * [New Relic Community](https://forum.newrelic.com): The best place to engage in troubleshooting questions
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
 
@@ -119,7 +118,7 @@ If you have any questions, or to execute our corporate CLA (required if your con
119
118
 
120
119
  As noted in our [security policy](https://github.com/newrelic/newrelic-ruby-agent/security/policy), New Relic is committed to the privacy and security of our customers and their data. We believe that providing coordinated disclosure by security researchers and engaging with the security community are important means to achieve our security goals.
121
120
 
122
- If you believe you have found a security vulnerability in this project or any of New Relic's products or websites, we welcome and greatly appreciate you reporting it to New Relic through [HackerOne](https://hackerone.com/newrelic).
121
+ If you believe you have found a security vulnerability in this project or any of New Relic's products or websites, we welcome and greatly appreciate you reporting it to New Relic through [our bug bounty program](https://docs.newrelic.com/docs/security/security-privacy/information-security/report-security-vulnerabilities/).
123
122
 
124
123
  If you would like to contribute to this project, please review [these guidelines](https://github.com/newrelic/newrelic-ruby-agent/blob/main/CONTRIBUTING.md).
125
124
 
@@ -132,7 +131,11 @@ 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
135
+
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.
137
+
138
+ Visit our [project board](https://github.com/orgs/newrelic/projects/84/) to see what's upcoming in a future release, what we're currently working on, and what we're planning next.
136
139
 
137
140
  Thank you,
138
141
 
data/Rakefile CHANGED
@@ -131,8 +131,8 @@ end
131
131
 
132
132
  desc 'Start an interactive console session'
133
133
  task :console do
134
- require 'pry'
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/bin/newrelic CHANGED
@@ -1,14 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
4
+ # This command has been renamed "newrelic_rpm"
3
5
  # executes one of the commands in the new_relic/commands directory
4
6
  # pass the name of the command as an argument
5
7
 
6
- $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
7
- require 'new_relic/cli/command'
8
- begin
9
- NewRelic::Cli::Command.run
10
- rescue NewRelic::Cli::Command::CommandFailure => failure
11
- STDERR.puts failure.message
12
- STDERR.puts failure.options if failure.options
13
- exit(1)
14
- end
8
+ load File.dirname(__FILE__) + '/newrelic_rpm'
data/bin/newrelic_rpm ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # executes one of the commands in the new_relic/commands directory
5
+ # pass the name of the command as an argument
6
+
7
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
8
+ require 'new_relic/cli/command'
9
+ begin
10
+ NewRelic::Cli::Command.run
11
+ rescue NewRelic::Cli::Command::CommandFailure => failure
12
+ STDERR.puts failure.message
13
+ STDERR.puts failure.options if failure.options
14
+ exit(1)
15
+ end
data/init.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
3
  # frozen_string_literal: true
4
4
 
5
- # This is the initialization for the New Relic Ruby Agent when used as
5
+ # This is the initialization for the New Relic Ruby agent when used as
6
6
  # a plugin
7
7
  require 'new_relic/control'
8
8
 
@@ -12,7 +12,7 @@ require 'new_relic/control'
12
12
  # If you can't find any log files and you don't see anything in your
13
13
  # application log files please visit support.newrelic.com.
14
14
 
15
- # Initializer for the NewRelic Ruby Agent
15
+ # Initializer for the New Relic Ruby agent
16
16
 
17
17
  # After version 2.0 of Rails we can access the configuration directly.
18
18
  # We need it to add dev mode routes after initialization finished.
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'
@@ -34,8 +35,10 @@ require 'new_relic/agent/utilization_data'
34
35
  require 'new_relic/environment_report'
35
36
  require 'new_relic/agent/attribute_filter'
36
37
  require 'new_relic/agent/adaptive_sampler'
38
+ require 'new_relic/agent/serverless_handler'
37
39
  require 'new_relic/agent/connect/request_builder'
38
40
  require 'new_relic/agent/connect/response_handler'
41
+ require 'new_relic/agent/opentelemetry_bridge'
39
42
 
40
43
  require 'new_relic/agent/agent_helpers/connect'
41
44
  require 'new_relic/agent/agent_helpers/harvest'
@@ -47,7 +50,7 @@ require 'new_relic/agent/agent_helpers/transmit'
47
50
 
48
51
  module NewRelic
49
52
  module Agent
50
- # The Agent is a singleton that is instantiated when the plugin is
53
+ # The agent is a singleton that is instantiated when the plugin is
51
54
  # activated. It collects performance data from ruby applications
52
55
  # in realtime as the application runs, and periodically sends that
53
56
  # data to the NewRelic server.
@@ -87,6 +90,7 @@ module NewRelic
87
90
  end
88
91
 
89
92
  def init_components
93
+ @health_check = HealthCheck.new
90
94
  @service = NewRelicService.new
91
95
  @events = EventListener.new
92
96
  @stats_engine = StatsEngine.new
@@ -96,6 +100,8 @@ module NewRelic
96
100
  @monotonic_gc_profiler = VM::MonotonicGCProfiler.new
97
101
  @adaptive_sampler = AdaptiveSampler.new(Agent.config[:sampling_target],
98
102
  Agent.config[:sampling_target_period_in_seconds])
103
+ @serverless_handler = ServerlessHandler.new
104
+ @opentelemetry_bridge = OpenTelemetryBridge.new
99
105
  end
100
106
 
101
107
  def init_event_handlers
@@ -137,6 +143,8 @@ module NewRelic
137
143
  # Holds all the methods defined on NewRelic::Agent::Agent
138
144
  # instances
139
145
  module InstanceMethods
146
+ # the agent control health check file generator
147
+ attr_reader :health_check
140
148
  # the statistics engine that holds all the timeslice data
141
149
  attr_reader :stats_engine
142
150
  # the transaction sampler that handles recording transactions
@@ -172,6 +180,7 @@ module NewRelic
172
180
  attr_reader :transaction_event_recorder
173
181
  attr_reader :attribute_filter
174
182
  attr_reader :adaptive_sampler
183
+ attr_reader :serverless_handler
175
184
 
176
185
  def transaction_event_aggregator
177
186
  @transaction_event_recorder.transaction_event_aggregator
@@ -307,7 +316,7 @@ module NewRelic
307
316
  @stats_engine = StatsEngine.new
308
317
  end
309
318
 
310
- def flush_pipe_data
319
+ def flush_pipe_data # used only by resque
311
320
  if connected? && @service.is_a?(PipeService)
312
321
  transmit_data_types
313
322
  end
@@ -27,9 +27,13 @@ module NewRelic
27
27
  @connect_state == :disconnected
28
28
  end
29
29
 
30
- # Don't connect if we're already connected, or if we tried to connect
31
- # and were rejected with prejudice because of a license issue, unless
32
- # we're forced to by force_reconnect.
30
+ def serverless?
31
+ Agent.config[:'serverless_mode.enabled']
32
+ end
33
+
34
+ # Don't connect if we're already connected, if we're in serverless mode,
35
+ # or if we tried to connect and were rejected with prejudice because of
36
+ # a license issue, unless we're forced to by force_reconnect.
33
37
  def should_connect?(force = false)
34
38
  force || (!connected? && !disconnected?)
35
39
  end
@@ -62,10 +66,9 @@ module NewRelic
62
66
  # no longer try to connect to the server, saving the
63
67
  # application and the server load
64
68
  def handle_license_error(error)
65
- ::NewRelic::Agent.logger.error( \
66
- error.message, \
67
- 'Visit NewRelic.com to obtain a valid license key, or to upgrade your account.'
68
- )
69
+ ::NewRelic::Agent.logger.error(error.message,
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)
69
72
  disconnect
70
73
  end
71
74
 
@@ -94,7 +97,7 @@ module NewRelic
94
97
  # connects, then configures the agent using the response from
95
98
  # the connect service
96
99
  def connect_to_server
97
- request_builder = ::NewRelic::Agent::Connect::RequestBuilder.new( \
100
+ request_builder = ::NewRelic::Agent::Connect::RequestBuilder.new(
98
101
  @service,
99
102
  Agent.config,
100
103
  event_harvest_config,
@@ -189,6 +192,7 @@ module NewRelic
189
192
  @connected_pid = $$
190
193
  @connect_state = :connected
191
194
  signal_connected
195
+ NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::HEALTHY)
192
196
  rescue NewRelic::Agent::ForceDisconnectException => e
193
197
  handle_force_disconnect(e)
194
198
  rescue NewRelic::Agent::LicenseException => e
@@ -196,6 +200,7 @@ module NewRelic
196
200
  rescue NewRelic::Agent::UnrecoverableAgentException => e
197
201
  handle_unrecoverable_agent_error(e)
198
202
  rescue StandardError, Timeout::Error, NewRelic::Agent::ServerConnectionException => e
203
+ NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::FAILED_TO_CONNECT)
199
204
  retry if retry_from_error?(e, opts)
200
205
  rescue Exception => e
201
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)
@@ -11,7 +11,7 @@ module NewRelic
11
11
  def shutdown
12
12
  return unless started?
13
13
 
14
- ::NewRelic::Agent.logger.info('Starting Agent shutdown')
14
+ ::NewRelic::Agent.logger.info('Starting agent shutdown')
15
15
 
16
16
  stop_event_loop
17
17
  trap_signals_for_litespeed
@@ -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
 
@@ -10,7 +10,7 @@ module NewRelic
10
10
  # requests, we need to wait until the children are forked
11
11
  # before connecting, otherwise the parent process sends useless data
12
12
  def using_forking_dispatcher?
13
- if [:puma, :passenger, :unicorn].include?(Agent.config[:dispatcher])
13
+ if [:puma, :passenger, :unicorn, :falcon].include?(Agent.config[:dispatcher])
14
14
  ::NewRelic::Agent.logger.info('Deferring startup of agent reporting thread because ' \
15
15
  "#{Agent.config[:dispatcher]} may fork.")
16
16
  true
@@ -19,12 +19,12 @@ module NewRelic
19
19
  # See #connect for a description of connection_options.
20
20
  def start_worker_thread(connection_options = {})
21
21
  if disable = NewRelic::Agent.config[:disable_harvest_thread]
22
- NewRelic::Agent.logger.info('Not starting Ruby Agent worker thread because :disable_harvest_thread is ' \
22
+ NewRelic::Agent.logger.info('Not starting Ruby agent worker thread because :disable_harvest_thread is ' \
23
23
  "#{disable}")
24
24
  return
25
25
  end
26
26
 
27
- ::NewRelic::Agent.logger.debug('Creating Ruby Agent worker thread.')
27
+ ::NewRelic::Agent.logger.debug('Creating Ruby agent worker thread.')
28
28
  @worker_thread = Threading::AgentThread.create('Worker Loop') do
29
29
  deferred_work!(connection_options)
30
30
  end
@@ -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
@@ -128,7 +129,7 @@ module NewRelic
128
129
  catch_errors do
129
130
  NewRelic::Agent.disable_all_tracing do
130
131
  connect(connection_options)
131
- if connected?
132
+ if NewRelic::Agent.instance.connected?
132
133
  create_and_run_event_loop
133
134
  # never reaches here unless there is a problem or
134
135
  # the agent is exiting
@@ -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
 
@@ -103,7 +106,7 @@ module NewRelic
103
106
  # so we can disambiguate processes in the log file and make
104
107
  # sure they're running a reasonable version
105
108
  def log_version_and_pid
106
- ::NewRelic::Agent.logger.debug("New Relic Ruby Agent #{NewRelic::VERSION::STRING} Initialized: pid = #{$$}")
109
+ ::NewRelic::Agent.logger.debug("New Relic Ruby agent #{NewRelic::VERSION::STRING} initialized: pid = #{$$}")
107
110
  end
108
111
 
109
112
  # Logs the configured application names
@@ -124,9 +127,12 @@ module NewRelic
124
127
  # Warn the user if they have configured their agent not to
125
128
  # send data, that way we can see this clearly in the log file
126
129
  def monitoring?
130
+ return false if Agent.config[:'serverless_mode.enabled']
131
+
127
132
  if Agent.config[:monitor_mode]
128
133
  true
129
134
  else
135
+ NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::AGENT_DISABLED)
130
136
  ::NewRelic::Agent.logger.warn('Agent configured not to send data in this environment.')
131
137
  false
132
138
  end
@@ -138,6 +144,7 @@ module NewRelic
138
144
  if Agent.config[:license_key] && Agent.config[:license_key].length > 0
139
145
  true
140
146
  else
147
+ NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::MISSING_LICENSE_KEY)
141
148
  ::NewRelic::Agent.logger.warn('No license key found. ' +
142
149
  'This often means your newrelic.yml file was not found, or it lacks a section for the running ' \
143
150
  "environment, '#{NewRelic::Control.instance.env}'. You may also want to try linting your newrelic.yml " \
@@ -146,7 +153,6 @@ module NewRelic
146
153
  end
147
154
  end
148
155
 
149
- # A correct license key exists and is of the proper length
150
156
  def has_correct_license_key?
151
157
  has_license_key? && correct_license_length
152
158
  end
@@ -159,6 +165,7 @@ module NewRelic
159
165
  if key.length == 40
160
166
  true
161
167
  else
168
+ NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::INVALID_LICENSE_KEY)
162
169
  ::NewRelic::Agent.logger.error("Invalid license key: #{key}")
163
170
  false
164
171
  end
@@ -179,8 +186,9 @@ module NewRelic
179
186
  end
180
187
 
181
188
  unless app_name_configured?
189
+ NewRelic::Agent.agent&.health_check&.update_status(NewRelic::Agent::HealthCheck::MISSING_APP_NAME)
182
190
  NewRelic::Agent.logger.error('No application name configured.',
183
- 'The Agent cannot start without at least one. Please check your ',
191
+ 'The agent cannot start without at least one. Please check your ',
184
192
  'newrelic.yml and ensure that it is valid and has at least one ',
185
193
  "value set for app_name in the #{NewRelic::Control.instance.env} ",
186
194
  'environment.')
@@ -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'
@@ -132,7 +133,8 @@ module NewRelic
132
133
  end
133
134
 
134
135
  def wants_stdout?
135
- ::NewRelic::Agent.config[:log_file_path].casecmp(NewRelic::STANDARD_OUT) == 0
136
+ ::NewRelic::Agent.config[:log_file_path].casecmp(NewRelic::STANDARD_OUT) == 0 ||
137
+ ::NewRelic::Agent.config[:'serverless_mode.enabled']
136
138
  end
137
139
 
138
140
  def find_or_create_file_path(path_setting, root)
@@ -2,7 +2,7 @@
2
2
  # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
3
  # frozen_string_literal: true
4
4
 
5
- # This class applies filtering rules as specified in the Agent Attributes
5
+ # This class applies filtering rules as specified in the agent attributes
6
6
  # cross-agent spec.
7
7
  #
8
8
  # Instances of it are constructed by deriving a set of rules from the agent
@@ -44,7 +44,7 @@
44
44
  # 1. First, the names are compared lexicographically. This has the impact of
45
45
  # forcing shorter (more general) rules towards the top of the list and longer
46
46
  # (more specific) rules towards the bottom. This is important, because the
47
- # Agent Attributes spec stipulates that the most specific rule for a given
47
+ # agent Attributes spec stipulates that the most specific rule for a given
48
48
  # destination should take precedence. Since rules are applied top-to-bottom,
49
49
  # this sorting guarantees that the most specific rule will be applied last.
50
50
  # 2. If the names are identical, we next examine the wildcard flag. Rules ending
@@ -274,7 +274,7 @@ module NewRelic
274
274
 
275
275
  def initialize(attribute_name, destinations, is_include)
276
276
  @attribute_name = attribute_name.sub(/\*$/, '')
277
- @wildcard = attribute_name.end_with?('*')
277
+ @wildcard = attribute_name.end_with?(ASTERISK)
278
278
  @is_include = is_include
279
279
  @destinations = is_include ? destinations : ~destinations
280
280
  end