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
@@ -9,18 +9,12 @@ module NewRelic
9
9
  module Instrumentation
10
10
  module ActiveRecord
11
11
  EXPLAINER = lambda do |statement|
12
- connection = NewRelic::Agent::Database.get_connection(statement.config) do
13
- ::ActiveRecord::Base.send("#{statement.config[:adapter]}_connection",
14
- statement.config)
15
- end
16
- # the following line needs else branch coverage
17
- if connection && connection.respond_to?(:execute) # rubocop:disable Style/SafeNavigation
18
- return connection.execute("EXPLAIN #{statement.sql}")
19
- end
12
+ NewRelic::Agent::Database.explain_this(statement, true)
20
13
  end
21
14
 
22
15
  def self.insert_instrumentation
23
- if defined?(::ActiveRecord::VERSION::MAJOR) && ::ActiveRecord::VERSION::MAJOR.to_i >= 3
16
+ if defined?(::ActiveRecord::VERSION::MAJOR) &&
17
+ NewRelic::Helper.version_satisfied?(::ActiveRecord::VERSION::MAJOR, '>=', 3)
24
18
  if ::NewRelic::Agent.config[:prepend_active_record_instrumentation]
25
19
  ::ActiveRecord::Base.prepend(::NewRelic::Agent::Instrumentation::ActiveRecordPrepend::BaseExtensions)
26
20
  ::ActiveRecord::Relation.prepend(::NewRelic::Agent::Instrumentation::ActiveRecordPrepend::RelationExtensions)
@@ -44,7 +38,7 @@ module NewRelic
44
38
  end
45
39
  end
46
40
 
47
- if RUBY_VERSION < '2.7.0'
41
+ if NewRelic::Helper.version_satisfied?(RUBY_VERSION, '<', '2.7.0')
48
42
  def log_with_newrelic_instrumentation(*args, &block)
49
43
  state = NewRelic::Agent::Tracer.state
50
44
 
@@ -144,11 +138,11 @@ DependencyDetection.defer do
144
138
  depends_on do
145
139
  defined?(ActiveRecord) && defined?(ActiveRecord::Base) &&
146
140
  (!defined?(ActiveRecord::VERSION) ||
147
- ActiveRecord::VERSION::MAJOR.to_i <= 3)
141
+ NewRelic::Helper.version_satisfied?(ActiveRecord::VERSION::MAJOR, '<=', 3))
148
142
  end
149
143
 
150
144
  depends_on do
151
- !NewRelic::Agent.config[:disable_activerecord_instrumentation]
145
+ !NewRelic::Agent.config[:disable_active_record_instrumentation]
152
146
  end
153
147
 
154
148
  executes do
@@ -158,7 +152,8 @@ DependencyDetection.defer do
158
152
  executes do
159
153
  require 'new_relic/agent/instrumentation/active_record_helper'
160
154
 
161
- if defined?(Rails::VERSION::MAJOR) && Rails::VERSION::MAJOR.to_i == 3
155
+ if defined?(Rails::VERSION::MAJOR) &&
156
+ NewRelic::Helper.version_satisfied?(Rails::VERSION::MAJOR, '==', 3)
162
157
  ActiveSupport.on_load(:active_record) do
163
158
  NewRelic::Agent::Instrumentation::ActiveRecord.insert_instrumentation
164
159
  end
@@ -49,7 +49,7 @@ module NewRelic
49
49
 
50
50
  alias_method(:delete_all_without_newrelic, :delete_all)
51
51
 
52
- if RUBY_VERSION < '2.7.0'
52
+ if NewRelic::Helper.version_satisfied?(RUBY_VERSION, '<', '2.7.0')
53
53
  def delete_all(*args, &blk)
54
54
  ::NewRelic::Agent.with_database_metric_name(self.name, nil, ACTIVE_RECORD) do
55
55
  delete_all_without_newrelic(*args, &blk)
@@ -170,6 +170,9 @@ module NewRelic
170
170
 
171
171
  'sqlite3' => 'SQLite',
172
172
 
173
+ # https://rubygems.org/gems/trilogy
174
+ 'trilogy' => 'MySQL',
175
+
173
176
  # https://rubygems.org/gems/activerecord-jdbcpostgresql-adapter
174
177
  'jdbcmysql' => 'MySQL',
175
178
 
@@ -222,7 +225,8 @@ module NewRelic
222
225
 
223
226
  'postgresql' => :postgres,
