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,39 +1,67 @@
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/distributed_trace_payload'
5
+ require 'new_relic/agent/distributed_tracing/distributed_trace_payload'
6
+ require 'new_relic/agent/distributed_tracing/distributed_trace_attributes'
7
+ require 'new_relic/agent/distributed_tracing/distributed_trace_metrics'
6
8
 
7
9
  module NewRelic
8
10
  module Agent
9
11
  class Transaction
10
12
  module DistributedTracing
11
13
  attr_accessor :distributed_trace_payload
14
+ attr_writer :distributed_trace_payload_created
15
+
16
+ SUPPORTABILITY_DISTRIBUTED_TRACE = "Supportability/DistributedTrace"
17
+ CREATE_PREFIX = "#{SUPPORTABILITY_DISTRIBUTED_TRACE}/CreatePayload"
18
+ ACCEPT_PREFIX = "#{SUPPORTABILITY_DISTRIBUTED_TRACE}/AcceptPayload"
19
+ IGNORE_PREFIX = "#{ACCEPT_PREFIX}/Ignored"
20
+
21
+ CREATE_SUCCESS_METRIC = "#{CREATE_PREFIX}/Success"
22
+ CREATE_EXCEPTION_METRIC = "#{CREATE_PREFIX}/Exception"
23
+ ACCEPT_SUCCESS_METRIC = "#{ACCEPT_PREFIX}/Success"
24
+ ACCEPT_EXCEPTION_METRIC = "#{ACCEPT_PREFIX}/Exception"
25
+ ACCEPT_PARSE_EXCEPTION_METRIC = "#{ACCEPT_PREFIX}/ParseException"
26
+
27
+ IGNORE_ACCEPT_AFTER_CREATE_METRIC = "#{IGNORE_PREFIX}/CreateBeforeAccept"
28
+ IGNORE_MULTIPLE_ACCEPT_METRIC = "#{IGNORE_PREFIX}/Multiple"
29
+ IGNORE_ACCEPT_NULL_METRIC = "#{IGNORE_PREFIX}/Null"
30
+ IGNORE_ACCEPT_MAJOR_VERSION_METRIC = "#{IGNORE_PREFIX}/MajorVersion"
31
+ IGNORE_ACCEPT_UNTRUSTED_ACCOUNT_METRIC = "#{IGNORE_PREFIX}/UntrustedAccount"
32
+
33
+ LBRACE = "{"
34
+ NULL_PAYLOAD = 'null'
12
35
 
13
- def distributed_trace?
14
- !!distributed_trace_payload
36
+ NEWRELIC_TRACE_KEY = "HTTP_NEWRELIC"
37
+
38
+ def accept_distributed_tracing_incoming_request(request)
39
+ return unless Agent.config[:'distributed_tracing.enabled']
40
+ return unless payload = request[NEWRELIC_TRACE_KEY]
41
+
42
+ accept_distributed_trace_payload(payload)
15
43
  end
16
44
 
17
- SUPPORTABILITY_CREATE_PAYLOAD_SUCCESS = "Supportability/DistributedTrace/CreatePayload/Success".freeze
18
- SUPPORTABILITY_CREATE_PAYLOAD_EXCEPTION = "Supportability/DistributedTrace/CreatePayload/Exception".freeze
45
+ def distributed_trace_payload_created?
46
+ @distributed_trace_payload_created ||= false
47
+ end
19
48
 
20
49
  def create_distributed_trace_payload
21
50
  return unless Agent.config[:'distributed_tracing.enabled']
22
- self.distributed_trace_payload_created = true
23
- payload = DistributedTracePayload.for_transaction self
24
- NewRelic::Agent.increment_metric SUPPORTABILITY_CREATE_PAYLOAD_SUCCESS
51
+
52
+ @distributed_trace_payload_created = true
53
+ payload = DistributedTracePayload.for_transaction(transaction)
54
+ NewRelic::Agent.increment_metric(CREATE_SUCCESS_METRIC)
25
55
  payload
26
56
  rescue => e
27
- NewRelic::Agent.increment_metric SUPPORTABILITY_CREATE_PAYLOAD_EXCEPTION
28
- NewRelic::Agent.logger.warn "Failed to create distributed trace payload", e
57
+ NewRelic::Agent.increment_metric(CREATE_EXCEPTION_METRIC)
58
+ NewRelic::Agent.logger.warn("Failed to create distributed trace payload", e)
29
59
  nil
