newrelic_rpm 8.15.0 → 9.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (342) hide show
  1. checksums.yaml +4 -4
  2. data/.build_ignore +26 -0
  3. data/CHANGELOG.md +538 -44
  4. data/CONTRIBUTING.md +1 -1
  5. data/Gemfile +1 -1
  6. data/README.md +11 -6
  7. data/Rakefile +9 -9
  8. data/Thorfile +1 -1
  9. data/bin/newrelic +1 -0
  10. data/bin/newrelic_cmd +1 -0
  11. data/bin/nrdebug +36 -36
  12. data/init.rb +1 -1
  13. data/lib/new_relic/agent/agent.rb +3 -16
  14. data/lib/new_relic/agent/agent_helpers/connect.rb +5 -10
  15. data/lib/new_relic/agent/agent_helpers/harvest.rb +4 -4
  16. data/lib/new_relic/agent/agent_helpers/shutdown.rb +5 -5
  17. data/lib/new_relic/agent/agent_helpers/special_startup.rb +3 -4
  18. data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +47 -39
  19. data/lib/new_relic/agent/agent_helpers/startup.rb +13 -13
  20. data/lib/new_relic/agent/agent_helpers/transmit.rb +6 -6
  21. data/lib/new_relic/agent/agent_logger.rb +9 -9
  22. data/lib/new_relic/agent/attribute_filter.rb +2 -4
  23. data/lib/new_relic/agent/attribute_pre_filtering.rb +109 -0
  24. data/lib/new_relic/agent/attribute_processing.rb +2 -2
  25. data/lib/new_relic/agent/audit_logger.rb +5 -5
  26. data/lib/new_relic/agent/autostart.rb +1 -1
  27. data/lib/new_relic/agent/commands/agent_command.rb +2 -2
  28. data/lib/new_relic/agent/commands/agent_command_router.rb +5 -4
  29. data/lib/new_relic/agent/commands/thread_profiler_session.rb +8 -8
  30. data/lib/new_relic/agent/configuration/default_source.rb +428 -586
  31. data/lib/new_relic/agent/configuration/environment_source.rb +2 -2
  32. data/lib/new_relic/agent/configuration/high_security_source.rb +3 -5
  33. data/lib/new_relic/agent/configuration/manager.rb +16 -2
  34. data/lib/new_relic/agent/configuration/security_policy_source.rb +10 -26
  35. data/lib/new_relic/agent/configuration/server_source.rb +24 -24
  36. data/lib/new_relic/agent/configuration/yaml_source.rb +17 -4
  37. data/lib/new_relic/agent/connect/request_builder.rb +1 -1
  38. data/lib/new_relic/agent/connect/response_handler.rb +1 -1
  39. data/lib/new_relic/agent/custom_event_aggregator.rb +4 -4
  40. data/lib/new_relic/agent/database/explain_plan_helpers.rb +1 -1
  41. data/lib/new_relic/agent/database/obfuscation_helpers.rb +2 -2
  42. data/lib/new_relic/agent/database/obfuscator.rb +2 -2
  43. data/lib/new_relic/agent/database.rb +4 -18
  44. data/lib/new_relic/agent/datastores/metric_helper.rb +5 -5
  45. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +11 -11
  46. data/lib/new_relic/agent/datastores/redis.rb +6 -6
  47. data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +8 -10
  48. data/lib/new_relic/agent/distributed_tracing/distributed_trace_attributes.rb +10 -10
  49. data/lib/new_relic/agent/distributed_tracing/distributed_trace_metrics.rb +7 -7
  50. data/lib/new_relic/agent/distributed_tracing/distributed_trace_payload.rb +1 -1
  51. data/lib/new_relic/agent/distributed_tracing/distributed_trace_transport_type.rb +6 -6
  52. data/lib/new_relic/agent/distributed_tracing/trace_context.rb +7 -7
  53. data/lib/new_relic/agent/distributed_tracing/trace_context_payload.rb +4 -4
  54. data/lib/new_relic/agent/distributed_tracing.rb +6 -6
  55. data/lib/new_relic/agent/error_collector.rb +36 -8
  56. data/lib/new_relic/agent/error_filter.rb +5 -5
  57. data/lib/new_relic/agent/error_trace_aggregator.rb +5 -4
  58. data/lib/new_relic/agent/event_loop.rb +3 -3
  59. data/lib/new_relic/agent/external.rb +1 -1
  60. data/lib/new_relic/agent/harvester.rb +1 -3
  61. data/lib/new_relic/agent/heap.rb +2 -1
  62. data/lib/new_relic/agent/hostname.rb +1 -1
  63. data/lib/new_relic/agent/http_clients/abstract.rb +9 -21
  64. data/lib/new_relic/agent/http_clients/async_http_wrappers.rb +83 -0
  65. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +7 -3
  66. data/lib/new_relic/agent/http_clients/ethon_wrappers.rb +111 -0
  67. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +7 -5
  68. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +4 -0
  69. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +6 -2
  70. data/lib/new_relic/agent/http_clients/httpx_wrappers.rb +93 -0
  71. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +5 -1
  72. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +8 -5
  73. data/lib/new_relic/agent/http_clients/uri_util.rb +2 -2
  74. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +6 -19
  75. data/lib/new_relic/agent/instrumentation/action_controller_other_subscriber.rb +42 -0
  76. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +3 -2
  77. data/lib/new_relic/agent/instrumentation/action_dispatch.rb +31 -0
  78. data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +64 -0
  79. data/lib/new_relic/agent/instrumentation/action_mailbox.rb +30 -0
  80. data/lib/new_relic/agent/instrumentation/action_mailbox_subscriber.rb +33 -0
  81. data/lib/new_relic/agent/instrumentation/action_mailer.rb +30 -0
  82. data/lib/new_relic/agent/instrumentation/action_mailer_subscriber.rb +85 -0
  83. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +10 -10
  84. data/lib/new_relic/agent/instrumentation/active_job.rb +16 -3
  85. data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +41 -0
  86. data/lib/new_relic/agent/instrumentation/active_merchant.rb +3 -3
  87. data/lib/new_relic/agent/instrumentation/active_record.rb +4 -3
  88. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +38 -36
  89. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +5 -4
  90. data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +2 -2
  91. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +3 -2
  92. data/lib/new_relic/agent/instrumentation/active_storage.rb +4 -0
  93. data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +2 -30
  94. data/lib/new_relic/agent/instrumentation/active_support.rb +21 -6
  95. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/chain.rb +69 -0
  96. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/instrumentation.rb +13 -0
  97. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/prepend.rb +37 -0
  98. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger.rb +23 -0
  99. data/lib/new_relic/agent/instrumentation/active_support_logger/instrumentation.rb +4 -0
  100. data/lib/new_relic/agent/instrumentation/active_support_logger.rb +3 -1
  101. data/lib/new_relic/agent/instrumentation/active_support_subscriber.rb +41 -0
  102. data/lib/new_relic/agent/instrumentation/async_http/chain.rb +23 -0
  103. data/lib/new_relic/agent/instrumentation/async_http/instrumentation.rb +37 -0
  104. data/lib/new_relic/agent/instrumentation/async_http/prepend.rb +15 -0
  105. data/lib/new_relic/agent/instrumentation/async_http.rb +26 -0
  106. data/lib/new_relic/agent/instrumentation/bunny/chain.rb +1 -1
  107. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +12 -3
  108. data/lib/new_relic/agent/instrumentation/bunny.rb +1 -1
  109. data/lib/new_relic/agent/instrumentation/concurrent_ruby/chain.rb +1 -1
  110. data/lib/new_relic/agent/instrumentation/concurrent_ruby/instrumentation.rb +3 -4
  111. data/lib/new_relic/agent/instrumentation/concurrent_ruby/prepend.rb +1 -1
  112. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +7 -6
  113. data/lib/new_relic/agent/instrumentation/curb/chain.rb +1 -1
  114. data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +9 -5
  115. data/lib/new_relic/agent/instrumentation/curb.rb +1 -1
  116. data/lib/new_relic/agent/instrumentation/custom_events.rb +12 -0
  117. data/lib/new_relic/agent/instrumentation/custom_events_subscriber.rb +2 -1
  118. data/lib/new_relic/agent/instrumentation/delayed_job/chain.rb +1 -0
  119. data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +4 -1
  120. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +2 -1
  121. data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +2 -2
  122. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +8 -4
  123. data/lib/new_relic/agent/instrumentation/elasticsearch.rb +2 -2
  124. data/lib/new_relic/agent/instrumentation/ethon/chain.rb +39 -0
  125. data/lib/new_relic/agent/instrumentation/ethon/instrumentation.rb +105 -0
  126. data/lib/new_relic/agent/instrumentation/ethon/prepend.rb +35 -0
  127. data/lib/new_relic/agent/instrumentation/ethon.rb +39 -0
  128. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +5 -1
  129. data/lib/new_relic/agent/instrumentation/excon.rb +3 -3
  130. data/lib/new_relic/agent/instrumentation/fiber/chain.rb +27 -0
  131. data/lib/new_relic/agent/instrumentation/fiber/instrumentation.rb +23 -0
  132. data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +25 -0
  133. data/lib/new_relic/agent/instrumentation/fiber.rb +25 -0
  134. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +8 -4
  135. data/lib/new_relic/agent/instrumentation/grape.rb +4 -4
  136. data/lib/new_relic/agent/instrumentation/grpc/client/chain.rb +1 -1
  137. data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +7 -2
  138. data/lib/new_relic/agent/instrumentation/grpc/client/prepend.rb +1 -1
  139. data/lib/new_relic/agent/instrumentation/grpc/client/request_wrapper.rb +1 -1
  140. data/lib/new_relic/agent/instrumentation/grpc/server/instrumentation.rb +8 -4
  141. data/lib/new_relic/agent/instrumentation/grpc_client.rb +2 -2
  142. data/lib/new_relic/agent/instrumentation/grpc_server.rb +2 -2
  143. data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +4 -0
  144. data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +4 -0
  145. data/lib/new_relic/agent/instrumentation/httprb.rb +1 -1
  146. data/lib/new_relic/agent/instrumentation/httpx/chain.rb +20 -0
  147. data/lib/new_relic/agent/instrumentation/httpx/instrumentation.rb +51 -0
  148. data/lib/new_relic/agent/instrumentation/httpx/prepend.rb +15 -0
  149. data/lib/new_relic/agent/instrumentation/httpx.rb +27 -0
  150. data/lib/new_relic/agent/instrumentation/ignore_actions.rb +1 -1
  151. data/lib/new_relic/agent/instrumentation/logger/instrumentation.rb +3 -0
  152. data/lib/new_relic/agent/instrumentation/logger.rb +1 -1
  153. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +3 -1
  154. data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +14 -5
  155. data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +3 -1
  156. data/lib/new_relic/agent/instrumentation/memcache.rb +12 -12
  157. data/lib/new_relic/agent/instrumentation/middleware_proxy.rb +3 -3
  158. data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +1 -1
  159. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +6 -8
  160. data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +5 -1
  161. data/lib/new_relic/agent/instrumentation/net_http.rb +2 -2
  162. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +46 -1
  163. data/lib/new_relic/agent/instrumentation/padrino/instrumentation.rb +7 -3
  164. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +2 -2
  165. data/lib/new_relic/agent/instrumentation/queue_time.rb +1 -1
  166. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +7 -1
  167. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +7 -2
  168. data/lib/new_relic/agent/instrumentation/rails_middleware.rb +1 -1
  169. data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +4 -4
  170. data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +14 -1
  171. data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +12 -15
  172. data/lib/new_relic/agent/instrumentation/rake.rb +3 -3
  173. data/lib/new_relic/agent/instrumentation/redis/constants.rb +1 -1
  174. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +6 -1
  175. data/lib/new_relic/agent/instrumentation/redis.rb +1 -1
  176. data/lib/new_relic/agent/instrumentation/resque/helper.rb +1 -1
  177. data/lib/new_relic/agent/instrumentation/resque/instrumentation.rb +4 -0
  178. data/lib/new_relic/agent/instrumentation/resque.rb +1 -1
  179. data/lib/new_relic/agent/instrumentation/roda/chain.rb +43 -0
  180. data/lib/new_relic/agent/instrumentation/roda/ignorer.rb +45 -0
  181. data/lib/new_relic/agent/instrumentation/roda/instrumentation.rb +68 -0
  182. data/lib/new_relic/agent/instrumentation/roda/prepend.rb +24 -0
  183. data/lib/new_relic/agent/instrumentation/roda/roda_transaction_namer.rb +29 -0
  184. data/lib/new_relic/agent/instrumentation/roda.rb +36 -0
  185. data/lib/new_relic/agent/instrumentation/sequel.rb +8 -9
  186. data/lib/new_relic/agent/instrumentation/sequel_helper.rb +10 -10
  187. data/lib/new_relic/agent/instrumentation/sidekiq/client.rb +4 -0
  188. data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +1 -1
  189. data/lib/new_relic/agent/instrumentation/sidekiq/server.rb +26 -3
  190. data/lib/new_relic/agent/instrumentation/sidekiq.rb +6 -3
  191. data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +1 -1
  192. data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +10 -5
  193. data/lib/new_relic/agent/instrumentation/sinatra/transaction_namer.rb +2 -4
  194. data/lib/new_relic/agent/instrumentation/stripe.rb +28 -0
  195. data/lib/new_relic/agent/instrumentation/stripe_subscriber.rb +77 -0
  196. data/lib/new_relic/agent/instrumentation/thread/chain.rb +1 -1
  197. data/lib/new_relic/agent/instrumentation/thread/instrumentation.rb +3 -8
  198. data/lib/new_relic/agent/instrumentation/thread/prepend.rb +1 -1
  199. data/lib/new_relic/agent/instrumentation/tilt/instrumentation.rb +6 -1
  200. data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +10 -6
  201. data/lib/new_relic/agent/javascript_instrumentor.rb +29 -24
  202. data/lib/new_relic/agent/linking_metadata.rb +2 -2
  203. data/lib/new_relic/agent/log_event_aggregator.rb +64 -17
  204. data/lib/new_relic/agent/log_event_attributes.rb +115 -0
  205. data/lib/new_relic/agent/logging.rb +77 -37
  206. data/lib/new_relic/agent/messaging.rb +9 -7
  207. data/lib/new_relic/agent/method_tracer.rb +7 -7
  208. data/lib/new_relic/agent/method_tracer_helpers.rb +27 -6
  209. data/lib/new_relic/agent/monitors/cross_app_monitor.rb +4 -5
  210. data/lib/new_relic/agent/monitors/distributed_tracing_monitor.rb +1 -1
  211. data/lib/new_relic/agent/monitors/synthetics_monitor.rb +12 -1
  212. data/lib/new_relic/agent/new_relic_service/encoders.rb +1 -1
  213. data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +2 -2
  214. data/lib/new_relic/agent/new_relic_service/security_policy_settings.rb +0 -1
  215. data/lib/new_relic/agent/new_relic_service.rb +47 -32
  216. data/lib/new_relic/agent/obfuscator.rb +1 -1
  217. data/lib/new_relic/agent/parameter_filtering.rb +6 -6
  218. data/lib/new_relic/agent/pipe_channel_manager.rb +7 -6
  219. data/lib/new_relic/agent/pipe_service.rb +5 -3
  220. data/lib/new_relic/agent/priority_sampled_buffer.rb +1 -1
  221. data/lib/new_relic/agent/rules_engine/segment_terms_rule.rb +0 -1
  222. data/lib/new_relic/agent/rules_engine.rb +1 -1
  223. data/lib/new_relic/agent/sampler.rb +2 -1
  224. data/lib/new_relic/agent/sampler_collection.rb +1 -1
  225. data/lib/new_relic/agent/samplers/cpu_sampler.rb +5 -5
  226. data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +9 -9
  227. data/lib/new_relic/agent/samplers/memory_sampler.rb +9 -9
  228. data/lib/new_relic/agent/samplers/object_sampler.rb +1 -1
  229. data/lib/new_relic/agent/span_event_aggregator.rb +4 -4
  230. data/lib/new_relic/agent/span_event_primitive.rb +18 -6
  231. data/lib/new_relic/agent/sql_sampler.rb +2 -2
  232. data/lib/new_relic/agent/stats.rb +1 -1
  233. data/lib/new_relic/agent/synthetics_event_aggregator.rb +1 -1
  234. data/lib/new_relic/agent/system_info.rb +36 -10
  235. data/lib/new_relic/agent/threading/agent_thread.rb +1 -1
  236. data/lib/new_relic/agent/threading/backtrace_node.rb +3 -3
  237. data/lib/new_relic/agent/threading/backtrace_service.rb +3 -7
  238. data/lib/new_relic/agent/threading/thread_profile.rb +5 -5
  239. data/lib/new_relic/agent/timestamp_sampled_buffer.rb +1 -1
  240. data/lib/new_relic/agent/tracer.rb +25 -16
  241. data/lib/new_relic/agent/transaction/abstract_segment.rb +109 -48
  242. data/lib/new_relic/agent/transaction/datastore_segment.rb +1 -1
  243. data/lib/new_relic/agent/transaction/distributed_tracer.rb +7 -6
  244. data/lib/new_relic/agent/transaction/distributed_tracing.rb +13 -14
  245. data/lib/new_relic/agent/transaction/external_request_segment.rb +16 -13
  246. data/lib/new_relic/agent/transaction/message_broker_segment.rb +2 -3
  247. data/lib/new_relic/agent/transaction/request_attributes.rb +47 -11
  248. data/lib/new_relic/agent/transaction/segment.rb +1 -1
  249. data/lib/new_relic/agent/transaction/synthetics_sample_buffer.rb +1 -1
  250. data/lib/new_relic/agent/transaction/trace.rb +1 -1
  251. data/lib/new_relic/agent/transaction/trace_context.rb +4 -4
  252. data/lib/new_relic/agent/transaction/trace_node.rb +8 -7
  253. data/lib/new_relic/agent/transaction/tracing.rb +10 -4
  254. data/lib/new_relic/agent/transaction/transaction_sample_buffer.rb +1 -1
  255. data/lib/new_relic/agent/transaction.rb +90 -58
  256. data/lib/new_relic/agent/transaction_error_primitive.rb +21 -5
  257. data/lib/new_relic/agent/transaction_event_aggregator.rb +4 -4
  258. data/lib/new_relic/agent/transaction_event_primitive.rb +22 -3
  259. data/lib/new_relic/agent/transaction_sampler.rb +3 -3
  260. data/lib/new_relic/agent/transaction_time_aggregator.rb +7 -3
  261. data/lib/new_relic/agent/utilization/aws.rb +1 -1
  262. data/lib/new_relic/agent/utilization/azure.rb +3 -3
  263. data/lib/new_relic/agent/utilization/gcp.rb +4 -6
  264. data/lib/new_relic/agent/utilization/pcf.rb +1 -1
  265. data/lib/new_relic/agent/utilization/vendor.rb +6 -8
  266. data/lib/new_relic/agent/vm/monotonic_gc_profiler.rb +1 -1
  267. data/lib/new_relic/agent/vm/mri_vm.rb +9 -8
  268. data/lib/new_relic/agent/worker_loop.rb +1 -1
  269. data/lib/new_relic/agent.rb +133 -36
  270. data/lib/new_relic/cli/command.rb +4 -3
  271. data/lib/new_relic/cli/commands/deployments.rb +26 -25
  272. data/lib/new_relic/cli/commands/install.rb +23 -23
  273. data/lib/new_relic/collection_helper.rb +2 -2
  274. data/lib/new_relic/constants.rb +10 -8
  275. data/lib/new_relic/control/class_methods.rb +4 -10
  276. data/lib/new_relic/control/frameworks/rails.rb +44 -20
  277. data/lib/new_relic/control/frameworks/roda.rb +20 -0
  278. data/lib/new_relic/control/instance_methods.rb +6 -6
  279. data/lib/new_relic/control/instrumentation.rb +1 -15
  280. data/lib/new_relic/control/private_instance_methods.rb +1 -1
  281. data/lib/new_relic/dependency_detection.rb +20 -18
  282. data/lib/new_relic/environment_report.rb +4 -4
  283. data/lib/new_relic/helper.rb +2 -1
  284. data/lib/new_relic/language_support.rb +10 -1
  285. data/lib/new_relic/latest_changes.rb +6 -6
  286. data/lib/new_relic/local_environment.rb +0 -10
  287. data/lib/new_relic/noticed_error.rb +25 -20
  288. data/lib/new_relic/rack/agent_hooks.rb +1 -1
  289. data/lib/new_relic/rack/agent_middleware.rb +0 -16
  290. data/lib/new_relic/rack/browser_monitoring.rb +21 -17
  291. data/lib/new_relic/recipes/capistrano3.rb +1 -1
  292. data/lib/new_relic/recipes/capistrano_legacy.rb +6 -6
  293. data/lib/new_relic/recipes/helpers/send_deployment.rb +5 -5
  294. data/lib/new_relic/supportability_helper.rb +4 -1
  295. data/lib/new_relic/traced_thread.rb +2 -3
  296. data/lib/new_relic/version.rb +2 -2
  297. data/lib/newrelic_rpm.rb +4 -4
  298. data/lib/sequel/extensions/{newrelic_instrumentation.rb → new_relic_instrumentation.rb} +6 -6
  299. data/lib/sequel/plugins/{newrelic_instrumentation.rb → new_relic_instrumentation.rb} +4 -4
  300. data/lib/tasks/bump_version.rake +21 -0
  301. data/lib/tasks/config.rake +13 -12
  302. data/lib/tasks/coverage_report.rake +4 -4
  303. data/lib/tasks/helpers/config.html.erb +93 -0
  304. data/lib/tasks/helpers/format.rb +19 -15
  305. data/lib/tasks/helpers/newrelicyml.rb +144 -0
  306. data/lib/tasks/helpers/version_bump.rb +62 -0
  307. data/lib/tasks/install.rake +4 -4
  308. data/lib/tasks/instrumentation_generator/instrumentation.thor +16 -19
  309. data/lib/tasks/instrumentation_generator/templates/Envfile.tt +1 -1
  310. data/lib/tasks/instrumentation_generator/templates/chain.tt +1 -1
  311. data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +1 -1
  312. data/lib/tasks/newrelic.rb +1 -0
  313. data/lib/tasks/newrelicyml.rake +13 -0
  314. data/lib/tasks/tests.rake +77 -6
  315. data/newrelic.yml +393 -274
  316. data/newrelic_rpm.gemspec +41 -30
  317. data/test/agent_helper.rb +25 -24
  318. metadata +172 -35
  319. data/.gitignore +0 -42
  320. data/.project +0 -23
  321. data/.rubocop.yml +0 -1946
  322. data/.rubocop_todo.yml +0 -62
  323. data/.simplecov +0 -15
  324. data/.snyk +0 -11
  325. data/.yardopts +0 -27
  326. data/Brewfile +0 -12
  327. data/DOCKER.md +0 -167
  328. data/Dockerfile +0 -10
  329. data/Guardfile +0 -26
  330. data/config/database.yml +0 -5
  331. data/config.dot +0 -278
  332. data/docker-compose.yml +0 -107
  333. data/lefthook.yml +0 -9
  334. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +0 -83
  335. data/lib/new_relic/agent/instrumentation/authlogic.rb +0 -33
  336. data/lib/new_relic/agent/instrumentation/data_mapper.rb +0 -215
  337. data/lib/new_relic/agent/instrumentation/rainbows_instrumentation.rb +0 -36
  338. data/lib/new_relic/agent/instrumentation/sunspot.rb +0 -41
  339. data/lib/new_relic/agent/range_extensions.rb +0 -27
  340. data/lib/tasks/helpers/removers.rb +0 -33
  341. data/lib/tasks/multiverse.rake +0 -6
  342. data/lib/tasks/multiverse.rb +0 -77
