newrelic_rpm 5.7.0.350 → 9.0.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 (476) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -1
  3. data/.rubocop.yml +1919 -0
  4. data/.rubocop_todo.yml +100 -0
  5. data/.simplecov +15 -0
  6. data/.snyk +11 -0
  7. data/.yardopts +2 -0
  8. data/Brewfile +12 -0
  9. data/CHANGELOG.md +4056 -2339
  10. data/CONTRIBUTING.md +132 -19
  11. data/DOCKER.md +167 -0
  12. data/Dockerfile +10 -0
  13. data/Gemfile +5 -2
  14. data/Guardfile +22 -4
  15. data/LICENSE +202 -38
  16. data/README.md +87 -87
  17. data/Rakefile +27 -27
  18. data/THIRD_PARTY_NOTICES.md +28 -0
  19. data/Thorfile +5 -0
  20. data/bin/newrelic +3 -2
  21. data/bin/newrelic_cmd +1 -0
  22. data/bin/nrdebug +77 -54
  23. data/config.dot +5 -5
  24. data/docker-compose.yml +107 -0
  25. data/init.rb +5 -7
  26. data/install.rb +3 -3
  27. data/lefthook.yml +9 -0
  28. data/lib/new_relic/agent/adaptive_sampler.rb +14 -10
  29. data/lib/new_relic/agent/agent.rb +125 -969
  30. data/lib/new_relic/agent/agent_helpers/connect.rb +227 -0
  31. data/lib/new_relic/agent/agent_helpers/harvest.rb +153 -0
  32. data/lib/new_relic/agent/agent_helpers/shutdown.rb +72 -0
  33. data/lib/new_relic/agent/agent_helpers/special_startup.rb +74 -0
  34. data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +167 -0
  35. data/lib/new_relic/agent/agent_helpers/startup.rb +202 -0
  36. data/lib/new_relic/agent/agent_helpers/transmit.rb +76 -0
  37. data/lib/new_relic/agent/agent_logger.rb +26 -18
  38. data/lib/new_relic/agent/attribute_filter.rb +69 -52
  39. data/lib/new_relic/agent/attribute_processing.rb +8 -8
  40. data/lib/new_relic/agent/attributes.rb +153 -0
  41. data/lib/new_relic/agent/audit_logger.rb +19 -4
  42. data/lib/new_relic/agent/autostart.rb +34 -28
  43. data/lib/new_relic/agent/chained_call.rb +2 -2
  44. data/lib/new_relic/agent/commands/agent_command.rb +4 -4
  45. data/lib/new_relic/agent/commands/agent_command_router.rb +15 -33
  46. data/lib/new_relic/agent/commands/thread_profiler_session.rb +13 -11
  47. data/lib/new_relic/agent/configuration/default_source.rb +1480 -1053
  48. data/lib/new_relic/agent/configuration/dotted_hash.rb +7 -6
  49. data/lib/new_relic/agent/configuration/environment_source.rb +15 -11
  50. data/lib/new_relic/agent/configuration/event_harvest_config.rb +68 -0
  51. data/lib/new_relic/agent/configuration/high_security_source.rb +9 -9
  52. data/lib/new_relic/agent/configuration/manager.rb +96 -79
  53. data/lib/new_relic/agent/configuration/manual_source.rb +2 -2
  54. data/lib/new_relic/agent/configuration/mask_defaults.rb +4 -4
  55. data/lib/new_relic/agent/configuration/security_policy_source.rb +83 -86
  56. data/lib/new_relic/agent/configuration/server_source.rb +49 -12
  57. data/lib/new_relic/agent/configuration/yaml_source.rb +42 -13
  58. data/lib/new_relic/agent/configuration.rb +2 -2
  59. data/lib/new_relic/agent/connect/request_builder.rb +61 -0
  60. data/lib/new_relic/agent/connect/response_handler.rb +58 -0
  61. data/lib/new_relic/agent/custom_event_aggregator.rb +15 -15
  62. data/lib/new_relic/agent/database/explain_plan_helpers.rb +5 -6
  63. data/lib/new_relic/agent/database/obfuscation_helpers.rb +16 -15
  64. data/lib/new_relic/agent/database/obfuscator.rb +3 -3
  65. data/lib/new_relic/agent/database/postgres_explain_obfuscator.rb +4 -4
  66. data/lib/new_relic/agent/database.rb +44 -53
  67. data/lib/new_relic/agent/database_adapter.rb +35 -0
  68. data/lib/new_relic/agent/datastores/metric_helper.rb +18 -20
  69. data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +9 -8
  70. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +7 -11
  71. data/lib/new_relic/agent/datastores/mongo.rb +7 -12
  72. data/lib/new_relic/agent/datastores/nosql_obfuscator.rb +41 -0
  73. data/lib/new_relic/agent/datastores/redis.rb +6 -12
  74. data/lib/new_relic/agent/datastores.rb +19 -23
  75. data/lib/new_relic/agent/deprecator.rb +2 -2
  76. data/lib/new_relic/agent/{cross_app_payload.rb → distributed_tracing/cross_app_payload.rb} +13 -12
  77. data/lib/new_relic/agent/{cross_app_tracing.rb → distributed_tracing/cross_app_tracing.rb} +87 -66
  78. data/lib/new_relic/agent/distributed_tracing/distributed_trace_attributes.rb +84 -0
  79. data/lib/new_relic/agent/distributed_tracing/distributed_trace_metrics.rb +75 -0
  80. data/lib/new_relic/agent/distributed_tracing/distributed_trace_payload.rb +163 -0
  81. data/lib/new_relic/agent/distributed_tracing/distributed_trace_transport_type.rb +38 -0
  82. data/lib/new_relic/agent/distributed_tracing/trace_context.rb +245 -0
  83. data/lib/new_relic/agent/distributed_tracing/trace_context_payload.rb +127 -0
  84. data/lib/new_relic/agent/distributed_tracing.rb +113 -32
  85. data/lib/new_relic/agent/encoding_normalizer.rb +5 -3
  86. data/lib/new_relic/agent/error_collector.rb +99 -63
  87. data/lib/new_relic/agent/error_event_aggregator.rb +10 -8
  88. data/lib/new_relic/agent/error_filter.rb +174 -0
  89. data/lib/new_relic/agent/error_trace_aggregator.rb +6 -4
  90. data/lib/new_relic/agent/event_aggregator.rb +43 -48
  91. data/lib/new_relic/agent/event_buffer.rb +8 -9
  92. data/lib/new_relic/agent/event_listener.rb +2 -3
  93. data/lib/new_relic/agent/event_loop.rb +27 -25
  94. data/lib/new_relic/agent/external.rb +20 -51
  95. data/lib/new_relic/agent/guid_generator.rb +30 -0
  96. data/lib/new_relic/agent/harvester.rb +5 -6
  97. data/lib/new_relic/agent/heap.rb +8 -10
  98. data/lib/new_relic/agent/hostname.rb +26 -5
  99. data/lib/new_relic/agent/http_clients/abstract.rb +81 -0
  100. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +26 -26
  101. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +31 -17
  102. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +18 -23
  103. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +12 -15
  104. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +24 -8
  105. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +9 -12
  106. data/lib/new_relic/agent/http_clients/uri_util.rb +12 -13
  107. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +22 -52
  108. data/lib/new_relic/agent/instrumentation/action_controller_other_subscriber.rb +39 -0
  109. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +59 -72
  110. data/lib/new_relic/agent/instrumentation/action_dispatch.rb +31 -0
  111. data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +64 -0
  112. data/lib/new_relic/agent/instrumentation/action_mailbox.rb +30 -0
  113. data/lib/new_relic/agent/instrumentation/action_mailbox_subscriber.rb +33 -0
  114. data/lib/new_relic/agent/instrumentation/action_mailer.rb +30 -0
  115. data/lib/new_relic/agent/instrumentation/action_mailer_subscriber.rb +85 -0
  116. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +86 -62
  117. data/lib/new_relic/agent/instrumentation/active_job.rb +38 -19
  118. data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +41 -0
  119. data/lib/new_relic/agent/instrumentation/active_merchant.rb +21 -7
  120. data/lib/new_relic/agent/instrumentation/active_record.rb +95 -46
  121. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +82 -61
  122. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +155 -0
  123. data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +36 -12
  124. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +69 -64
  125. data/lib/new_relic/agent/instrumentation/active_storage.rb +8 -4
  126. data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +11 -32
  127. data/lib/new_relic/agent/instrumentation/active_support.rb +27 -0
  128. data/lib/new_relic/agent/instrumentation/active_support_logger/chain.rb +23 -0
  129. data/lib/new_relic/agent/instrumentation/active_support_logger/instrumentation.rb +20 -0
  130. data/lib/new_relic/agent/instrumentation/active_support_logger/prepend.rb +12 -0
  131. data/lib/new_relic/agent/instrumentation/active_support_logger.rb +24 -0
  132. data/lib/new_relic/agent/instrumentation/active_support_subscriber.rb +41 -0
  133. data/lib/new_relic/agent/instrumentation/bunny/chain.rb +45 -0
  134. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +150 -0
  135. data/lib/new_relic/agent/instrumentation/bunny/prepend.rb +35 -0
  136. data/lib/new_relic/agent/instrumentation/bunny.rb +14 -134
  137. data/lib/new_relic/agent/instrumentation/concurrent_ruby/chain.rb +36 -0
  138. data/lib/new_relic/agent/instrumentation/concurrent_ruby/instrumentation.rb +21 -0
  139. data/lib/new_relic/agent/instrumentation/concurrent_ruby/prepend.rb +27 -0
  140. data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +31 -0
  141. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +77 -61
  142. data/lib/new_relic/agent/instrumentation/curb/chain.rb +91 -0
  143. data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +221 -0
  144. data/lib/new_relic/agent/instrumentation/curb/prepend.rb +61 -0
  145. data/lib/new_relic/agent/instrumentation/curb.rb +15 -187
  146. data/lib/new_relic/agent/instrumentation/custom_events.rb +12 -0
  147. data/lib/new_relic/agent/instrumentation/custom_events_subscriber.rb +37 -0
  148. data/lib/new_relic/agent/instrumentation/delayed_job/chain.rb +35 -0
  149. data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +48 -0
  150. data/lib/new_relic/agent/instrumentation/delayed_job/prepend.rb +33 -0
  151. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +30 -52
  152. data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +29 -0
  153. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +66 -0
  154. data/lib/new_relic/agent/instrumentation/elasticsearch/prepend.rb +13 -0
  155. data/lib/new_relic/agent/instrumentation/elasticsearch.rb +31 -0
  156. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +8 -7
  157. data/lib/new_relic/agent/instrumentation/excon.rb +29 -31
  158. data/lib/new_relic/agent/instrumentation/fiber/chain.rb +20 -0
  159. data/lib/new_relic/agent/instrumentation/fiber/instrumentation.rb +24 -0
  160. data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +18 -0
  161. data/lib/new_relic/agent/instrumentation/fiber.rb +25 -0
  162. data/lib/new_relic/agent/instrumentation/grape/chain.rb +24 -0
  163. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +100 -0
  164. data/lib/new_relic/agent/instrumentation/grape/prepend.rb +17 -0
  165. data/lib/new_relic/agent/instrumentation/grape.rb +16 -121
  166. data/lib/new_relic/agent/instrumentation/grpc/client/chain.rb +97 -0
  167. data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +89 -0
  168. data/lib/new_relic/agent/instrumentation/grpc/client/prepend.rb +111 -0
  169. data/lib/new_relic/agent/instrumentation/grpc/client/request_wrapper.rb +30 -0
  170. data/lib/new_relic/agent/instrumentation/grpc/helper.rb +32 -0
  171. data/lib/new_relic/agent/instrumentation/grpc/server/chain.rb +69 -0
  172. data/lib/new_relic/agent/instrumentation/grpc/server/instrumentation.rb +134 -0
  173. data/lib/new_relic/agent/instrumentation/grpc/server/rpc_desc_prepend.rb +35 -0
  174. data/lib/new_relic/agent/instrumentation/grpc/server/rpc_server_prepend.rb +26 -0
  175. data/lib/new_relic/agent/instrumentation/grpc_client.rb +23 -0
  176. data/lib/new_relic/agent/instrumentation/grpc_server.rb +25 -0
  177. data/lib/new_relic/agent/instrumentation/httpclient/chain.rb +24 -0
  178. data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +37 -0
  179. data/lib/new_relic/agent/instrumentation/httpclient/prepend.rb +15 -0
  180. data/lib/new_relic/agent/instrumentation/httpclient.rb +12 -32
  181. data/lib/new_relic/agent/instrumentation/httprb/chain.rb +22 -0
  182. data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +30 -0
  183. data/lib/new_relic/agent/instrumentation/httprb/prepend.rb +15 -0
  184. data/lib/new_relic/agent/instrumentation/httprb.rb +29 -0
  185. data/lib/new_relic/agent/instrumentation/ignore_actions.rb +5 -6
  186. data/lib/new_relic/agent/instrumentation/logger/chain.rb +21 -0
  187. data/lib/new_relic/agent/instrumentation/logger/instrumentation.rb +66 -0
  188. data/lib/new_relic/agent/instrumentation/logger/prepend.rb +13 -0
  189. data/lib/new_relic/agent/instrumentation/logger.rb +26 -0
  190. data/lib/new_relic/agent/instrumentation/memcache/chain.rb +15 -0
  191. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +58 -125
  192. data/lib/new_relic/agent/instrumentation/memcache/helper.rb +59 -0
  193. data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +90 -0
  194. data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +101 -0
  195. data/lib/new_relic/agent/instrumentation/memcache.rb +57 -71
  196. data/lib/new_relic/agent/instrumentation/middleware_proxy.rb +15 -14
  197. data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +21 -14
  198. data/lib/new_relic/agent/instrumentation/mongo.rb +7 -132
  199. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +49 -13
  200. data/lib/new_relic/agent/instrumentation/net_http/chain.rb +24 -0
  201. data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +40 -0
  202. data/lib/new_relic/agent/instrumentation/net_http/prepend.rb +21 -0
  203. data/lib/new_relic/agent/instrumentation/net_http.rb +44 -0
  204. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +142 -0
  205. data/lib/new_relic/agent/instrumentation/padrino/chain.rb +38 -0
  206. data/lib/new_relic/agent/instrumentation/padrino/instrumentation.rb +28 -0
  207. data/lib/new_relic/agent/instrumentation/padrino/prepend.rb +20 -0
  208. data/lib/new_relic/agent/instrumentation/padrino.rb +22 -58
  209. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +7 -7
  210. data/lib/new_relic/agent/instrumentation/queue_time.rb +9 -10
  211. data/lib/new_relic/agent/instrumentation/rack/chain.rb +66 -0
  212. data/lib/new_relic/agent/instrumentation/rack/helpers.rb +33 -0
  213. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +75 -0
  214. data/lib/new_relic/agent/instrumentation/rack/prepend.rb +43 -0
  215. data/lib/new_relic/agent/instrumentation/rack.rb +33 -141
  216. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +19 -55
  217. data/lib/new_relic/agent/instrumentation/rails_middleware.rb +5 -5
  218. data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +36 -0
  219. data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +45 -0
  220. data/lib/new_relic/agent/instrumentation/rails_notifications/action_view.rb +30 -0
  221. data/lib/new_relic/agent/instrumentation/rails_notifications/custom_events.rb +30 -0
  222. data/lib/new_relic/agent/instrumentation/rake/chain.rb +20 -0
  223. data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +142 -0
  224. data/lib/new_relic/agent/instrumentation/rake/prepend.rb +14 -0
  225. data/lib/new_relic/agent/instrumentation/rake.rb +18 -159
  226. data/lib/new_relic/agent/instrumentation/redis/chain.rb +45 -0
  227. data/lib/new_relic/agent/instrumentation/redis/constants.rb +17 -0
  228. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +93 -0
  229. data/lib/new_relic/agent/instrumentation/redis/middleware.rb +16 -0
  230. data/lib/new_relic/agent/instrumentation/redis/prepend.rb +29 -0
  231. data/lib/new_relic/agent/instrumentation/redis.rb +20 -103
  232. data/lib/new_relic/agent/instrumentation/resque/chain.rb +21 -0
  233. data/lib/new_relic/agent/instrumentation/resque/helper.rb +19 -0
  234. data/lib/new_relic/agent/instrumentation/resque/instrumentation.rb +34 -0
  235. data/lib/new_relic/agent/instrumentation/resque/prepend.rb +15 -0
  236. data/lib/new_relic/agent/instrumentation/resque.rb +33 -41
  237. data/lib/new_relic/agent/instrumentation/sequel.rb +17 -20
  238. data/lib/new_relic/agent/instrumentation/sequel_helper.rb +3 -3
  239. data/lib/new_relic/agent/instrumentation/sidekiq/client.rb +20 -0
  240. data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +30 -0
  241. data/lib/new_relic/agent/instrumentation/sidekiq/server.rb +37 -0
  242. data/lib/new_relic/agent/instrumentation/sidekiq.rb +29 -46
  243. data/lib/new_relic/agent/instrumentation/sinatra/chain.rb +55 -0
  244. data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +31 -37
  245. data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +125 -0
  246. data/lib/new_relic/agent/instrumentation/sinatra/prepend.rb +33 -0
  247. data/lib/new_relic/agent/instrumentation/sinatra/transaction_namer.rb +3 -3
  248. data/lib/new_relic/agent/instrumentation/sinatra.rb +35 -165
  249. data/lib/new_relic/agent/instrumentation/thread/chain.rb +24 -0
  250. data/lib/new_relic/agent/instrumentation/thread/instrumentation.rb +28 -0
  251. data/lib/new_relic/agent/instrumentation/thread/prepend.rb +22 -0
  252. data/lib/new_relic/agent/instrumentation/thread.rb +20 -0
  253. data/lib/new_relic/agent/instrumentation/tilt/chain.rb +24 -0
  254. data/lib/new_relic/agent/instrumentation/tilt/instrumentation.rb +41 -0
  255. data/lib/new_relic/agent/instrumentation/tilt/prepend.rb +13 -0
  256. data/lib/new_relic/agent/instrumentation/tilt.rb +25 -0
  257. data/lib/new_relic/agent/instrumentation/typhoeus/chain.rb +22 -0
  258. data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +80 -0
  259. data/lib/new_relic/agent/instrumentation/typhoeus/prepend.rb +14 -0
  260. data/lib/new_relic/agent/instrumentation/typhoeus.rb +14 -76
  261. data/lib/new_relic/agent/instrumentation.rb +2 -2
  262. data/lib/new_relic/agent/internal_agent_error.rb +3 -3
  263. data/lib/new_relic/agent/javascript_instrumentor.rb +51 -45
  264. data/lib/new_relic/agent/linking_metadata.rb +44 -0
  265. data/lib/new_relic/agent/local_log_decorator.rb +37 -0
  266. data/lib/new_relic/agent/log_event_aggregator.rb +235 -0
  267. data/lib/new_relic/agent/log_once.rb +2 -2
  268. data/lib/new_relic/agent/log_priority.rb +20 -0
  269. data/lib/new_relic/agent/logging.rb +142 -0
  270. data/lib/new_relic/agent/memory_logger.rb +3 -3
  271. data/lib/new_relic/agent/messaging.rb +81 -164
  272. data/lib/new_relic/agent/method_tracer.rb +152 -145
  273. data/lib/new_relic/agent/method_tracer_helpers.rb +90 -13
  274. data/lib/new_relic/agent/monitors/cross_app_monitor.rb +117 -0
  275. data/lib/new_relic/agent/monitors/distributed_tracing_monitor.rb +28 -0
  276. data/lib/new_relic/agent/{inbound_request_monitor.rb → monitors/inbound_request_monitor.rb} +5 -6
  277. data/lib/new_relic/agent/{synthetics_monitor.rb → monitors/synthetics_monitor.rb} +9 -15
  278. data/lib/new_relic/agent/monitors.rb +26 -0
  279. data/lib/new_relic/agent/new_relic_service/encoders.rb +7 -7
  280. data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +6 -7
  281. data/lib/new_relic/agent/new_relic_service/marshaller.rb +8 -29
  282. data/lib/new_relic/agent/new_relic_service/security_policy_settings.rb +5 -5
  283. data/lib/new_relic/agent/new_relic_service.rb +282 -166
  284. data/lib/new_relic/agent/noticeable_error.rb +19 -0
  285. data/lib/new_relic/agent/null_logger.rb +8 -4
  286. data/lib/new_relic/agent/obfuscator.rb +9 -11
  287. data/lib/new_relic/agent/parameter_filtering.rb +35 -8
  288. data/lib/new_relic/agent/payload_metric_mapping.rb +10 -11
  289. data/lib/new_relic/agent/pipe_channel_manager.rb +28 -18
  290. data/lib/new_relic/agent/pipe_service.rb +9 -6
  291. data/lib/new_relic/agent/prepend_supportability.rb +3 -3
  292. data/lib/new_relic/agent/priority_sampled_buffer.rb +16 -14
  293. data/lib/new_relic/agent/range_extensions.rb +9 -29
  294. data/lib/new_relic/agent/rules_engine/replacement_rule.rb +12 -12
  295. data/lib/new_relic/agent/rules_engine/segment_terms_rule.rb +13 -14
  296. data/lib/new_relic/agent/rules_engine.rb +6 -5
  297. data/lib/new_relic/agent/sampler.rb +4 -5
  298. data/lib/new_relic/agent/sampler_collection.rb +4 -5
  299. data/lib/new_relic/agent/samplers/cpu_sampler.rb +4 -3
  300. data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +14 -11
  301. data/lib/new_relic/agent/samplers/memory_sampler.rb +26 -15
  302. data/lib/new_relic/agent/samplers/object_sampler.rb +2 -2
  303. data/lib/new_relic/agent/samplers/vm_sampler.rb +22 -20
  304. data/lib/new_relic/agent/span_event_aggregator.rb +14 -16
  305. data/lib/new_relic/agent/span_event_primitive.rb +118 -58
  306. data/lib/new_relic/agent/sql_sampler.rb +25 -25
  307. data/lib/new_relic/agent/stats.rb +79 -42
  308. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +11 -13
  309. data/lib/new_relic/agent/stats_engine/stats_hash.rb +13 -14
  310. data/lib/new_relic/agent/stats_engine.rb +11 -11
  311. data/lib/new_relic/agent/synthetics_event_aggregator.rb +8 -9
  312. data/lib/new_relic/agent/system_info.rb +100 -66
  313. data/lib/new_relic/agent/threading/agent_thread.rb +20 -16
  314. data/lib/new_relic/agent/threading/backtrace_node.rb +13 -14
  315. data/lib/new_relic/agent/threading/backtrace_service.rb +18 -18
  316. data/lib/new_relic/agent/threading/thread_profile.rb +31 -45
  317. data/lib/new_relic/agent/timestamp_sampled_buffer.rb +2 -2
  318. data/lib/new_relic/agent/tracer.rb +513 -0
  319. data/lib/new_relic/agent/transaction/abstract_segment.rb +131 -41
  320. data/lib/new_relic/agent/transaction/datastore_segment.rb +22 -18
  321. data/lib/new_relic/agent/transaction/distributed_tracer.rb +184 -0
  322. data/lib/new_relic/agent/transaction/distributed_tracing.rb +72 -163
  323. data/lib/new_relic/agent/transaction/external_request_segment.rb +66 -63
  324. data/lib/new_relic/agent/transaction/message_broker_segment.rb +34 -46
  325. data/lib/new_relic/agent/transaction/request_attributes.rb +36 -36
  326. data/lib/new_relic/agent/transaction/segment.rb +46 -10
  327. data/lib/new_relic/agent/transaction/slowest_sample_buffer.rb +2 -4
  328. data/lib/new_relic/agent/transaction/synthetics_sample_buffer.rb +2 -2
  329. data/lib/new_relic/agent/transaction/trace.rb +21 -24
  330. data/lib/new_relic/agent/transaction/trace_builder.rb +11 -12
  331. data/lib/new_relic/agent/transaction/trace_context.rb +168 -0
  332. data/lib/new_relic/agent/transaction/trace_node.rb +31 -28
  333. data/lib/new_relic/agent/transaction/tracing.rb +15 -111
  334. data/lib/new_relic/agent/transaction/transaction_sample_buffer.rb +6 -6
  335. data/lib/new_relic/agent/transaction.rb +252 -259
  336. data/lib/new_relic/agent/transaction_error_primitive.rb +34 -37
  337. data/lib/new_relic/agent/transaction_event_aggregator.rb +13 -13
  338. data/lib/new_relic/agent/transaction_event_primitive.rb +44 -56
  339. data/lib/new_relic/agent/transaction_event_recorder.rb +17 -16
  340. data/lib/new_relic/agent/transaction_metrics.rb +11 -10
  341. data/lib/new_relic/agent/transaction_sampler.rb +7 -12
  342. data/lib/new_relic/agent/transaction_time_aggregator.rb +41 -26
  343. data/lib/new_relic/agent/utilization/aws.rb +34 -4
  344. data/lib/new_relic/agent/utilization/azure.rb +4 -4
  345. data/lib/new_relic/agent/utilization/gcp.rb +8 -8
  346. data/lib/new_relic/agent/utilization/pcf.rb +6 -5
  347. data/lib/new_relic/agent/utilization/vendor.rb +44 -29
  348. data/lib/new_relic/agent/utilization_data.rb +43 -6
  349. data/lib/new_relic/agent/vm/jruby_vm.rb +2 -2
  350. data/lib/new_relic/agent/vm/monotonic_gc_profiler.rb +3 -3
  351. data/lib/new_relic/agent/vm/mri_vm.rb +46 -19
  352. data/lib/new_relic/agent/vm/snapshot.rb +6 -6
  353. data/lib/new_relic/agent/vm.rb +2 -2
  354. data/lib/new_relic/agent/worker_loop.rb +11 -13
  355. data/lib/new_relic/agent.rb +151 -79
  356. data/lib/new_relic/cli/command.rb +21 -23
  357. data/lib/new_relic/cli/commands/deployments.rb +94 -45
  358. data/lib/new_relic/cli/commands/install.rb +24 -26
  359. data/lib/new_relic/coerce.rb +42 -15
  360. data/lib/new_relic/collection_helper.rb +51 -49
  361. data/lib/new_relic/constants.rb +39 -0
  362. data/lib/new_relic/control/class_methods.rb +11 -5
  363. data/lib/new_relic/control/frameworks/external.rb +3 -3
  364. data/lib/new_relic/control/frameworks/rails.rb +24 -18
  365. data/lib/new_relic/control/frameworks/rails3.rb +4 -5
  366. data/lib/new_relic/control/frameworks/rails4.rb +2 -2
  367. data/lib/new_relic/control/frameworks/rails_notifications.rb +14 -0
  368. data/lib/new_relic/control/frameworks/ruby.rb +4 -4
  369. data/lib/new_relic/control/frameworks/sinatra.rb +8 -2
  370. data/lib/new_relic/control/frameworks.rb +2 -2
  371. data/lib/new_relic/control/instance_methods.rb +33 -42
  372. data/lib/new_relic/control/instrumentation.rb +40 -12
  373. data/lib/new_relic/control/private_instance_methods.rb +48 -0
  374. data/lib/new_relic/control/server_methods.rb +4 -5
  375. data/lib/new_relic/control.rb +2 -3
  376. data/lib/new_relic/delayed_job_injection.rb +2 -2
  377. data/lib/new_relic/dependency_detection.rb +129 -18
  378. data/lib/new_relic/environment_report.rb +41 -35
  379. data/lib/new_relic/helper.rb +49 -8
  380. data/lib/new_relic/language_support.rb +30 -6
  381. data/lib/new_relic/latest_changes.rb +9 -8
  382. data/lib/new_relic/local_environment.rb +23 -27
  383. data/lib/new_relic/metric_data.rb +32 -27
  384. data/lib/new_relic/metric_spec.rb +9 -7
  385. data/lib/new_relic/noticed_error.rb +46 -33
  386. data/lib/new_relic/rack/agent_hooks.rb +2 -2
  387. data/lib/new_relic/rack/agent_middleware.rb +7 -5
  388. data/lib/new_relic/rack/browser_monitoring.rb +134 -117
  389. data/lib/new_relic/rack.rb +2 -2
  390. data/lib/new_relic/recipes/capistrano3.rb +4 -62
  391. data/lib/new_relic/recipes/capistrano_legacy.rb +24 -27
  392. data/lib/new_relic/recipes/helpers/send_deployment.rb +70 -0
  393. data/lib/new_relic/recipes.rb +2 -2
  394. data/lib/new_relic/supportability_helper.rb +21 -7
  395. data/lib/new_relic/traced_thread.rb +39 -0
  396. data/lib/new_relic/version.rb +7 -18
  397. data/lib/newrelic_rpm.rb +20 -33
  398. data/lib/sequel/extensions/{newrelic_instrumentation.rb → new_relic_instrumentation.rb} +16 -19
  399. data/lib/sequel/plugins/{newrelic_instrumentation.rb → new_relic_instrumentation.rb} +9 -15
  400. data/lib/tasks/all.rb +4 -4
  401. data/lib/tasks/config.rake +22 -118
  402. data/lib/tasks/coverage_report.rake +28 -0
  403. data/lib/tasks/helpers/config.html.erb +21 -0
  404. data/lib/tasks/helpers/format.rb +123 -0
  405. data/lib/tasks/helpers/matches.rb +12 -0
  406. data/lib/tasks/helpers/prompt.rb +24 -0
  407. data/lib/tasks/helpers/removers.rb +33 -0
  408. data/lib/tasks/install.rake +4 -0
  409. data/lib/tasks/instrumentation_generator/README.md +63 -0
  410. data/lib/tasks/instrumentation_generator/TODO.md +33 -0
  411. data/lib/tasks/instrumentation_generator/instrumentation.thor +121 -0
  412. data/lib/tasks/instrumentation_generator/templates/Envfile.tt +9 -0
  413. data/lib/tasks/instrumentation_generator/templates/chain.tt +22 -0
  414. data/lib/tasks/instrumentation_generator/templates/chain_method.tt +8 -0
  415. data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +29 -0
  416. data/lib/tasks/instrumentation_generator/templates/instrumentation.tt +13 -0
  417. data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +3 -0
  418. data/lib/tasks/instrumentation_generator/templates/newrelic.yml.tt +19 -0
  419. data/lib/tasks/instrumentation_generator/templates/prepend.tt +13 -0
  420. data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +3 -0
  421. data/lib/tasks/instrumentation_generator/templates/test.tt +15 -0
  422. data/lib/tasks/multiverse.rake +4 -0
  423. data/lib/tasks/multiverse.rb +12 -5
  424. data/lib/tasks/newrelic.rb +2 -2
  425. data/lib/tasks/tests.rake +14 -14
  426. data/newrelic.yml +672 -3
  427. data/newrelic_rpm.gemspec +40 -31
  428. data/recipes/newrelic.rb +3 -3
  429. data/test/agent_helper.rb +419 -98
  430. metadata +238 -127
  431. data/.travis.yml +0 -228
  432. data/bin/mongrel_rpm +0 -33
  433. data/cert/cacert.pem +0 -1177
  434. data/lib/new_relic/agent/commands/xray_session.rb +0 -55
  435. data/lib/new_relic/agent/commands/xray_session_collection.rb +0 -161
  436. data/lib/new_relic/agent/cross_app_monitor.rb +0 -110
  437. data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +0 -44
  438. data/lib/new_relic/agent/datastores/mongo/statement_formatter.rb +0 -53
  439. data/lib/new_relic/agent/distributed_trace_monitor.rb +0 -41
  440. data/lib/new_relic/agent/distributed_trace_payload.rb +0 -246
  441. data/lib/new_relic/agent/http_clients/abstract_request.rb +0 -31
  442. data/lib/new_relic/agent/instrumentation/active_record_4.rb +0 -42
  443. data/lib/new_relic/agent/instrumentation/active_record_5.rb +0 -41
  444. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +0 -74
  445. data/lib/new_relic/agent/instrumentation/authlogic.rb +0 -25
  446. data/lib/new_relic/agent/instrumentation/data_mapper.rb +0 -202
  447. data/lib/new_relic/agent/instrumentation/evented_subscriber.rb +0 -104
  448. data/lib/new_relic/agent/instrumentation/excon/connection.rb +0 -46
  449. data/lib/new_relic/agent/instrumentation/http.rb +0 -46
  450. data/lib/new_relic/agent/instrumentation/merb/controller.rb +0 -44
  451. data/lib/new_relic/agent/instrumentation/merb/errors.rb +0 -33
  452. data/lib/new_relic/agent/instrumentation/net.rb +0 -50
  453. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +0 -125
  454. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +0 -46
  455. data/lib/new_relic/agent/instrumentation/rails4/action_controller.rb +0 -32
  456. data/lib/new_relic/agent/instrumentation/rails4/action_view.rb +0 -27
  457. data/lib/new_relic/agent/instrumentation/rails5/action_cable.rb +0 -36
  458. data/lib/new_relic/agent/instrumentation/rails5/action_controller.rb +0 -33
  459. data/lib/new_relic/agent/instrumentation/rails5/action_view.rb +0 -27
  460. data/lib/new_relic/agent/instrumentation/rainbows_instrumentation.rb +0 -26
  461. data/lib/new_relic/agent/instrumentation/sunspot.rb +0 -33
  462. data/lib/new_relic/agent/supported_versions.rb +0 -275
  463. data/lib/new_relic/agent/transaction/attributes.rb +0 -154
  464. data/lib/new_relic/agent/transaction/xray_sample_buffer.rb +0 -64
  465. data/lib/new_relic/agent/transaction_state.rb +0 -186
  466. data/lib/new_relic/build.rb +0 -2
  467. data/lib/new_relic/control/frameworks/merb.rb +0 -29
  468. data/lib/new_relic/control/frameworks/rails5.rb +0 -14
  469. data/lib/new_relic/metrics.rb +0 -13
  470. data/lib/tasks/config.html.erb +0 -32
  471. data/lib/tasks/versions.html.erb +0 -28
  472. data/lib/tasks/versions.postface.html +0 -8
  473. data/lib/tasks/versions.preface.html +0 -9
  474. data/lib/tasks/versions.rake +0 -65
  475. data/lib/tasks/versions.txt.erb +0 -14
  476. /data/lib/tasks/{config.text.erb → helpers/config.text.erb} +0 -0