30
60
  end
31
61
 
32
- SUPPORTABILITY_ACCEPT_PAYLOAD_SUCCESS = "Supportability/DistributedTrace/AcceptPayload/Success".freeze
33
- SUPPORTABILITY_ACCEPT_PAYLOAD_EXCEPTION = "Supportability/DistributedTrace/AcceptPayload/Exception".freeze
34
-
35
- def accept_distributed_trace_payload payload
62
+ def accept_distributed_trace_payload(payload)
36
63
  return unless Agent.config[:'distributed_tracing.enabled']
64
+
37
65
  return false if check_payload_ignored(payload)
38
66
  return false unless check_payload_present(payload)
39
67
  return false unless payload = decode_payload(payload)
@@ -43,221 +71,102 @@ module NewRelic
43
71
 
44
72
  assign_payload_and_sampling_params(payload)
45
73
 
46
- NewRelic::Agent.increment_metric SUPPORTABILITY_ACCEPT_PAYLOAD_SUCCESS
74
+ NewRelic::Agent.increment_metric(ACCEPT_SUCCESS_METRIC)
47
75
  true
48
76
  rescue => e
49
- NewRelic::Agent.increment_metric SUPPORTABILITY_ACCEPT_PAYLOAD_EXCEPTION
50
- NewRelic::Agent.logger.warn "Failed to accept distributed trace payload", e
77
+ NewRelic::Agent.increment_metric(ACCEPT_EXCEPTION_METRIC)
78
+ NewRelic::Agent.logger.warn("Failed to accept distributed trace payload", e)
51
79
  false
52
80
  end
53
81
 
54
- def trace_id
55
- if distributed_trace_payload
56
- distributed_trace_payload.trace_id
57
- else
58
- guid
59
- end
60
- end
61
-
62
- def parent_id
63
- # The payload comes from our parent transaction, so its ID
64
- # is our parent ID.
65
- #
66
- distributed_trace_payload && distributed_trace_payload.transaction_id
67
- end
68
-
69
- def distributed_trace_payload_created?
70
- @distributed_trace_payload_created ||= false
71
- end
72
-
73
- attr_writer :distributed_trace_payload_created
74
-
75
- def append_distributed_trace_info transaction_payload
76
- return unless Agent.config[:'distributed_tracing.enabled']
77
- if distributed_trace_payload
78
- distributed_trace_payload.assign_intrinsics self, transaction_payload
79
- else
80
- DistributedTracePayload.assign_initial_intrinsics self, transaction_payload
81
- end
82
- end
83
-
84
- def assign_distributed_trace_intrinsics
85
- return unless Agent.config[:'distributed_tracing.enabled']
86
- DistributedTracePayload::INTRINSIC_KEYS.each do |key|
87
- next unless @payload.key? key
88
- attributes.add_intrinsic_attribute key, @payload[key]
89
- end
90
- nil
91
- end
92
-
93
- # This method returns transport_duration in seconds. Transport duration
94
- # is stored in milliseconds on the payload, but it's needed in seconds
95
- # for metrics and intrinsics.
96
- def transport_duration
97
- return unless distributed_trace_payload
98
- duration = (start_time.to_f * 1000 - distributed_trace_payload.timestamp) / 1000
99
- duration < 0 ? 0 : duration
100
- end
101
-
102
82
  private
103
83
 
104
- SUPPORTABILITY_CREATE_BEFORE_ACCEPT_PAYLOAD = "Supportability/DistributedTrace/AcceptPayload/Ignored/CreateBeforeAccept".freeze
105
- SUPPORTABILITY_MULTIPLE_ACCEPT_PAYLOAD = "Supportability/DistributedTrace/AcceptPayload/Ignored/Multiple".freeze
106
- SUPPORTABILITY_PAYLOAD_ACCEPT_IGNORED_NULL = "Supportability/DistributedTrace/AcceptPayload/Ignored/Null".freeze
107
- SUPPORTABILITY_PAYLOAD_ACCEPT_IGNORED_BROWSER = "Supportability/DistributedTrace/AcceptPayload/Ignored/BrowserAgentInjected".freeze
108
-
109
84
  def check_payload_ignored(payload)