@@ -0,0 +1,111 @@
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 'uri'
6
+ require_relative 'abstract'
7
+
8
+ module NewRelic
9
+ module Agent
10
+ module HTTPClients
11
+ class EthonHTTPResponse < AbstractResponse
12
+ def initialize(easy)
13
+ @easy = easy
14
+ end
15
+
16
+ def status_code
17
+ @easy.response_code
18
+ end
19
+
20
+ def [](key)
21
+ headers[format_key(key)]
22
+ end
23
+
24
+ def headers
25
+ # Ethon::Easy#response_headers will return '' if headers are unset
26
+ @easy.response_headers.scan(/\n([^:]+?): ([^:\n]+?)\r/).each_with_object({}) do |pair, hash|
27
+ hash[format_key(pair[0])] = pair[1]
28
+ end
29
+ end
30
+ alias to_hash headers
31
+
32
+ private
33
+
34
+ def format_key(key)
35
+ key.tr('-', '_').downcase
36
+ end
37
+ end
38
+
39
+ class EthonHTTPRequest < AbstractRequest
40
+ attr_reader :uri
41
+
42
+ DEFAULT_ACTION = 'GET'
43
+ DEFAULT_HOST = 'UNKNOWN_HOST'
44
+ ETHON = 'Ethon'
45
+ LHOST = 'host'.freeze
46
+ UHOST = 'Host'.freeze
47
+
48
+ def initialize(easy)
49
+ @easy = easy
50
+ @uri = uri_from_easy
51
+ end
52
+
53
+ def type
54
+ ETHON
55
+ end
56
+
57
+ def host_from_header
58
+ self[LHOST] || self[UHOST]
59
+ end
60
+
61
+ def uri_from_easy
62
+ # anticipate `Ethon::Easy#url` being `example.com` without a protocol
63
+ # defined and use an 'http' protocol prefix for `URI.parse` to work
64
+ # with the URL as desired
65
+ url_str = @easy.url.match?(':') ? @easy.url : "http://#{@easy.url}"
66
+ begin
67
+ URI.parse(url_str)
68
+ rescue URI::InvalidURIError => e
69
+ NewRelic::Agent.logger.debug("Failed to parse URI '#{url_str}': #{e.class} - #{e.message}")
70
+ URI.parse(NewRelic::EMPTY_STR)
71
+ end
72
+ end
73
+
74
+ def host
75
+ host_from_header || uri.host&.downcase || DEFAULT_HOST
76
+ end
77
+
78
+ def method
79
+ return DEFAULT_ACTION unless @easy.instance_variable_defined?(action_instance_var)
80
+
81
+ @easy.instance_variable_get(action_instance_var)
82
+ end
83
+
84
+ def action_instance_var
85
+ NewRelic::Agent::Instrumentation::Ethon::Easy::ACTION_INSTANCE_VAR
86
+ end
87
+
88
+ def []=(key, value)
89
+ headers[key] = value
90
+ @easy.headers = headers
91
+ end
92
+
93
+ def headers
94
+ @headers ||= if @easy.instance_variable_defined?(headers_instance_var)
95
+ @easy.instance_variable_get(headers_instance_var)
96
+ else
97
+ {}
98
+ end
99
+ end
100
+
101
+ def headers_instance_var
102
+ NewRelic::Agent::Instrumentation::Ethon::Easy::HEADERS_INSTANCE_VAR
103
+ end
104
+
105
+ def [](key)
106
+ headers[key]
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -46,7 +46,7 @@ module NewRelic
46
46
  class ExconHTTPRequest < AbstractRequest