224
227
  'jdbcpostgresql' => :postgres,
225
- 'postgis' => :postgres
228
+ 'postgis' => :postgres,
229
+ 'redshift' => :postgres
226
230
  }.freeze
227
231
 
228
232
  DATASTORE_DEFAULT_PORTS = {
@@ -231,8 +235,7 @@ module NewRelic
231
235
  }.freeze
232
236
 
233
237
  DEFAULT = 'default'.freeze
234
- UNKNOWN = 'unknown'.freeze
235
- SLASH = '/'.freeze
238
+ UNKNOWN = NewRelic::UNKNOWN_LOWER
236
239
  LOCALHOST = 'localhost'.freeze
237
240
 
238
241
  def adapter_from_config(config)
@@ -288,7 +291,7 @@ module NewRelic
288
291
  private
289
292
 
290
293
  def postgres_unix_domain_socket_case?(host, adapter)
291
- adapter == :postgres && host && host.start_with?(SLASH)
294
+ adapter == :postgres && host && host.start_with?(NewRelic::SLASH)
292
295
  end
293
296
 
294
297
  def mysql_default_case?(config, adapter)
@@ -28,7 +28,7 @@ module NewRelic
28
28
  ) { yield }
29
29
  rescue => e
30
30
  # The translate_exception_class method got introduced in 4.1
31
- if ::ActiveRecord::VERSION::MINOR == 0
31
+ if NewRelic::Helper.version_satisfied?(::ActiveRecord::VERSION::MINOR, '==', 0)
32
32
  raise translate_exception(e, sql)
33
33
  else
34
34
  raise translate_exception_class(e, sql)
@@ -86,11 +86,12 @@ DependencyDetection.defer do
86
86
  depends_on do
87
87
  defined?(ActiveRecord) && defined?(ActiveRecord::Base) &&
88
88
  defined?(ActiveRecord::VERSION) &&
89
- ActiveRecord::VERSION::MAJOR.to_i >= 4
89
+ NewRelic::Helper.version_satisfied?(ActiveRecord::VERSION::MAJOR, '>=', 4)
90
90
  end
91
91
 
92
92
  depends_on do
93
- !NewRelic::Agent.config[:disable_activerecord_instrumentation] &&
93
+ !NewRelic::Agent.config[:disable_active_record_instrumentation] &&
94
+ !NewRelic::Agent.config[:disable_active_record_notifications] &&
94
95
  !NewRelic::Agent::Instrumentation::ActiveRecordSubscriber.subscribed?
95
96
  end
96
97
 
@@ -112,7 +113,7 @@ DependencyDetection.defer do
112
113
 
113
114
  # Default to .prepending, unless the ActiveRecord version is <=4
114
115
  # **AND** the :prepend_active_record_instrumentation config is false
115
- if ActiveRecord::VERSION::MAJOR > 4 \
116
+ if NewRelic::Helper.version_satisfied?(ActiveRecord::VERSION::MAJOR, '>', 4) \
116
117
  || NewRelic::Agent.config[:prepend_active_record_instrumentation]
117
118
 