110
85
  if distributed_trace_payload
111
- NewRelic::Agent.increment_metric SUPPORTABILITY_MULTIPLE_ACCEPT_PAYLOAD
86
+ NewRelic::Agent.increment_metric(IGNORE_MULTIPLE_ACCEPT_METRIC)
112
87
  return true
113
88
  elsif distributed_trace_payload_created?
114
- NewRelic::Agent.increment_metric SUPPORTABILITY_CREATE_BEFORE_ACCEPT_PAYLOAD
89
+ NewRelic::Agent.increment_metric(IGNORE_ACCEPT_AFTER_CREATE_METRIC)
115
90
  return true
116
91
  end
117
92
  false
118
93
  end
119
94
 
120
- NULL_PAYLOAD = 'null'.freeze
121
-
122
95
  def check_payload_present(payload)
123
96
  # We might be passed a Ruby `nil` object _or_ the JSON "null"
124
97
  if payload.nil? || payload == NULL_PAYLOAD
125
- NewRelic::Agent.increment_metric SUPPORTABILITY_PAYLOAD_ACCEPT_IGNORED_NULL
98
+ NewRelic::Agent.increment_metric(IGNORE_ACCEPT_NULL_METRIC)
126
99
  return nil
127
100
  end
128
101
 
129
102
  payload
130
103
  end
131
104
 
132
- SUPPORTABILITY_PAYLOAD_ACCEPT_IGNORED_PARSE_EXCEPTION = "Supportability/DistributedTrace/AcceptPayload/ParseException".freeze
133
- LBRACE = "{".freeze
134
-
135
105
  def decode_payload(payload)
136
- decoded = if payload.start_with? LBRACE
137
- DistributedTracePayload.from_json payload
106
+ decoded = if payload.start_with?(LBRACE)
107
+ DistributedTracePayload.from_json(payload)
138
108
  else
139
- DistributedTracePayload.from_http_safe payload
109
+ DistributedTracePayload.from_http_safe(payload)
140
110
  end
141
111
 
142
112
  return nil unless check_payload_present(decoded)
143
113
 
144
114
  decoded
145
115
  rescue => e
146
- NewRelic::Agent.increment_metric SUPPORTABILITY_PAYLOAD_ACCEPT_IGNORED_PARSE_EXCEPTION
147
- NewRelic::Agent.logger.warn "Error parsing distributed trace payload", e
116
+ NewRelic::Agent.increment_metric(ACCEPT_PARSE_EXCEPTION_METRIC)
117
+ NewRelic::Agent.logger.warn("Error parsing distributed trace payload", e)
148
118
  nil
149
119
  end
150
120
 
151
121
  def check_required_fields_present(payload)
152
122
  if \
153
123
  !payload.version.nil? &&
154
- !payload.parent_account_id.nil? &&
155
- !payload.parent_app_id.nil? &&
156
- !payload.parent_type.nil? &&
157
- (!payload.transaction_id.nil? || !payload.id.nil?) &&
158
- !payload.trace_id.nil? &&
159
- !payload.timestamp.nil? &&
160
- !payload.parent_account_id.nil?
124
+ !payload.parent_account_id.nil? &&
125
+ !payload.parent_app_id.nil? &&
126
+ !payload.parent_type.nil? &&
127
+ (!payload.transaction_id.nil? || !payload.id.nil?) &&
128
+ !payload.trace_id.nil? &&
129
+ !payload.timestamp.nil?
161
130
 
162
131
  true
163
132
  else
164
- NewRelic::Agent.increment_metric SUPPORTABILITY_PAYLOAD_ACCEPT_IGNORED_PARSE_EXCEPTION
133
+ NewRelic::Agent.increment_metric(ACCEPT_PARSE_EXCEPTION_METRIC)
165
134
  false
166
135
  end
167
136
  end
168
137
 
169
- SUPPORTABILITY_PAYLOAD_ACCEPT_IGNORED_MAJOR_VERSION = "Supportability/DistributedTrace/AcceptPayload/Ignored/MajorVersion".freeze
170
-
171
138
  def check_valid_version(payload)
172
139
  if DistributedTracePayload.major_version_matches?(payload)
173
140
  true