47
47
  attr_reader :method
48
48
 
49
- EXCON = "Excon"
49
+ EXCON = 'Excon'
50
50
  LHOST = 'host'
51
51
  UHOST = 'Host'
52
52
  COLON = ':'
@@ -65,7 +65,6 @@ module NewRelic
65
65
  end
66
66
 
67
67
  def host_from_header
68
- headers = @datum[:headers]
69
68
  if hostname = (headers[LHOST] || headers[UHOST])
70
69
  hostname.split(COLON).first
71
70
  end
@@ -76,18 +75,21 @@ module NewRelic
76
75
  end
77
76
 
78
77
  def [](key)
79
- @datum[:headers][key]
78
+ headers[key]
80
79
  end
81
80
 
82
81
  def []=(key, value)
83
- @datum[:headers] ||= {}
84
- @datum[:headers][key] = value
82
+ headers[key] = value
85
83
  end
86
84
 
87
85
  def uri
88
86
  url = "#{@scheme}://#{host}:#{@port}#{@path}"
89
87
  URIUtil.parse_and_normalize_url(url)
90
88
  end
89
+
90
+ def headers
91
+ @datum[:headers]
92
+ end
91
93
  end
92
94
  end
93
95
  end
@@ -56,6 +56,10 @@ module NewRelic
56
56
  def []=(key, value)