@@ -1,22 +1,16 @@
1
- # encoding: utf-8
2
1
  # This file is distributed under New Relic's license terms.
3
- # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
4
 
5
- require 'new_relic/agent/http_clients/abstract_request'
5
+ require_relative 'abstract'
6
6
 
7
7
  module NewRelic
8
8
  module Agent
9
9
  module HTTPClients
10
- class HTTPClientResponse
11
- attr_reader :response
12
-
13
- def initialize(response)
14
- @response = response
15
- end
16
-
10
+ class HTTPClientResponse < AbstractResponse
17
11
  def [](key)
18
- response.headers.each do |k,v|
19
- if key.downcase == k.downcase
12
+ @wrapped_response.headers.each do |k, v|
13
+ if key.casecmp(k) == 0
20
14
  return v
21
15
  end
22
16
  end
@@ -24,12 +18,12 @@ module NewRelic
24
18
  end
25
19
 
26
20
  def to_hash
27
- response.headers
21
+ @wrapped_response.headers
28
22
  end
29
23
  end
30
24
 
31
25
  class HTTPClientRequest < AbstractRequest
32
- attr_reader :request, :uri
26
+ attr_reader :request
33
27
 
34
28
  HTTP_CLIENT = "HTTPClient".freeze
35
29
  LHOST = 'host'.freeze