174
141
  else
175
- NewRelic::Agent.increment_metric SUPPORTABILITY_PAYLOAD_ACCEPT_IGNORED_MAJOR_VERSION
142
+ NewRelic::Agent.increment_metric(IGNORE_ACCEPT_MAJOR_VERSION_METRIC)
176
143
  false
177
144
  end
178
145
  end
179
146
 
180
- SUPPORTABILITY_PAYLOAD_ACCEPT_UNTRUSTED_ACCOUNT = "Supportability/DistributedTrace/AcceptPayload/Ignored/UntrustedAccount".freeze
181
-
182
147
  def check_trusted_account(payload)
183
148
  compare_key = payload.trusted_account_key || payload.parent_account_id
184
149
  unless compare_key == NewRelic::Agent.config[:trusted_account_key]
185
- NewRelic::Agent.increment_metric SUPPORTABILITY_PAYLOAD_ACCEPT_UNTRUSTED_ACCOUNT
150
+ NewRelic::Agent.increment_metric(IGNORE_ACCEPT_UNTRUSTED_ACCOUNT_METRIC)
186
151
  return false
187
152
  end
188
153
  true
189
154
  end
190
155
 
191
156
  def assign_payload_and_sampling_params(payload)
192
- self.distributed_trace_payload = payload
193
-
194
- unless payload.sampled.nil?
195
- self.sampled = payload.sampled
196
- self.priority = payload.priority if payload.priority
197
- end
198
- end
157
+ @distributed_trace_payload = payload
158
+ return if transaction.distributed_tracer.trace_context_header_data
199
159
 
200
- ALL_SUFFIX = "all".freeze
201
- ALL_WEB_SUFFIX = "allWeb".freeze
202
- ALL_OTHER_SUFFIX = "allOther".freeze
160
+ transaction.trace_id = payload.trace_id
161
+ transaction.distributed_tracer.parent_transaction_id = payload.transaction_id
162
+ transaction.parent_span_id = payload.id
203
163
 
204
- def transaction_type_suffix
205
- if Transaction.recording_web_transaction?
206
- ALL_WEB_SUFFIX
207
- else
208
- ALL_OTHER_SUFFIX
209
- end
210
- end
211
-
212
- def record_distributed_tracing_metrics
213
- return unless Agent.config[:'distributed_tracing.enabled']
214
-
215
- record_caller_by_duration_metrics
216
- record_transport_duration_metrics
217
- record_errors_by_caller_metrics
218
- end
219
-
220
- DURATION_BY_CALLER_UNKOWN_PREFIX = "DurationByCaller/Unknown/Unknown/Unknown/Unknown".freeze
221
-
222
- def record_caller_by_duration_metrics
223
- prefix = if distributed_trace?
224
- payload = distributed_trace_payload
225
- "DurationByCaller/#{payload.parent_type}/#{payload.parent_account_id}/#{payload.parent_app_id}/#{payload.caller_transport_type}"
226
- else
227
- DURATION_BY_CALLER_UNKOWN_PREFIX
228
- end
229
-
230
- metrics.record_unscoped "#{prefix}/#{ALL_SUFFIX}", duration
231
- metrics.record_unscoped "#{prefix}/#{transaction_type_suffix}", duration
232
- end
233
-
234
- def record_transport_duration_metrics
235
- return unless distributed_trace?
236
-
237
- payload = distributed_trace_payload
238
- prefix = "TransportDuration/#{payload.parent_type}/#{payload.parent_account_id}/#{payload.parent_app_id}/#{payload.caller_transport_type}"
239
-
240
- metrics.record_unscoped "#{prefix}/#{ALL_SUFFIX}", transport_duration
241
- metrics.record_unscoped "#{prefix}/#{transaction_type_suffix}", transport_duration
242
- end
243
-
244
- ERRORS_BY_CALLER_UNKOWN_PREFIX = "ErrorsByCaller/Unknown/Unknown/Unknown/Unknown".freeze
245
-
246
- def record_errors_by_caller_metrics
247
- return unless exceptions.size > 0
248
-
249
- prefix = if distributed_trace?
250
- payload = distributed_trace_payload
251
- "ErrorsByCaller/#{payload.parent_type}/#{payload.parent_account_id}/#{payload.parent_app_id}/#{payload.caller_transport_type}"
252
- else
253
- ERRORS_BY_CALLER_UNKOWN_PREFIX
164
+ unless payload.sampled.nil?
165
+ transaction.sampled = payload.sampled
166
+ transaction.priority = payload.priority if payload.priority
254
167
  end