57
57
  @wrapped_request.headers[key] = value
58
58
  end
59
+
60
+ def headers
61
+ @wrapped_request.headers.to_hash
62
+ end
59
63
  end
60
64
  end
61
65
  end
@@ -25,7 +25,7 @@ module NewRelic
25
25
  class HTTPClientRequest < AbstractRequest
26
26
  attr_reader :request
27
27
 
28
- HTTP_CLIENT = "HTTPClient".freeze
28
+ HTTP_CLIENT = 'HTTPClient'.freeze
29
29
  LHOST = 'host'.freeze
30
30
  UHOST = 'Host'.freeze
31
31
  COLON = ':'.freeze
@@ -57,12 +57,16 @@ module NewRelic
57
57
  end
58
58
 
59
59
  def [](key)
60
- request.headers[key]
60
+ headers[key]
61
61
  end
62
62
 
63
63
  def []=(key, value)
64
64
  request.http_header[key] = value
65
65
  end
66
+
67
+ def headers
68
+ request.headers
69
+ end
66
70
  end
67
71
  end
68
72
  end
@@ -0,0 +1,93 @@
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 'abstract'
6
+
7
+ module NewRelic
8
+ module Agent
9
+ module HTTPClients
10
+ # HTTPX returns an instance of HTTPX::ErrorResponse on error,
11
+ # and that instance itself yields the underlying HTTP response
12
+ # object via #response, but depending on the error that HTTP
13
+ # response object could be unset.
14
+ class HTTPXErrorResponse
15
+ def status; end
16
+ def headers; {}; end
17
+ end
18
+
19
+ class HTTPXHTTPResponse < AbstractResponse
20
+ def initialize(response)
21
+ if response.is_a?(::HTTPX::ErrorResponse)
22
+ @response = response.response || HTTPXErrorResponse.new
23
+ else
24
+ @response = response
25
+ end
26
+ end
27
+
28
+ def status_code
29
+ @response.status
30
+ end
31
+
32
+ def [](key)
33
+ headers[format_key(key)]
34
+ end
35
+
36
+ def headers
37
+ headers ||= @response.headers.to_hash.each_with_object({}) do |(k, v), h|
38
+ h[format_key(k)] = v
39
+ end
40
+ end
41
+ alias to_hash headers
42
+
43
+ private
44
+
45
+ def format_key(key)
46
+ key.tr('-', '_').downcase
47
+ end
48
+ end
49
+
50
+ class HTTPXHTTPRequest < AbstractRequest
51
+ attr_reader :uri
52
+
53
+ DEFAULT_HOST = 'UNKNOWN_HOST'
54
+ TYPE = 'HTTPX'
55
+ LHOST = 'host'.freeze
56
+ UHOST = 'Host'.freeze
57
+
58
+ def initialize(request)
59
+ @request = request
60
+ @uri = request.uri
61
+ end
62
+
63
+ def type
64
+ TYPE
65
+ end
66
+
67
+ def host_from_header
68
+ self[LHOST] || self[UHOST]
69
+ end
70
+
71
+ def host
72
+ host_from_header || uri.host&.downcase || DEFAULT_HOST
73
+ end
74
+
75
+ def method
76
+ @request.verb
77
+ end
78
+
79
+ def []=(key, value)
80
+ @request.headers[key] = value
81
+ end
82
+
83
+ def headers
84
+ @request.headers
85
+ end
86
+
87
+ def [](key)
88
+ @request.headers[key]
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -61,7 +61,7 @@ module NewRelic
61
61
  ::NewRelic::Agent::HTTPClients::URIUtil.parse_and_normalize_url(@request.path)