@@ -38,7 +32,6 @@ module NewRelic
38
32
 
39
33
  def initialize(request)
40
34
  @request = request
41
- @uri = request.header.request_uri
42
35
  end
43
36
 
44
37
  def type
@@ -59,6 +52,10 @@ module NewRelic
59
52
  host_from_header || uri.host.to_s
60
53
  end
61
54
 
55
+ def uri
56
+ @uri ||= URIUtil.parse_and_normalize_url(request.header.request_uri)
57
+ end
58
+
62
59
  def [](key)
63
60
  request.headers[key]
64
61
  end
@@ -1,26 +1,37 @@
1
- # encoding: utf-8
2
1
  # This file is distributed under New Relic's license terms.
3
- # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
4
 
5
- require 'new_relic/agent/http_clients/abstract_request'
5
+ require_relative 'abstract'
6
+ require 'resolv'
6
7
 
7
8
  module NewRelic
8
9
  module Agent
9
10
  module HTTPClients
11
+ class NetHTTPResponse < AbstractResponse
12
+ def [](key)
13
+ @wrapped_response[key]
14
+ end
15
+
16
+ def to_hash
17
+ @wrapped_response.to_hash
18
+ end
19
+ end
20
+
10
21
  class NetHTTPRequest < AbstractRequest