255
-
256
- metrics.record_unscoped "#{prefix}/#{ALL_SUFFIX}", 1
257
- metrics.record_unscoped "#{prefix}/#{transaction_type_suffix}", 1
258
168
  end
259
169
  end
260
170
  end
261
171
  end
262
172
  end
263
-
@@ -1,6 +1,6 @@
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
5
  require 'new_relic/agent/transaction/segment'
6
6
  require 'new_relic/agent/http_clients/uri_util'
@@ -8,23 +8,30 @@ require 'new_relic/agent/http_clients/uri_util'
8
8
  module NewRelic
9
9
  module Agent
10
10
  class Transaction
11
-
12
11
  #
13
12
  # This class represents an external segment in a transaction trace.
14
13
  #
15
14
  # @api public
16
15
  class ExternalRequestSegment < Segment
17
- attr_reader :library, :uri, :procedure
16
+ NR_SYNTHETICS_HEADER = 'X-NewRelic-Synthetics'
17
+ APP_DATA_KEY = 'NewRelicAppData'
18
18
 
19
- NR_SYNTHETICS_HEADER = 'X-NewRelic-Synthetics'.freeze
19
+ EXTERNAL_ALL = "External/all"
20
+ EXTERNAL_ALL_WEB = "External/allWeb"
21
+ EXTERNAL_ALL_OTHER = "External/allOther"
22
+ MISSING_STATUS_CODE = "MissingHTTPStatusCode"
20
23
 
24
+ attr_reader :library, :uri, :procedure, :http_status_code
25
+ attr_writer :record_agent_attributes
21
26
 
22
- def initialize library, uri, procedure, start_time = nil # :nodoc:
27
+ def initialize(library, uri, procedure, start_time = nil) # :nodoc:
23
28
  @library = library
24
- @uri = HTTPClients::URIUtil.parse_and_normalize_url(uri)
29
+ @uri = HTTPClients::URIUtil.obfuscated_uri(uri)
25
30
  @procedure = procedure
26
31
  @host_header = nil
27
32
  @app_data = nil
33
+ @http_status_code = nil
34
+ @record_agent_attributes = false
28
35
  super(nil, nil, start_time)
29
36
  end
30
37
 
@@ -36,6 +43,14 @@ module NewRelic
36
43
  @host_header || uri.host
37
44
  end
38
45
 
46
+ # By default external request segments only have errors and the http
47
+ # url recorded as agent attributes. To have all the agent attributes
48
+ # recorded, use the attr_writer like so `segment.record_agent_attributes = true`
49
+ # See: SpanEventPrimitive#for_external_request_segment
50
+ def record_agent_attributes?
51
+ @record_agent_attributes
52
+ end
53
+
39
54
  # This method adds New Relic request headers to a given request made to an
40
55
  # external API and checks to see if a host header is used for the request.
41
56
  # If a host header is used, it updates the segment name to match the host
@@ -45,17 +60,16 @@ module NewRelic
45
60
  # object (must belong to a subclass of NewRelic::Agent::HTTPClients::AbstractRequest)
46
61
  #
47
62
  # @api public
48
- def add_request_headers request
49
- process_host_header request
63
+ def add_request_headers(request)
64
+ process_host_header(request)
50
65
  synthetics_header = transaction && transaction.raw_synthetics_header
51
- insert_synthetics_header request, synthetics_header if synthetics_header
66
+ insert_synthetics_header(request, synthetics_header) if synthetics_header
52
67
 
53
68
  return unless record_metrics?
54
69
 
55
- insert_cross_app_header request
56
- insert_distributed_trace_header request
70
+ transaction.distributed_tracer.insert_headers(request)
57
71
  rescue => e
58
- NewRelic::Agent.logger.error "Error in add_request_headers", e
72
+ NewRelic::Agent.logger.error("Error in add_request_headers", e)
59
73
  end
60
74
 
61
75
  # This method extracts app data from an external response if present. If