62
62
  else
63
63
  connection_address = @connection.address
64
- if connection_address =~ Resolv::IPv6::Regex
64
+ if Resolv::IPv6::Regex.match?(connection_address)
65
65
  connection_address = "[#{connection_address}]"
66
66
  end
67
67
 
@@ -71,6 +71,10 @@ module NewRelic
71
71
  )
72
72
  end
73
73
  end
74
+
75
+ def headers
76
+ @request.instance_variable_get(:@header)
77
+ end
74
78
  end
75
79
  end
76
80
  end
@@ -42,7 +42,7 @@ module NewRelic
42
42
  end
43
43
  end
44
44
 
45
- TYPHOEUS = "Typhoeus".freeze
45
+ TYPHOEUS = 'Typhoeus'.freeze
46
46
 
47
47
  def type
48
48
  TYPHOEUS
@@ -66,14 +66,17 @@ module NewRelic
66
66
  end
67
67
 
68
68
  def [](key)
69
- return nil unless @request.options && @request.options[:headers]
69
+ return nil unless @request.options && headers
70
70
 
71
- @request.options[:headers][key]
71
+ headers[key]
72
72
  end
73
73
 
74
74
  def []=(key, value)
75
- @request.options[:headers] ||= {}
76
- @request.options[:headers][key] = value
75
+ headers[key] = value
76
+ end
77
+
78
+ def headers
79
+ @request.options[:headers] || {}
77
80
  end