11
22
  def initialize(connection, request)
12
23
  @connection = connection
13
24
  @request = request
14
25
  end
15
26
 
16
- NET_HTTP = 'Net::HTTP'.freeze
27
+ NET_HTTP = 'Net::HTTP'
17
28
 
18
29
  def type
19
30
  NET_HTTP
20
31
  end
21
32
 
22
- HOST = 'host'.freeze
23
- COLON = ':'.freeze
33
+ HOST = 'host'
34
+ COLON = ':'
24
35
 
25
36
  def host_from_header
26
37
  if hostname = self[HOST]
@@ -49,10 +60,15 @@ module NewRelic
49
60
  when /^https?:\/\//
50
61
  ::NewRelic::Agent::HTTPClients::URIUtil.parse_and_normalize_url(@request.path)
51
62
  else
63
+ connection_address = @connection.address
64
+ if connection_address =~ Resolv::IPv6::Regex
65
+ connection_address = "[#{connection_address}]"
66
+ end
67
+
52
68
  scheme = @connection.use_ssl? ? 'https' : 'http'
53
69
  ::NewRelic::Agent::HTTPClients::URIUtil.parse_and_normalize_url(
54
- "#{scheme}://#{@connection.address}:#{@connection.port}#{@request.path}"
55
- )
70
+ "#{scheme}://#{connection_address}:#{@connection.port}#{@request.path}"
71
+ )
56
72
  end