@@ -65,11 +79,12 @@ module NewRelic
65
79
  # @param [Hash] response a hash of response headers
66
80
  #
67
81
  # @api public
68
- def read_response_headers response
82
+ def read_response_headers(response)
69
83
  return unless record_metrics? && CrossAppTracing.cross_app_enabled?
70
84
  return unless CrossAppTracing.response_has_crossapp_header?(response)
85
+
71
86
  unless data = CrossAppTracing.extract_appdata(response)
72
- NewRelic::Agent.logger.debug "Couldn't extract_appdata from external segment response"
87
+ NewRelic::Agent.logger.debug("Couldn't extract_appdata from external segment response")
73
88
  return
74
89
  end
75
90
 
@@ -77,10 +92,10 @@ module NewRelic
77
92
  @app_data = data
78
93
  update_segment_name
79
94
  else
80
- NewRelic::Agent.logger.debug "External segment response has invalid cross_app_id"
95
+ NewRelic::Agent.logger.debug("External segment response has invalid cross_app_id")
81
96
  end
82
97
  rescue => e
83
- NewRelic::Agent.logger.error "Error in read_response_headers", e
98
+ NewRelic::Agent.logger.error("Error in read_response_headers", e)
84
99
  end
85
100
 
86
101
  def cross_app_request? # :nodoc:
@@ -99,10 +114,6 @@ module NewRelic
99
114
  @app_data && @app_data[1]
100
115
  end
101
116
 
102
- EXTERNAL_TRANSACTION_PREFIX = 'ExternalTransaction/'.freeze
103
- SLASH = '/'.freeze
104
- APP_DATA_KEY = 'NewRelicAppData'.freeze
105
-
106
117
  # Obtain an obfuscated +String+ suitable for delivery across public networks that identifies this application
107
118
  # and transaction to another application which is also running a New Relic agent. This +String+ can be processed
108
119
  # by +process_request_metadata+ on the receiving application.
@@ -124,14 +135,14 @@ module NewRelic
124
135
  NewRelicTransaction: [
125
136
  transaction.guid,
126
137
  false,
127
- transaction.cat_trip_id,
128
- transaction.cat_path_hash
138
+ transaction.distributed_tracer.cat_trip_id,
139
+ transaction.distributed_tracer.cat_path_hash
129
140
  ]
130
141
  }
131
142
 
132
- # flag cross app in the state so transaction knows to add bits to paylaod
143
+ # flag cross app in the state so transaction knows to add bits to payload
133
144
  #
134
- transaction.is_cross_app_caller = true
145
+ transaction.distributed_tracer.is_cross_app_caller = true
135
146
 
136
147
  # add Synthetics header if we have it
137
148
  #
@@ -139,11 +150,11 @@ module NewRelic
139
150
 
140
151
  # obfuscate the generated request metadata JSON
141
152
  #
142
- obfuscator.obfuscate ::JSON.dump(rmd)
153
+ obfuscator.obfuscate(::JSON.dump(rmd))
143
154
 
144
155
  end
145
156
  rescue => e
146
- NewRelic::Agent.logger.error "error during get_request_metadata", e
157
+ NewRelic::Agent.logger.error("error during get_request_metadata", e)
147
158
  end
148
159
 
149
160
  # Process obfuscated +String+ sent from a called application that is also running a New Relic agent and
@@ -154,24 +165,24 @@ module NewRelic
154
165
  #
155
166
  # @api public
156
167
  #
157
- def process_response_metadata response_metadata
168
+ def process_response_metadata(response_metadata)
158
169
  NewRelic::Agent.record_api_supportability_metric(:process_response_metadata)
159
170
  if transaction
160
171
  app_data = ::JSON.parse(obfuscator.deobfuscate(response_metadata))[APP_DATA_KEY]
161
172
 
162
173
  # validate cross app id
163
174
  #
164
- if Array === app_data and CrossAppTracing.trusted_valid_cross_app_id? app_data[0]
175
+ if Array === app_data and CrossAppTracing.trusted_valid_cross_app_id?(app_data[0])
165
176
  @app_data = app_data
166
177
  update_segment_name
167
178
  else
168
- NewRelic::Agent.logger.error "error processing response metadata: invalid/non-trusted ID"
179
+ NewRelic::Agent.logger.error("error processing response metadata: invalid/non-trusted ID")
169
180
  end