78
81
 
79
82
  def uri
@@ -36,11 +36,11 @@ module NewRelic
36
36
  uri = ::URI.parse(url)
37
37
  end
38
38
  end
39
- uri.host.downcase! unless uri.host.nil?
39
+ uri.host&.downcase!
40
40
  uri
41
41
  end
42
42
 
43
- QUESTION_MARK = "?"
43
+ QUESTION_MARK = '?'
44
44
 
45
45
  def self.strip_query_string(fragment)
46
46
  if fragment.include?(QUESTION_MARK)
@@ -10,9 +10,7 @@ module NewRelic
10
10
  class ActionCableSubscriber < NotificationsSubscriber
11
11
  PERFORM_ACTION = 'perform_action.action_cable'.freeze
12
12
 
13
- def start(name, id, payload) # THREAD_LOCAL_ACCESS
14
- return unless state.is_execution_traced?
15
-
13
+ def start_segment(name, id, payload) # THREAD_LOCAL_ACCESS
16
14
  finishable = if name == PERFORM_ACTION
17
15
  Tracer.start_transaction_or_segment(
18
16
  name: transaction_name_from_payload(payload),
@@ -22,21 +20,6 @@ module NewRelic
22
20
  Tracer.start_segment(name: metric_name_from_payload(name, payload))
23
21
  end
24
22
  push_segment(id, finishable)
25
- rescue => e
26
- log_notification_error(e, name, 'start')
27
- end
28
-
29
- def finish(name, id, payload) # THREAD_LOCAL_ACCESS
30
- return unless state.is_execution_traced?
31
-
32
- if exception = exception_object(payload)
33
- NewRelic::Agent.notice_error(exception)
34
- end
35
-
36
- finishable = pop_segment(id)
37
- finishable.finish if finishable
38
- rescue => e
39
- log_notification_error(e, name, 'finish')
40
23
  end
41
24
 
42
25
  private
@@ -46,7 +29,11 @@ module NewRelic
46
29
  end
47
30
 
48
31
  def metric_name_from_payload(name, payload)
49
- "Ruby/ActionCable/#{payload[:channel_class]}/#{action_name(name)}"
32
+ "Ruby/ActionCable/#{metric_name(payload)}/#{action_name(name)}"
33
+ end
34
+
35
+ def metric_name(payload)
36
+ payload[:broadcasting] || payload[:channel_class]
50
37
  end
51
38
 
52
39
  DOT_ACTION_CABLE = '.action_cable'.freeze
@@ -0,0 +1,42 @@
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/instrumentation/notifications_subscriber'
6
+ require 'new_relic/agent/instrumentation/ignore_actions'
7
+ require 'new_relic/agent/parameter_filtering'
8
+
9
+ module NewRelic
10
+ module Agent
11
+ module Instrumentation
12
+ class ActionControllerOtherSubscriber < NotificationsSubscriber
13
+ def add_segment_params(segment, payload)
14
+ segment.params[:filter] = payload[:filter] if payload[:filter]
15
+ segment.params[:keys] = payload[:keys] if payload[:keys]
16
+ segment.params[:original_path] = payload[:request].original_fullpath if payload[:request]
17
+
18
+ if payload[:context]
19
+ segment.params[:action] = payload[:context][:action]
20
+ segment.params[:controller] = payload[:context][:controller]
21
+ end
22
+ end
23
+
24
+ def metric_name(name, payload)
25
+ controller_name = controller_name_for_metric(payload)
26
+ "Ruby/ActionController#{"/#{controller_name}" if controller_name}/#{name.gsub('.action_controller', '')}"
27
+ end
28
+
29
+ def controller_name_for_metric(payload)
30
+ return unless payload
31
+ # redirect_to
32
+ return payload[:request].controller_class.controller_path if payload[:request].respond_to?(:controller_class) && payload[:request].controller_class&.respond_to?(:controller_path)
33
+
34
+ # unpermitted_parameters
35
+ if payload[:context]&.[](:controller) && constantized_class = ::NewRelic::LanguageSupport.constantize(payload[:context][:controller])
36
+ constantized_class.respond_to?(:controller_path) ? constantized_class.controller_path : nil
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -19,7 +19,7 @@ module NewRelic
19
19
  else
20
20
  # if this transaction is ignored, make sure child
21
21
  # transaction are also ignored
22
- state.current_transaction.ignore! if state.current_transaction
22
+ state.current_transaction&.ignore!
23
23
  NewRelic::Agent.instance.push_trace_execution_flag(false)
24
24
  end
25
25
  rescue => e
@@ -90,7 +90,8 @@ module NewRelic
90
90
  end
91
91
 
92
92
  def queue_start(request)
93
- if request && request.respond_to?(:env)
93
+ # the following line needs else branch coverage
94
+ if request && request.respond_to?(:env) # rubocop:disable Style/SafeNavigation
94
95
  QueueTime.parse_frontend_timestamp(request.env, Process.clock_gettime(Process::CLOCK_REALTIME))
95
96
  end
96
97
  end
@@ -0,0 +1,31 @@
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/instrumentation/action_dispatch_subscriber'
6
+
7
+ DependencyDetection.defer do
8
+ named :action_dispatch
9
+
10
+ depends_on do
11
+ !NewRelic::Agent.config[:disable_action_dispatch]
12
+ end
13
+
14
+ depends_on do
15
+ defined?(ActiveSupport) &&
16
+ defined?(ActionDispatch) &&
17
+ defined?(ActionPack) &&
18
+ ActionPack.respond_to?(:gem_version) &&
19
+ ActionPack.gem_version >= Gem::Version.new('6.0.0') && # notifications for dispatch added in Rails 6
20
+ !NewRelic::Agent::Instrumentation::ActionDispatchSubscriber.subscribed?
21
+ end
22
+
23
+ executes do
24
+ NewRelic::Agent.logger.info('Installing ActionDispatch instrumentation')
25
+ end
26
+
27
+ executes do
28
+ ActiveSupport::Notifications.subscribe(/\A[^\.]+\.action_dispatch\z/,
29
+ NewRelic::Agent::Instrumentation::ActionDispatchSubscriber.new)
30
+ end
31
+ end
@@ -0,0 +1,64 @@
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/instrumentation/notifications_subscriber'
6
+
7
+ module NewRelic
8
+ module Agent
9
+ module Instrumentation
10
+ class ActionDispatchSubscriber < NotificationsSubscriber
11
+ def start(name, id, payload)
12
+ return unless state.is_execution_traced?
13
+
14
+ start_segment(name, id, payload)
15
+ rescue => e
16
+ log_notification_error(e, name, 'start')
17
+ end
18
+
19
+ def finish(name, id, payload)
20
+ return unless state.is_execution_traced?
21
+
22
+ finish_segment(id, payload)
23
+ rescue => e
24
+ log_notification_error(e, name, 'finish')
25
+ end
26
+
27
+ def start_segment(name, id, payload)
28
+ segment = Tracer.start_segment(name: metric_name(name, payload))
29
+ push_segment(id, segment)
30
+ end
31
+
32
+ def finish_segment(id, payload)
33
+ if segment = pop_segment(id)
34
+ if exception = exception_object(payload)
35
+ segment.notice_error(exception)
36
+ end
37
+ segment.finish
38
+ end
39
+ end
40
+
41
+ def metric_name(name, payload)
42
+ middleware = payload[:middleware]
43
+ method = method_from_name(name)
44
+ "Ruby/ActionDispatch/#{middleware}/#{method}"
45
+ end
46
+
47
+ PATTERN = /\A([^\.]+)\.action_dispatch\z/
48
+ UNKNOWN = 'unknown'.freeze
49
+
50
+ METHOD_NAME_MAPPING = Hash.new do |h, k|
51
+ if PATTERN =~ k
52
+ h[k] = $1
53
+ else
54
+ h[k] = UNKNOWN
55
+ end
56
+ end
57
+
58
+ def method_from_name(name)
59
+ METHOD_NAME_MAPPING[name]
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,30 @@
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/instrumentation/action_mailbox_subscriber'
6
+
7
+ DependencyDetection.defer do
8
+ named :action_mailbox
9
+
10
+ depends_on do
11
+ !NewRelic::Agent.config[:disable_action_mailbox]
12
+ end
13
+
14
+ depends_on do
15
+ defined?(ActiveSupport) &&
16
+ defined?(ActionMailbox) &&
17
+ ActionMailbox.respond_to?(:gem_version) && # 'require "action_mailbox"' doesn't require version...
18
+ ActionMailbox.gem_version >= Gem::Version.new('7.1.0.alpha') && # notifications added in Rails 7.1
19
+ !NewRelic::Agent::Instrumentation::ActionMailboxSubscriber.subscribed?
20
+ end
21
+
22
+ executes do
23
+ NewRelic::Agent.logger.info('Installing ActionMailbox instrumentation')
24
+ end
25
+
26
+ executes do
27
+ ActiveSupport::Notifications.subscribe(/\A[^\.]+\.action_mailbox\z/,
28
+ NewRelic::Agent::Instrumentation::ActionMailboxSubscriber.new)
29
+ end
30
+ end
@@ -0,0 +1,33 @@
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/instrumentation/notifications_subscriber'
6
+
7
+ module NewRelic
8
+ module Agent
9
+ module Instrumentation
10
+ class ActionMailboxSubscriber < NotificationsSubscriber
11
+ def metric_name(name, payload)
12
+ mailbox = payload[:mailbox].class.name
13
+ method = method_from_name(name)
14
+ "Ruby/ActionMailbox/#{mailbox}/#{method}"
15
+ end
16
+
17
+ PATTERN = /\A([^\.]*)\.action_mailbox\z/
18
+
19
+ METHOD_NAME_MAPPING = Hash.new do |h, k|
20
+ if PATTERN =~ k
21
+ h[k] = $1
22
+ else
23
+ h[k] = NewRelic::UNKNOWN
24
+ end
25
+ end
26
+
27
+ def method_from_name(name)
28
+ METHOD_NAME_MAPPING[name]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,30 @@
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/instrumentation/action_mailer_subscriber'
6
+
7
+ DependencyDetection.defer do
8
+ named :action_mailer
9
+
10
+ depends_on do
11
+ !NewRelic::Agent.config[:disable_action_mailer]
12
+ end
13
+
14
+ depends_on do
15
+ defined?(ActiveSupport) &&
16
+ defined?(ActionMailer) &&
17
+ ActionMailer.respond_to?(:gem_version) &&
18
+ ActionMailer.gem_version >= Gem::Version.new('5.0') &&
19
+ !NewRelic::Agent::Instrumentation::ActionMailerSubscriber.subscribed?
20
+ end
21
+
22
+ executes do
23
+ NewRelic::Agent.logger.info('Installing ActionMailer instrumentation')
24
+ end
25
+
26
+ executes do
27
+ ActiveSupport::Notifications.subscribe(/\A(?:[^\.]+)\.action_mailer\z/,
28
+ NewRelic::Agent::Instrumentation::ActionMailerSubscriber.new)
29
+ end
30
+ end