57
73
  end
58
74
  end
@@ -1,30 +1,26 @@
1
- # encoding: utf-8
2
1
  # This file is distributed under New Relic's license terms.
3
- # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
4
 
5
- require 'new_relic/agent/http_clients/abstract_request'
5
+ require_relative 'abstract'
6
6
 
7
7
  module NewRelic
8
8
  module Agent
9
9
  module HTTPClients
10
- class TyphoeusHTTPResponse
11
- def initialize(response)
12
- @response = response
13
- end
14
-
10
+ class TyphoeusHTTPResponse < AbstractResponse
15
11
  def [](key)
16
12
  unless headers.nil?
17
13
  result = headers[key]
18
14
 
19
15
  # Typhoeus 0.5.3 has a bug where asking the headers hash for a
20
- # non-existent header will return the hash itself, not what we want.
16
+ # nonexistent header will return the hash itself, not what we want.
21
17
  result == headers ? nil : result
22
18
  end
23
19
  end
24
20
 
25
21
  def to_hash
26
22
  hash = {}
27
- headers.each do |(k,v)|
23
+ headers.each do |(k, v)|
28
24
  hash[k] = v
29
25
  end
30
26
  hash
@@ -33,7 +29,7 @@ module NewRelic
33
29
  private
34
30
 