170
181
  end
171
182
 
172
183
  nil
173
184
  rescue => e
174
- NewRelic::Agent.logger.error "error during process_response_metadata", e
185
+ NewRelic::Agent.logger.error("error during process_response_metadata", e)
175
186
  end
176
187
 
177
188
  def record_metrics
@@ -179,14 +190,29 @@ module NewRelic
179
190
  super
180
191
  end
181
192
 
193
+ def process_response_headers(response) # :nodoc:
194
+ set_http_status_code(response)
195
+ read_response_headers(response)
196
+ end
197
+
182
198
  private
183
199
 
184
- def insert_synthetics_header request, header
200
+ # Only sets the http_status_code if response.status_code is non-empty value
201
+ def set_http_status_code(response)
202
+ if response.respond_to?(:status_code)
203
+ @http_status_code = response.status_code if response.has_status_code?
204
+ else
205
+ NewRelic::Agent.logger.warn("Cannot extract HTTP Status Code from response #{response.class.to_s}")
206
+ NewRelic::Agent.record_metric("#{name}/#{MISSING_STATUS_CODE}", 1)
207
+ end
208
+ end
209
+
210
+ def insert_synthetics_header(request, header)
185
211
  request[NR_SYNTHETICS_HEADER] = header
186
212
  end
187
213
 
188
214
  def segment_complete
189
- params[:uri] = HTTPClients::URIUtil.filter_uri(uri)
215
+ params[:uri] = uri.to_s
190
216
  if cross_app_request?
191
217
  params[:transaction_guid] = transaction_guid
192
218
  end
@@ -194,47 +220,22 @@ module NewRelic
194
220
  super
195
221
  end
196
222
 
197
- def process_host_header request
223
+ def process_host_header(request)
198
224
  if @host_header = request.host_from_header
199
225
  update_segment_name
200
226
  end
201
227
  end
202
228
 
203
- def insert_cross_app_header request
204
- return unless CrossAppTracing.cross_app_enabled?
205
-
206
- transaction.is_cross_app_caller = true
207
- txn_guid = transaction.guid
208
- trip_id = transaction && transaction.cat_trip_id
209
- path_hash = transaction && transaction.cat_path_hash
210
-
211
- CrossAppTracing.insert_request_headers request, txn_guid, trip_id, path_hash
212
- end
213
-
214
- NEWRELIC_TRACE_HEADER = "newrelic".freeze
215
-
216
- def insert_distributed_trace_header request
217
- return unless Agent.config[:'distributed_tracing.enabled']
218
- payload = transaction.create_distributed_trace_payload
219
- request[NEWRELIC_TRACE_HEADER] = payload.http_safe if payload
220
- end
221
-
222
- EXTERNAL_ALL = "External/all".freeze
223
-
224
229
  def add_unscoped_metrics
225
- @unscoped_metrics = [ EXTERNAL_ALL,
230
+ @unscoped_metrics = [EXTERNAL_ALL,
226
231
  "External/#{host}/all",
227
- suffixed_rollup_metric
228
- ]
232
+ suffixed_rollup_metric]
229
233
 
230
234
  if cross_app_request?
231
235
  @unscoped_metrics << "ExternalApp/#{host}/#{cross_process_id}/all"
232
236
  end
233
237
  end
234
238
 
235
- EXTERNAL_ALL_WEB = "External/allWeb".freeze
236
- EXTERNAL_ALL_OTHER = "External/allOther".freeze
237
-
238
239
  def suffixed_rollup_metric
239
240
  if Transaction.recording_web_transaction?
240
241
  EXTERNAL_ALL_WEB
@@ -256,9 +257,11 @@ module NewRelic
256
257
  end
257
258
 
258
259
  def record_span_event
259
- aggregator = ::NewRelic::Agent.agent.span_event_aggregator
260
- priority = transaction.priority
260
+ # don't record a span event if the transaction is ignored
261
+ return if transaction.ignore?
261
262
 
263
+ aggregator = ::NewRelic::Agent.agent.span_event_aggregator
264
+ priority = transaction.priority
262
265
  aggregator.record(priority: priority) do
263
266
  SpanEventPrimitive.for_external_request_segment(self)
264
267
  end