118
119
  ActiveRecord::Base.send(:prepend,
@@ -130,11 +131,13 @@ DependencyDetection.defer do
130
131
  major_version = ActiveRecord::VERSION::MAJOR.to_i
131
132
  minor_version = ActiveRecord::VERSION::MINOR.to_i
132
133
 
133
- activerecord_extension = if major_version == 4
134
+ activerecord_extension = if NewRelic::Helper.version_satisfied?(major_version, '==', 4)
134
135
  NewRelic::Agent::Instrumentation::ActiveRecordNotifications::BaseExtensions4x
135
- elsif major_version == 5 && minor_version == 0
136
+ elsif NewRelic::Helper.version_satisfied?(major_version, '==', 5) &&
137
+ NewRelic::Helper.version_satisfied?(minor_version, '==', 0)
136
138
  NewRelic::Agent::Instrumentation::ActiveRecordNotifications::BaseExtensions50
137
- elsif major_version == 5 && minor_version == 1
139
+ elsif NewRelic::Helper.version_satisfied?(major_version, '==', 5) &&
140
+ NewRelic::Helper.version_satisfied?(minor_version, '==', 1)
138
141
  NewRelic::Agent::Instrumentation::ActiveRecordNotifications::BaseExtensions51
139
142
  end
140
143
 
@@ -145,9 +148,9 @@ DependencyDetection.defer do
145
148
  end
146
149
 
147
150
  executes do
148
- if ActiveRecord::VERSION::MAJOR == 5 \
149
- && ActiveRecord::VERSION::MINOR.to_i == 1 \
150
- && ActiveRecord::VERSION::TINY.to_i >= 6
151
+ if NewRelic::Helper.version_satisfied?(ActiveRecord::VERSION::MAJOR, '==', 5) \
152
+ && NewRelic::Helper.version_satisfied?(ActiveRecord::VERSION::MINOR, '==', 1) \
153
+ && NewRelic::Helper.version_satisfied?(ActiveRecord::VERSION::TINY, '>=', 6)
151
154
 
152
155
  ActiveRecord::Base.prepend(NewRelic::Agent::Instrumentation::ActiveRecordPrepend::BaseExtensions516)
153
156
  end
@@ -11,7 +11,7 @@ module NewRelic
11
11
  ACTIVE_RECORD = 'ActiveRecord'.freeze
12
12
 
13
13
  module BaseExtensions
14
- if RUBY_VERSION < '2.7.0'
14
+ if NewRelic::Helper.version_satisfied?(RUBY_VERSION, '<', '2.7.0')
15
15
  def save(*args, &blk)
16
16
  ::NewRelic::Agent.with_database_metric_name(self.class.name, nil, ACTIVE_RECORD) do
17
17
  super
@@ -46,7 +46,7 @@ module NewRelic
46
46
  # Starting in v5.1.6, this call no longer happens. We'll
47
47
  # have to set the database metrics explicitly now.
48
48
  #
49
- if RUBY_VERSION < '2.7.0'
49
+ if NewRelic::Helper.version_satisfied?(RUBY_VERSION, '<', '2.7.0')
50
50
  def touch(*args, **kwargs, &blk)
51
51
  ::NewRelic::Agent.with_database_metric_name(self.class.name, nil, ACTIVE_RECORD) do
52
52
  super
@@ -70,18 +70,7 @@ module NewRelic
70
70
  end
71
71
 
72
72
  def get_explain_plan(statement)
73
- connection = NewRelic::Agent::Database.get_connection(statement.config) do
74
- ::ActiveRecord::Base.send("#{statement.config[:adapter]}_connection",
75
- statement.config)
76
- end
77
- # the following line needs else branch coverage
78
- if connection && connection.respond_to?(:exec_query) # rubocop:disable Style/SafeNavigation
79
- return connection.exec_query("EXPLAIN #{statement.sql}",
80
- "Explain #{statement.name}",
81
- statement.binds)
82
- end
83
- rescue => e
84
- NewRelic::Agent.logger.debug("Couldn't fetch the explain plan for #{statement} due to #{e}")
73
+ NewRelic::Agent::Database.explain_this(statement)
85
74
  end
86
75
 
87
76
  def active_record_config(payload)
@@ -127,10 +116,14 @@ module NewRelic
127
116
  port_path_or_id = nil
128
117
  database = nil
129
118
 
130
- if ActiveRecordHelper::InstanceIdentification.supported_adapter?(config)
131
- host = ActiveRecordHelper::InstanceIdentification.host(config)
132
- port_path_or_id = ActiveRecordHelper::InstanceIdentification.port_path_or_id(config)
133
- database = config && config[:database]
119
+ begin
120
+ if ActiveRecordHelper::InstanceIdentification.supported_adapter?(config)
121
+ host = ActiveRecordHelper::InstanceIdentification.host(config)
122
+ port_path_or_id = ActiveRecordHelper::InstanceIdentification.port_path_or_id(config)
123
+ database = config && config[:database]
124
+ end
125
+ rescue
126
+ NewRelic::Agent.logger.debug("Failed to retrieve ActiveRecord host, port, and database details for adapter: #{config && config[:adapter]}")
134
127
  end
135
128
 
136
129
  segment = Tracer.start_datastore_segment(product: product,
@@ -0,0 +1,69 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module ActiveSupportBroadcastLogger::Chain
7
+ def self.instrument!
8
+ ::ActiveSupportBroadcastLogger.class_eval do
9
+ include NewRelic::Agent::Instrumentation::ActiveSupportBroadcastLogger
10
+
11
+ alias_method(:add_without_new_relic, :add)
12
+
13
+ def add(*args, &task)
14
+ record_one_broadcast_with_new_relic(*args) do
15
+ add_without_new_relic(*args, &traced_task)
16
+ end
17
+ end
18
+
19
+ alias_method(:debug_without_new_relic, :debug)
20
+
21
+ def debug(*args, &task)
22
+ record_one_broadcast_with_new_relic(*args) do
23
+ debug_without_new_relic(*args, &traced_task)
24
+ end
25
+ end
26
+
27
+ alias_method(:info_without_new_relic, :info)
28
+
29
+ def info(*args, &task)
30
+ record_one_broadcast_with_new_relic(*args) do
31
+ info_without_new_relic(*args, &traced_task)
32
+ end
33
+ end
34
+
35
+ alias_method(:warn_without_new_relic, :warn)
36
+
37
+ def warn(*args, &task)
38
+ record_one_broadcast_with_new_relic(*args) do
39
+ warn_without_new_relic(*args, &traced_task)
40
+ end
41
+ end
42
+
43
+ alias_method(:error_without_new_relic, :error)
44
+
45
+ def error(*args, &task)
46
+ record_one_broadcast_with_new_relic(*args) do
47
+ error_without_new_relic(*args, &traced_task)
48
+ end
49
+ end
50
+
51
+ alias_method(:fatal_without_new_relic, :fatal)
52
+
53
+ def fatal(*args, &task)
54
+ record_one_broadcast_with_new_relic(*args) do
55
+ fatal_without_new_relic(*args, &traced_task)
56
+ end
57
+ end
58
+ end
59
+
60
+ alias_method(:unknown_without_new_relic, :unknown)
61
+
62
+ def unknown(*args, &task)
63
+ record_one_broadcast_with_new_relic(*args) do
64
+ unknown_without_new_relic(*args, &traced_task)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,17 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module ActiveSupportBroadcastLogger
7
+ def record_one_broadcast_with_new_relic(*args)
8
+ if broadcasts && broadcasts[1..-1]
9
+ broadcasts[1..-1].each { |broadcasted_logger| broadcasted_logger.instance_variable_set(:@skip_instrumenting, true) }
10
+ yield
11
+ broadcasts.each { |broadcasted_logger| broadcasted_logger.instance_variable_set(:@skip_instrumenting, false) }
12
+ else
13
+ NewRelic::Agent.logger.error('Error recording broadcasted logger')
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module ActiveSupportBroadcastLogger::Prepend
7
+ include NewRelic::Agent::Instrumentation::ActiveSupportBroadcastLogger
8
+
9
+ def add(*args)
10
+ record_one_broadcast_with_new_relic(*args) { super }
11
+ end
12
+
13
+ def debug(*args)
14
+ record_one_broadcast_with_new_relic(*args) { super }
15
+ end
16
+
17
+ def info(*args)
18
+ record_one_broadcast_with_new_relic(*args) { super }
19
+ end
20
+
21
+ def warn(*args)
22
+ record_one_broadcast_with_new_relic(*args) { super }
23
+ end
24
+
25
+ def error(*args)
26
+ record_one_broadcast_with_new_relic(*args) { super }
27
+ end
28
+
29
+ def fatal(*args)
30
+ record_one_broadcast_with_new_relic(*args) { super }
31
+ end
32
+
33
+ def unknown(*args)
34
+ record_one_broadcast_with_new_relic(*args) { super }
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require_relative 'active_support_broadcast_logger/instrumentation'
6
+ require_relative 'active_support_broadcast_logger/chain'
7
+ require_relative 'active_support_broadcast_logger/prepend'
8
+
9
+ DependencyDetection.defer do
10
+ named :'active_support_broadcast_logger'
11
+
12
+ depends_on { defined?(ActiveSupport::BroadcastLogger) }
13
+
14
+ executes do
15
+ if use_prepend?
16
+ prepend_instrument ActiveSupport::BroadcastLogger, NewRelic::Agent::Instrumentation::ActiveSupportBroadcastLogger::Prepend
17
+ else
18
+ chain_instrument NewRelic::Agent::Instrumentation::ActiveSupportBroadcastLogger::Chain
19
+ end
20
+ end
21
+ end
@@ -6,8 +6,12 @@ module NewRelic
6
6
  module Agent
7
7
  module Instrumentation
8
8
  module ActiveSupportLogger
9
+ INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
10
+
9
11
  # Mark @skip_instrumenting on any broadcasted loggers to instrument Rails.logger only
10
12
  def broadcast_with_tracing(logger)
13
+ NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
14
+
11
15
  NewRelic::Agent::Instrumentation::Logger.mark_skip_instrumenting(logger)
12
16
  yield
13
17
  rescue => error
@@ -9,11 +9,11 @@ require_relative 'active_support_logger/prepend'
9
9
  DependencyDetection.defer do
10
10
  named :active_support_logger
11
11
 
12
- depends_on { defined?(ActiveSupport::Logger) }
12
+ depends_on do
13
+ defined?(ActiveSupport::Logger) && defined?(ActiveSupport::Logger.broadcast)
14
+ end
13
15
 
14
16
  executes do
15
- NewRelic::Agent.logger.info('Installing ActiveSupport::Logger instrumentation')
16
-
17
17
  if use_prepend?
18
18
  # the only method currently instrumented is a class method
19
19
  prepend_instrument ActiveSupport::Logger.singleton_class, NewRelic::Agent::Instrumentation::ActiveSupportLogger::Prepend
@@ -0,0 +1,23 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require_relative 'instrumentation'
6
+
7
+ module NewRelic::Agent::Instrumentation
8
+ module AsyncHttp::Chain
9
+ def self.instrument!
10
+ ::Async::HTTP::Internet.class_eval do
11
+ include NewRelic::Agent::Instrumentation::AsyncHttp
12
+
13
+ alias_method(:call_without_new_relic, :call)
14
+
15
+ def call(method, url, headers = nil, body = nil)
16
+ call_with_new_relic(method, url, headers, body) do |hdr|
17
+ call_without_new_relic(method, url, hdr, body)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,37 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require 'new_relic/agent/http_clients/async_http_wrappers'
6
+
7
+ module NewRelic::Agent::Instrumentation
8
+ module AsyncHttp
9
+ def call_with_new_relic(method, url, headers = nil, body = nil)
10
+ headers ||= {} # if it is nil, we need to make it a hash so we can insert headers
11
+ wrapped_request = NewRelic::Agent::HTTPClients::AsyncHTTPRequest.new(self, method, url, headers)
12
+
13
+ segment = NewRelic::Agent::Tracer.start_external_request_segment(
14
+ library: wrapped_request.type,
15
+ uri: wrapped_request.uri,
16
+ procedure: wrapped_request.method
17
+ )
18
+
19
+ begin
20
+ response = nil
21
+ segment.add_request_headers(wrapped_request)
22
+
23
+ NewRelic::Agent.disable_all_tracing do
24
+ response = NewRelic::Agent::Tracer.capture_segment_error(segment) do
25
+ yield(headers)
26
+ end
27
+ end
28
+
29
+ wrapped_response = NewRelic::Agent::HTTPClients::AsyncHTTPResponse.new(response)
30
+ segment.process_response_headers(wrapped_response)
31
+ response
32
+ ensure
33
+ segment&.finish
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,15 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require_relative 'instrumentation'
6
+
7
+ module NewRelic::Agent::Instrumentation
8
+ module AsyncHttp::Prepend
9
+ include NewRelic::Agent::Instrumentation::AsyncHttp
10
+
11
+ def call(method, url, headers = nil, body = nil)
12
+ call_with_new_relic(method, url, headers, body) { |hdr| super(method, url, hdr, body) }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require_relative 'async_http/instrumentation'
6
+ require_relative 'async_http/chain'
7
+ require_relative 'async_http/prepend'
8
+
9
+ DependencyDetection.defer do
10
+ named :async_http
11
+
12
+ depends_on do
13
+ defined?(Async::HTTP) &&
14
+ NewRelic::Helper.version_satisfied?(Async::HTTP::VERSION, '>=', '0.59.0') &&
15
+ !defined?(Traces::Backend::NewRelic) # defined in the traces-backend-newrelic gem
16
+ end
17
+
18
+ executes do
19
+ require 'async/http/internet'
20
+
21
+ if use_prepend?
22
+ prepend_instrument Async::HTTP::Internet, NewRelic::Agent::Instrumentation::AsyncHttp::Prepend
23
+ else
24
+ chain_instrument NewRelic::Agent::Instrumentation::AsyncHttp::Chain
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module Firehose::Chain
7
+ def self.instrument!
8
+ ::Aws::Firehose::Client.class_eval do
9
+ include NewRelic::Agent::Instrumentation::Firehose
10
+
11
+ NewRelic::Agent::Instrumentation::Firehose::INSTRUMENTED_METHODS.each do |method_name|
12
+ alias_method("#{method_name}_without_new_relic".to_sym, method_name.to_sym)
13
+
14
+ define_method(method_name) do |*args|
15
+ instrument_method_with_new_relic(method_name, *args) { send("#{method_name}_without_new_relic".to_sym, *args) }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,66 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module Firehose
7
+ INSTRUMENTED_METHODS = %w[
8
+ create_delivery_stream
9
+ delete_delivery_stream
10
+ describe_delivery_stream
11
+ list_delivery_streams
12
+ list_tags_for_delivery_stream
13
+ put_record
14
+ put_record_batch
15
+ start_delivery_stream_encryption
16
+ stop_delivery_stream_encryption
17
+ tag_delivery_stream
18
+ untag_delivery_stream
19
+ update_destination
20
+ ].freeze
21
+
22
+ FIREHOSE = 'Firehose'
23
+ AWS_KINESIS_DELIVERY_STREAMS = 'aws_kinesis_delivery_streams'
24
+
25
+ def instrument_method_with_new_relic(method_name, *args)
26
+ return yield unless NewRelic::Agent::Tracer.tracing_enabled?
27
+
28
+ NewRelic::Agent.record_instrumentation_invocation(FIREHOSE)
29
+
30
+ params = args[0]
31
+ segment = NewRelic::Agent::Tracer.start_segment(name: get_segment_name(method_name, params))
32
+ arn = get_arn(params) if params
33
+ segment&.add_agent_attribute('cloud.resource_id', arn) if arn
34
+
35
+ begin
36
+ NewRelic::Agent::Tracer.capture_segment_error(segment) { yield }
37
+ ensure
38
+ segment&.add_agent_attribute('cloud.platform', AWS_KINESIS_DELIVERY_STREAMS)
39
+ segment&.finish
40
+ end
41
+ end
42
+
43
+ def get_segment_name(method_name, params)
44
+ stream_name = params&.dig(:delivery_stream_name)
45
+ return "#{FIREHOSE}/#{method_name}/#{stream_name}" if stream_name
46
+
47
+ "#{FIREHOSE}/#{method_name}"
48
+ rescue => e
49
+ NewRelic::Agent.logger.warn("Failed to create segment name: #{e}")
50
+ end
51
+
52
+ def nr_account_id
53
+ return @nr_account_id if defined?(@nr_account_id)
54
+
55
+ @nr_account_id = NewRelic::Agent::Aws.get_account_id(config)
56
+ end
57
+
58
+ def get_arn(params)
59
+ stream_arn = params&.dig(:delivery_stream_arn)
60
+ return stream_arn if stream_arn
61
+
62
+ stream_name = params&.dig(:delivery_stream_name)
63
+ NewRelic::Agent::Aws.create_arn(FIREHOSE.downcase, "deliverystream/#{stream_name}", config&.region, nr_account_id) if stream_name
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,15 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module Firehose::Prepend
7
+ include NewRelic::Agent::Instrumentation::Firehose
8
+
9
+ INSTRUMENTED_METHODS.each do |method_name|
10
+ define_method(method_name) do |*args|
11
+ instrument_method_with_new_relic(method_name, *args) { super(*args) }
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require_relative 'aws_sdk_firehose/instrumentation'
6
+ require_relative 'aws_sdk_firehose/chain'
7
+ require_relative 'aws_sdk_firehose/prepend'
8
+
9
+ DependencyDetection.defer do
10
+ named :aws_sdk_firehose
11
+
12
+ depends_on do
13
+ defined?(Aws::Firehose::Client)
14
+ end
15
+ executes do
16
+ if use_prepend?
17
+ prepend_instrument Aws::Firehose::Client, NewRelic::Agent::Instrumentation::Firehose::Prepend
18
+ else
19
+ chain_instrument NewRelic::Agent::Instrumentation::Firehose::Chain
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module Kinesis::Chain
7
+ def self.instrument!
8
+ ::Aws::Kinesis::Client.class_eval do
9
+ include NewRelic::Agent::Instrumentation::Kinesis
10
+
11
+ NewRelic::Agent::Instrumentation::Kinesis::INSTRUMENTED_METHODS.each do |method_name|
12
+ alias_method("#{method_name}_without_new_relic".to_sym, method_name.to_sym)
13
+
14
+ define_method(method_name) do |*args|
15
+ instrument_method_with_new_relic(method_name, *args) { send("#{method_name}_without_new_relic".to_sym, *args) }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end