35
31
  def headers
36
- @response.headers
32
+ @wrapped_response.headers
37
33
  end
38
34
  end
39
35
 
@@ -43,7 +39,7 @@ module NewRelic
43
39
  @uri = case request.url
44
40
  when ::URI then request.url
45
41
  else NewRelic::Agent::HTTPClients::URIUtil.parse_and_normalize_url(request.url)
46
- end
42
+ end
47
43
  end
48
44
 
49
45
  TYPHOEUS = "Typhoeus".freeze
@@ -71,6 +67,7 @@ module NewRelic
71
67
 
72
68
  def [](key)
73
69
  return nil unless @request.options && @request.options[:headers]
70
+
74
71
  @request.options[:headers][key]
75
72
  end
76
73
 
@@ -1,7 +1,7 @@
1
1
  # -*- ruby -*-
2
- # encoding: utf-8
3
2
  # This file is distributed under New Relic's license terms.
4
- # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
3
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+ # frozen_string_literal: true
5
5
 
6
6
  # This module includes utilities for manipulating URIs, particularly from the
7
7
  # context of Net::HTTP requests. We don't always have direct access to the full
@@ -13,21 +13,20 @@ module NewRelic
13
13
  module Agent
14
14
  module HTTPClients
15
15
  module URIUtil
16
-
17
- def self.filter_uri(original)
18
- filtered = original.dup
19
- filtered.user = nil
20
- filtered.password = nil
21
- filtered.query = nil
22
- filtered.fragment = nil
23
- filtered.to_s
16
+ def self.obfuscated_uri(url)
17
+ parse_and_normalize_url(url).tap do |obfuscated|
18
+ obfuscated.user = nil
19
+ obfuscated.password = nil
20
+ obfuscated.query = nil
21
+ obfuscated.fragment = nil
22
+ end
24
23
  end
25
24
 
26
25
  # There are valid URI strings that some HTTP client libraries will
27
26
  # accept that the stdlib URI module doesn't handle. If we find that
28
27
  # Addressable is around, use that to normalize out our URL's.
29
28
  def self.parse_and_normalize_url(url)
30
- uri = url
29
+ uri = url.dup
31
30
  unless ::URI === uri
32
31
  if defined?(::Addressable::URI)
33
32
  address = ::Addressable::URI.parse(url)
@@ -41,10 +40,10 @@ module NewRelic
41
40
  uri
42
41
  end
43
42
 
44
- QUESTION_MARK = "?".freeze
43
+ QUESTION_MARK = "?"
45
44
 
46
45
  def self.strip_query_string(fragment)
47
- if(fragment.include?(QUESTION_MARK))
46
+ if fragment.include?(QUESTION_MARK)
48
47
  fragment.split(QUESTION_MARK).first
49
48
  else
50
49
  fragment
@@ -1,75 +1,45 @@
1
- # encoding: utf-8
2
1
  # This file is distributed under New Relic's license terms.
3
- # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
- require 'new_relic/agent/instrumentation/evented_subscriber'
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'
5
6
 
6
7
  module NewRelic
7
8
  module Agent
8
9
  module Instrumentation
9
- class ActionCableSubscriber < EventedSubscriber
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
- event = super
16
- if event.name == PERFORM_ACTION
17
- start_transaction event
13
+ def start_segment(name, id, payload) # THREAD_LOCAL_ACCESS
14
+ finishable = if name == PERFORM_ACTION
15
+ Tracer.start_transaction_or_segment(
16
+ name: transaction_name_from_payload(payload),
17
+ category: :action_cable
18
+ )
18
19
  else
19
- start_recording_metrics event
20
+ Tracer.start_segment(name: metric_name_from_payload(name, payload))
20
21
  end
21
- rescue => e
22
- log_notification_error e, name, 'start'
23
- end
24
-
25
- def finish name, id, payload #THREAD_LOCAL_ACCESS
26
- return unless state.is_execution_traced?
27
- event = super
28
- notice_error payload if payload.key? :exception
29
- if event.name == PERFORM_ACTION
30
- finish_transaction
31
- else
32
- stop_recording_metrics event
33
- end
34
- rescue => e
35
- log_notification_error e, name, 'finish'
22
+ push_segment(id, finishable)
36
23
  end
37
24
 
38
25
  private
39
26
 
40
- def start_transaction event
41
- Transaction.start(state, :action_cable, :transaction_name => transaction_name_from_event(event))
42
- end
43
-
44
- def finish_transaction
45
- Transaction.stop(state)
46
- end
47
-
48
- def start_recording_metrics event
49
- event.payload[:segment] = Transaction.start_segment name: metric_name_from_event(event)
27
+ def transaction_name_from_payload(payload)
28
+ "Controller/ActionCable/#{payload[:channel_class]}/#{payload[:action]}"
50
29
  end
51
30
 
52
- def stop_recording_metrics event
53
- event.payload[:segment].finish if event.payload[:segment]
31
+ def metric_name_from_payload(name, payload)
32
+ "Ruby/ActionCable/#{metric_name(payload)}/#{action_name(name)}"
54
33
  end
55
34
 
56
- def transaction_name_from_event event
57
- "Controller/ActionCable/#{event.payload[:channel_class]}/#{event.payload[:action]}"
35
+ def metric_name(payload)
36
+ payload[:broadcasting] || payload[:channel_class]
58
37
  end
59
38
 
60
- def metric_name_from_event event
61
- "Ruby/ActionCable/#{event.payload[:channel_class]}/#{action_name_from_event(event)}"
62
- end
63
-
64
- DOT_ACTION_CABLE = ".action_cable".freeze
65
- EMPTY_STRING = "".freeze
66
-
67
- def action_name_from_event event
68
- event.name.gsub DOT_ACTION_CABLE, EMPTY_STRING
69
- end
39
+ DOT_ACTION_CABLE = '.action_cable'.freeze
70
40
 
71
- def notice_error payload
72
- NewRelic::Agent.notice_error payload[:exception_object]
41
+ def action_name(name)
42
+ name.gsub(DOT_ACTION_CABLE, NewRelic::EMPTY_STR)
73
43
  end
74
44
  end
75
45
  end
@@ -0,0 +1,39 @@
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
+ # redirect_to
31
+ return payload[:request].controller_class.controller_path if payload[:request] && payload[:request].controller_class
32
+
33
+ # unpermitted_parameters
34
+ ::NewRelic::LanguageSupport.constantize(payload[:context][:controller]).controller_path if payload[:context] && payload[:context][:controller]
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,24 +1,21 @@
1
- # encoding: utf-8
2
1
  # This file is distributed under New Relic's license terms.
3
- # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
- require 'new_relic/agent/instrumentation/evented_subscriber'
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'
5
6
  require 'new_relic/agent/instrumentation/ignore_actions'
6
7
  require 'new_relic/agent/parameter_filtering'
7
8
 
8
9
  module NewRelic
9
10
  module Agent
10
11
  module Instrumentation
11
- class ActionControllerSubscriber < EventedSubscriber
12
-
13
- def start(name, id, payload) #THREAD_LOCAL_ACCESS
14
- # @req is a historically stable but not guaranteed Rails header property
15
- request = payload[:headers].instance_variable_get(:@req)
12
+ class ActionControllerSubscriber < NotificationsSubscriber
13
+ def start(name, id, payload) # THREAD_LOCAL_ACCESS
14
+ controller_class = controller_class(payload)
16
15
 
17
- event = ControllerEvent.new(name, Time.now, nil, id, payload, request)
18
- push_event(event)
19
-
20
- if state.is_execution_traced? && !event.ignored?
21
- start_transaction(event)
16
+ if state.is_execution_traced? && !should_ignore(payload, controller_class)
17
+ finishable = start_transaction_or_segment(payload, request_for_payload(payload), controller_class)
18
+ push_segment(id, finishable)
22
19
  else
23
20
  # if this transaction is ignored, make sure child
24
21
  # transaction are also ignored
@@ -29,12 +26,17 @@ module NewRelic
29
26
  log_notification_error(e, name, 'start')
30
27
  end
31
28
 
32
- def finish(name, id, payload) #THREAD_LOCAL_ACCESS
33
- event = pop_event(id)
34
- event.payload.merge!(payload)
29
+ def finish(name, id, payload) # THREAD_LOCAL_ACCESS
30
+ finishable = pop_segment(id)
31
+
32
+ if state.is_execution_traced? \
33
+ && !should_ignore(payload, controller_class(payload))
34
+
35
+ if exception = exception_object(payload)
36
+ finishable.notice_error(exception)
37
+ end
35
38
 
36
- if state.is_execution_traced? && !event.ignored?
37
- stop_transaction(event)
39
+ finishable.finish
38
40
  else
39
41
  Agent.instance.pop_trace_execution_flag
40
42
  end
@@ -42,77 +44,62 @@ module NewRelic
42
44
  log_notification_error(e, name, 'finish')
43
45
  end
44
46
 
45
- def start_transaction(event)
46
- Transaction.start(state, :controller,
47
- :request => event.request,
48
- :filtered_params => filter(event.payload[:params]),
49
- :apdex_start_time => event.queue_start,
50
- :transaction_name => event.metric_name,
51
- :ignore_apdex => event.apdex_ignored?,
52
- :ignore_enduser => event.enduser_ignored?)
47
+ def start_transaction_or_segment(payload, request, controller_class)
48
+ Tracer.start_transaction_or_segment(
49
+ name: format_metric_name(payload[:action], controller_class),
50
+ category: :controller,
51
+ options: tracer_options(payload, request, controller_class)
52
+ )
53
53
  end
54
54
 
55
- def stop_transaction(event)
56
- Transaction.stop(state)
57
- end
58
-
59
- def filter(params)
60
- munged_params = NewRelic::Agent::ParameterFiltering.filter_rails_request_parameters(params)
61
- filters = Rails.application.config.filter_parameters
62
- ActionDispatch::Http::ParameterFilter.new(filters).filter(munged_params)
63
- end
64
- end
65
-
66
- class ControllerEvent < Event
67
- attr_accessor :parent
68
- attr_reader :queue_start, :request
69
-
70
- def initialize(name, start, ending, transaction_id, payload, request)
71
- # We have a different initialize parameter list, so be explicit
72
- super(name, start, ending, transaction_id, payload)
73
-
74
- @request = request
75
- @controller_class = payload[:controller].split('::') \
76
- .inject(Object){|m,o| m.const_get(o)}
77
-
78
- if request && request.respond_to?(:env)
79
- @queue_start = QueueTime.parse_frontend_timestamp(request.env, self.time)
80
- end
55
+ def tracer_options(payload, request, controller_class)
56
+ {
57
+ request: request,
58
+ filtered_params: filtered_params(payload[:params]),
59
+ apdex_start_time: queue_start(request),
60
+ ignore_apdex: ignore?(payload[:action], ControllerInstrumentation::NR_IGNORE_APDEX_KEY, controller_class),
61
+ ignore_enduser: ignore?(payload[:action],
62
+ ControllerInstrumentation::NR_IGNORE_ENDUSER_KEY,
63
+ controller_class)
64
+ }.merge(NewRelic::Agent::MethodTracerHelpers.code_information(controller_class, payload[:action]))
81
65
  end
82
66
 
83
- def metric_name
84
- @metric_name || "Controller/#{metric_path}/#{metric_action}"
67
+ def filtered_params(params)
68
+ NewRelic::Agent::ParameterFiltering.filter_using_rails(params, Rails.application.config.filter_parameters)
85
69
  end
86
70
 
87
- def metric_path
88
- @controller_class.controller_path
71
+ def ignore?(action, key, controller_class)
72
+ NewRelic::Agent::Instrumentation::IgnoreActions.is_filtered?(key, controller_class, action)
89
73
  end
90
74
 
91
- def metric_action
92
- payload[:action]
75
+ def format_metric_name(metric_action, controller)
76
+ controller_class = controller.is_a?(Class) ? controller : Object.const_get(controller)
77
+ "Controller/#{controller_class.controller_path}/#{metric_action}"
93
78
  end
94
79
 
95
- def ignored?
96
- _is_filtered?(ControllerInstrumentation::NR_DO_NOT_TRACE_KEY)
80
+ def controller_class(payload)
81
+ ::NewRelic::LanguageSupport.constantize(payload[:controller])
97
82
  end
98
83
 
99
- def apdex_ignored?
100
- _is_filtered?(ControllerInstrumentation::NR_IGNORE_APDEX_KEY)
84
+ def should_ignore(payload, controller_class)
85
+ NewRelic::Agent::Instrumentation::IgnoreActions.is_filtered?(
86
+ ControllerInstrumentation::NR_DO_NOT_TRACE_KEY,
87
+ controller_class,
88
+ payload[:action]
89
+ )
101
90
  end
102
91
 
103
- def enduser_ignored?
104
- _is_filtered?(ControllerInstrumentation::NR_IGNORE_ENDUSER_KEY)
92
+ def queue_start(request)
93
+ if request && request.respond_to?(:env)
94
+ QueueTime.parse_frontend_timestamp(request.env, Process.clock_gettime(Process::CLOCK_REALTIME))
95
+ end
105
96
  end
106
97
 
107
- def _is_filtered?(key)
108
- NewRelic::Agent::Instrumentation::IgnoreActions.is_filtered?(
109
- key,
110
- @controller_class,
111
- metric_action)
112
- end
98
+ def request_for_payload(payload)
99
+ # @req is a historically stable but not guaranteed Rails header property
100
+ return unless payload[:headers].instance_variables.include?(:@req)
113
101
 
114
- def to_s
115
- "#<NewRelic::Agent::Instrumentation::ControllerEvent:#{object_id} name: \"#{name}\" id: #{transaction_id} payload: #{payload}}>"
102
+ payload[:headers].instance_variable_get(:@req)
116
103
  end
117
104
  end
118
105
  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