newrelic_rpm 6.15.0 → 9.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (485) hide show
  1. checksums.yaml +4 -4
  2. data/.build_ignore +26 -0
  3. data/CHANGELOG.md +4176 -2789
  4. data/CONTRIBUTING.md +32 -13
  5. data/Gemfile +1 -2
  6. data/LICENSE +0 -6
  7. data/README.md +29 -22
  8. data/Rakefile +33 -35
  9. data/THIRD_PARTY_NOTICES.md +14 -199
  10. data/Thorfile +5 -0
  11. data/bin/newrelic +4 -9
  12. data/bin/newrelic_rpm +15 -0
  13. data/bin/nrdebug +85 -62
  14. data/init.rb +6 -8
  15. data/install.rb +2 -2
  16. data/lib/new_relic/agent/adaptive_sampler.rb +13 -9
  17. data/lib/new_relic/agent/agent.rb +99 -941
  18. data/lib/new_relic/agent/agent_helpers/connect.rb +222 -0
  19. data/lib/new_relic/agent/agent_helpers/harvest.rb +153 -0
  20. data/lib/new_relic/agent/agent_helpers/shutdown.rb +72 -0
  21. data/lib/new_relic/agent/agent_helpers/special_startup.rb +74 -0
  22. data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +175 -0
  23. data/lib/new_relic/agent/agent_helpers/startup.rb +202 -0
  24. data/lib/new_relic/agent/agent_helpers/transmit.rb +76 -0
  25. data/lib/new_relic/agent/agent_logger.rb +27 -23
  26. data/lib/new_relic/agent/attribute_filter.rb +67 -50
  27. data/lib/new_relic/agent/attribute_pre_filtering.rb +109 -0
  28. data/lib/new_relic/agent/attribute_processing.rb +9 -9
  29. data/lib/new_relic/agent/attributes.rb +5 -4
  30. data/lib/new_relic/agent/audit_logger.rb +13 -8
  31. data/lib/new_relic/agent/autostart.rb +21 -20
  32. data/lib/new_relic/agent/chained_call.rb +1 -1
  33. data/lib/new_relic/agent/commands/agent_command.rb +4 -4
  34. data/lib/new_relic/agent/commands/agent_command_router.rb +15 -13
  35. data/lib/new_relic/agent/commands/thread_profiler_session.rb +16 -14
  36. data/lib/new_relic/agent/configuration/default_source.rb +1608 -1182
  37. data/lib/new_relic/agent/configuration/dotted_hash.rb +6 -5
  38. data/lib/new_relic/agent/configuration/environment_source.rb +13 -11
  39. data/lib/new_relic/agent/configuration/event_harvest_config.rb +40 -17
  40. data/lib/new_relic/agent/configuration/high_security_source.rb +11 -12
  41. data/lib/new_relic/agent/configuration/manager.rb +103 -75
  42. data/lib/new_relic/agent/configuration/manual_source.rb +1 -1
  43. data/lib/new_relic/agent/configuration/mask_defaults.rb +3 -3
  44. data/lib/new_relic/agent/configuration/security_policy_source.rb +92 -95
  45. data/lib/new_relic/agent/configuration/server_source.rb +43 -41
  46. data/lib/new_relic/agent/configuration/yaml_source.rb +47 -10
  47. data/lib/new_relic/agent/configuration.rb +1 -1
  48. data/lib/new_relic/agent/connect/request_builder.rb +18 -18
  49. data/lib/new_relic/agent/connect/response_handler.rb +5 -8
  50. data/lib/new_relic/agent/custom_event_aggregator.rb +42 -16
  51. data/lib/new_relic/agent/database/explain_plan_helpers.rb +5 -6
  52. data/lib/new_relic/agent/database/obfuscation_helpers.rb +16 -15
  53. data/lib/new_relic/agent/database/obfuscator.rb +4 -4
  54. data/lib/new_relic/agent/database/postgres_explain_obfuscator.rb +3 -3
  55. data/lib/new_relic/agent/database.rb +45 -53
  56. data/lib/new_relic/agent/database_adapter.rb +3 -1
  57. data/lib/new_relic/agent/datastores/metric_helper.rb +21 -22
  58. data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +7 -6
  59. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +17 -21
  60. data/lib/new_relic/agent/datastores/mongo.rb +6 -11
  61. data/lib/new_relic/agent/datastores/nosql_obfuscator.rb +41 -0
  62. data/lib/new_relic/agent/datastores/redis.rb +9 -15
  63. data/lib/new_relic/agent/datastores.rb +13 -15
  64. data/lib/new_relic/agent/deprecator.rb +1 -1
  65. data/lib/new_relic/agent/distributed_tracing/cross_app_payload.rb +10 -10
  66. data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +45 -40
  67. data/lib/new_relic/agent/distributed_tracing/distributed_trace_attributes.rb +22 -22
  68. data/lib/new_relic/agent/distributed_tracing/distributed_trace_metrics.rb +23 -23
  69. data/lib/new_relic/agent/distributed_tracing/distributed_trace_payload.rb +52 -54
  70. data/lib/new_relic/agent/distributed_tracing/distributed_trace_transport_type.rb +10 -11
  71. data/lib/new_relic/agent/distributed_tracing/trace_context.rb +82 -83
  72. data/lib/new_relic/agent/distributed_tracing/trace_context_payload.rb +42 -41
  73. data/lib/new_relic/agent/distributed_tracing.rb +33 -101
  74. data/lib/new_relic/agent/encoding_normalizer.rb +4 -2
  75. data/lib/new_relic/agent/error_collector.rb +105 -58
  76. data/lib/new_relic/agent/error_event_aggregator.rb +4 -5
  77. data/lib/new_relic/agent/error_filter.rb +174 -0
  78. data/lib/new_relic/agent/error_trace_aggregator.rb +9 -7
  79. data/lib/new_relic/agent/event_aggregator.rb +22 -21
  80. data/lib/new_relic/agent/event_buffer.rb +7 -8
  81. data/lib/new_relic/agent/event_listener.rb +1 -2
  82. data/lib/new_relic/agent/event_loop.rb +27 -25
  83. data/lib/new_relic/agent/external.rb +11 -44
  84. data/lib/new_relic/agent/guid_generator.rb +13 -11
  85. data/lib/new_relic/agent/harvester.rb +5 -8
  86. data/lib/new_relic/agent/heap.rb +8 -9
  87. data/lib/new_relic/agent/hostname.rb +21 -14
  88. data/lib/new_relic/agent/http_clients/abstract.rb +22 -31
  89. data/lib/new_relic/agent/http_clients/async_http_wrappers.rb +80 -0
  90. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +14 -17
  91. data/lib/new_relic/agent/http_clients/ethon_wrappers.rb +109 -0
  92. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +15 -17
  93. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +7 -6
  94. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +8 -9
  95. data/lib/new_relic/agent/http_clients/httpx_wrappers.rb +91 -0
  96. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +13 -8
  97. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +12 -13
  98. data/lib/new_relic/agent/http_clients/uri_util.rb +3 -5
  99. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +9 -22
  100. data/lib/new_relic/agent/instrumentation/action_controller_other_subscriber.rb +42 -0
  101. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +41 -33
  102. data/lib/new_relic/agent/instrumentation/action_dispatch.rb +31 -0
  103. data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +64 -0
  104. data/lib/new_relic/agent/instrumentation/action_mailbox.rb +30 -0
  105. data/lib/new_relic/agent/instrumentation/action_mailbox_subscriber.rb +33 -0
  106. data/lib/new_relic/agent/instrumentation/action_mailer.rb +30 -0
  107. data/lib/new_relic/agent/instrumentation/action_mailer_subscriber.rb +85 -0
  108. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +20 -21
  109. data/lib/new_relic/agent/instrumentation/active_job.rb +33 -13
  110. data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +41 -0
  111. data/lib/new_relic/agent/instrumentation/active_merchant.rb +20 -6
  112. data/lib/new_relic/agent/instrumentation/active_record.rb +41 -38
  113. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +87 -75
  114. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +54 -66
  115. data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +6 -6
  116. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +30 -22
  117. data/lib/new_relic/agent/instrumentation/active_storage.rb +7 -3
  118. data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +8 -33
  119. data/lib/new_relic/agent/instrumentation/active_support.rb +27 -0
  120. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/chain.rb +69 -0
  121. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/instrumentation.rb +13 -0
  122. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/prepend.rb +37 -0
  123. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger.rb +23 -0
  124. data/lib/new_relic/agent/instrumentation/active_support_logger/chain.rb +23 -0
  125. data/lib/new_relic/agent/instrumentation/active_support_logger/instrumentation.rb +24 -0
  126. data/lib/new_relic/agent/instrumentation/active_support_logger/prepend.rb +12 -0
  127. data/lib/new_relic/agent/instrumentation/active_support_logger.rb +26 -0
  128. data/lib/new_relic/agent/instrumentation/active_support_subscriber.rb +41 -0
  129. data/lib/new_relic/agent/instrumentation/async_http/chain.rb +23 -0
  130. data/lib/new_relic/agent/instrumentation/async_http/instrumentation.rb +37 -0
  131. data/lib/new_relic/agent/instrumentation/async_http/prepend.rb +15 -0
  132. data/lib/new_relic/agent/instrumentation/async_http.rb +28 -0
  133. data/lib/new_relic/agent/instrumentation/bunny/chain.rb +45 -0
  134. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +159 -0
  135. data/lib/new_relic/agent/instrumentation/bunny/prepend.rb +35 -0
  136. data/lib/new_relic/agent/instrumentation/bunny.rb +11 -154
  137. data/lib/new_relic/agent/instrumentation/concurrent_ruby/chain.rb +36 -0
  138. data/lib/new_relic/agent/instrumentation/concurrent_ruby/instrumentation.rb +20 -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 +74 -63
  142. data/lib/new_relic/agent/instrumentation/curb/chain.rb +91 -0
  143. data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +225 -0
  144. data/lib/new_relic/agent/instrumentation/curb/prepend.rb +61 -0
  145. data/lib/new_relic/agent/instrumentation/curb.rb +14 -246
  146. data/lib/new_relic/agent/instrumentation/custom_events.rb +12 -0
  147. data/lib/new_relic/agent/instrumentation/custom_events_subscriber.rb +38 -0
  148. data/lib/new_relic/agent/instrumentation/delayed_job/chain.rb +36 -0
  149. data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +51 -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 -53
  152. data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +29 -0
  153. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +70 -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/ethon/chain.rb +39 -0
  157. data/lib/new_relic/agent/instrumentation/ethon/instrumentation.rb +105 -0
  158. data/lib/new_relic/agent/instrumentation/ethon/prepend.rb +35 -0
  159. data/lib/new_relic/agent/instrumentation/ethon.rb +39 -0
  160. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +11 -7
  161. data/lib/new_relic/agent/instrumentation/excon.rb +27 -29
  162. data/lib/new_relic/agent/instrumentation/fiber/chain.rb +27 -0
  163. data/lib/new_relic/agent/instrumentation/fiber/instrumentation.rb +20 -0
  164. data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +25 -0
  165. data/lib/new_relic/agent/instrumentation/fiber.rb +25 -0
  166. data/lib/new_relic/agent/instrumentation/grape/chain.rb +24 -0
  167. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +104 -0
  168. data/lib/new_relic/agent/instrumentation/grape/prepend.rb +17 -0
  169. data/lib/new_relic/agent/instrumentation/grape.rb +16 -117
  170. data/lib/new_relic/agent/instrumentation/grpc/client/chain.rb +97 -0
  171. data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +94 -0
  172. data/lib/new_relic/agent/instrumentation/grpc/client/prepend.rb +111 -0
  173. data/lib/new_relic/agent/instrumentation/grpc/client/request_wrapper.rb +30 -0
  174. data/lib/new_relic/agent/instrumentation/grpc/helper.rb +32 -0
  175. data/lib/new_relic/agent/instrumentation/grpc/server/chain.rb +69 -0
  176. data/lib/new_relic/agent/instrumentation/grpc/server/instrumentation.rb +138 -0
  177. data/lib/new_relic/agent/instrumentation/grpc/server/rpc_desc_prepend.rb +35 -0
  178. data/lib/new_relic/agent/instrumentation/grpc/server/rpc_server_prepend.rb +26 -0
  179. data/lib/new_relic/agent/instrumentation/grpc_client.rb +23 -0
  180. data/lib/new_relic/agent/instrumentation/grpc_server.rb +25 -0
  181. data/lib/new_relic/agent/instrumentation/httpclient/chain.rb +24 -0
  182. data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +41 -0
  183. data/lib/new_relic/agent/instrumentation/httpclient/prepend.rb +15 -0
  184. data/lib/new_relic/agent/instrumentation/httpclient.rb +10 -32
  185. data/lib/new_relic/agent/instrumentation/httprb/chain.rb +22 -0
  186. data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +34 -0
  187. data/lib/new_relic/agent/instrumentation/httprb/prepend.rb +15 -0
  188. data/lib/new_relic/agent/instrumentation/httprb.rb +29 -0
  189. data/lib/new_relic/agent/instrumentation/httpx/chain.rb +20 -0
  190. data/lib/new_relic/agent/instrumentation/httpx/instrumentation.rb +51 -0
  191. data/lib/new_relic/agent/instrumentation/httpx/prepend.rb +15 -0
  192. data/lib/new_relic/agent/instrumentation/httpx.rb +27 -0
  193. data/lib/new_relic/agent/instrumentation/ignore_actions.rb +5 -6
  194. data/lib/new_relic/agent/instrumentation/logger/chain.rb +21 -0
  195. data/lib/new_relic/agent/instrumentation/logger/instrumentation.rb +69 -0
  196. data/lib/new_relic/agent/instrumentation/logger/prepend.rb +13 -0
  197. data/lib/new_relic/agent/instrumentation/logger.rb +26 -0
  198. data/lib/new_relic/agent/instrumentation/memcache/chain.rb +15 -0
  199. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +59 -128
  200. data/lib/new_relic/agent/instrumentation/memcache/helper.rb +59 -0
  201. data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +99 -0
  202. data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +103 -0
  203. data/lib/new_relic/agent/instrumentation/memcache.rb +58 -74
  204. data/lib/new_relic/agent/instrumentation/middleware_proxy.rb +15 -14
  205. data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +6 -8
  206. data/lib/new_relic/agent/instrumentation/mongo.rb +6 -137
  207. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +24 -23
  208. data/lib/new_relic/agent/instrumentation/net_http/chain.rb +24 -0
  209. data/lib/new_relic/agent/instrumentation/{net_prepend.rb → net_http/instrumentation.rb} +18 -14
  210. data/lib/new_relic/agent/instrumentation/net_http/prepend.rb +21 -0
  211. data/lib/new_relic/agent/instrumentation/net_http.rb +44 -0
  212. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +56 -10
  213. data/lib/new_relic/agent/instrumentation/padrino/chain.rb +38 -0
  214. data/lib/new_relic/agent/instrumentation/padrino/instrumentation.rb +32 -0
  215. data/lib/new_relic/agent/instrumentation/padrino/prepend.rb +20 -0
  216. data/lib/new_relic/agent/instrumentation/padrino.rb +20 -58
  217. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +6 -6
  218. data/lib/new_relic/agent/instrumentation/queue_time.rb +9 -10
  219. data/lib/new_relic/agent/instrumentation/rack/chain.rb +66 -0
  220. data/lib/new_relic/agent/instrumentation/rack/helpers.rb +33 -0
  221. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +81 -0
  222. data/lib/new_relic/agent/instrumentation/rack/prepend.rb +43 -0
  223. data/lib/new_relic/agent/instrumentation/rack.rb +32 -142
  224. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +25 -56
  225. data/lib/new_relic/agent/instrumentation/rails_middleware.rb +4 -4
  226. data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +9 -8
  227. data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +18 -5
  228. data/lib/new_relic/agent/instrumentation/rails_notifications/action_view.rb +8 -5
  229. data/lib/new_relic/agent/instrumentation/rails_notifications/custom_events.rb +30 -0
  230. data/lib/new_relic/agent/instrumentation/rake/chain.rb +20 -0
  231. data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +146 -0
  232. data/lib/new_relic/agent/instrumentation/rake/prepend.rb +14 -0
  233. data/lib/new_relic/agent/instrumentation/rake.rb +17 -158
  234. data/lib/new_relic/agent/instrumentation/redis/chain.rb +45 -0
  235. data/lib/new_relic/agent/instrumentation/redis/constants.rb +17 -0
  236. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +98 -0
  237. data/lib/new_relic/agent/instrumentation/redis/middleware.rb +16 -0
  238. data/lib/new_relic/agent/instrumentation/redis/prepend.rb +29 -0
  239. data/lib/new_relic/agent/instrumentation/redis.rb +19 -108
  240. data/lib/new_relic/agent/instrumentation/resque/chain.rb +21 -0
  241. data/lib/new_relic/agent/instrumentation/resque/helper.rb +19 -0
  242. data/lib/new_relic/agent/instrumentation/resque/instrumentation.rb +38 -0
  243. data/lib/new_relic/agent/instrumentation/resque/prepend.rb +15 -0
  244. data/lib/new_relic/agent/instrumentation/resque.rb +32 -43
  245. data/lib/new_relic/agent/instrumentation/roda/chain.rb +43 -0
  246. data/lib/new_relic/agent/instrumentation/roda/ignorer.rb +45 -0
  247. data/lib/new_relic/agent/instrumentation/roda/instrumentation.rb +68 -0
  248. data/lib/new_relic/agent/instrumentation/roda/prepend.rb +24 -0
  249. data/lib/new_relic/agent/instrumentation/roda/roda_transaction_namer.rb +29 -0
  250. data/lib/new_relic/agent/instrumentation/roda.rb +36 -0
  251. data/lib/new_relic/agent/instrumentation/sequel.rb +16 -19
  252. data/lib/new_relic/agent/instrumentation/sequel_helper.rb +12 -12
  253. data/lib/new_relic/agent/instrumentation/sidekiq/client.rb +24 -0
  254. data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +30 -0
  255. data/lib/new_relic/agent/instrumentation/sidekiq/server.rb +60 -0
  256. data/lib/new_relic/agent/instrumentation/sidekiq.rb +27 -65
  257. data/lib/new_relic/agent/instrumentation/sinatra/chain.rb +55 -0
  258. data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +30 -36
  259. data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +130 -0
  260. data/lib/new_relic/agent/instrumentation/sinatra/prepend.rb +33 -0
  261. data/lib/new_relic/agent/instrumentation/sinatra/transaction_namer.rb +4 -6
  262. data/lib/new_relic/agent/instrumentation/sinatra.rb +34 -163
  263. data/lib/new_relic/agent/instrumentation/stripe.rb +28 -0
  264. data/lib/new_relic/agent/instrumentation/stripe_subscriber.rb +77 -0
  265. data/lib/new_relic/agent/instrumentation/thread/chain.rb +24 -0
  266. data/lib/new_relic/agent/instrumentation/thread/instrumentation.rb +24 -0
  267. data/lib/new_relic/agent/instrumentation/thread/prepend.rb +22 -0
  268. data/lib/new_relic/agent/instrumentation/thread.rb +20 -0
  269. data/lib/new_relic/agent/instrumentation/tilt/chain.rb +24 -0
  270. data/lib/new_relic/agent/instrumentation/tilt/instrumentation.rb +46 -0
  271. data/lib/new_relic/agent/instrumentation/tilt/prepend.rb +13 -0
  272. data/lib/new_relic/agent/instrumentation/tilt.rb +25 -0
  273. data/lib/new_relic/agent/instrumentation/typhoeus/chain.rb +22 -0
  274. data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +84 -0
  275. data/lib/new_relic/agent/instrumentation/typhoeus/prepend.rb +14 -0
  276. data/lib/new_relic/agent/instrumentation/typhoeus.rb +12 -91
  277. data/lib/new_relic/agent/instrumentation/view_component/chain.rb +21 -0
  278. data/lib/new_relic/agent/instrumentation/view_component/instrumentation.rb +39 -0
  279. data/lib/new_relic/agent/instrumentation/view_component/prepend.rb +13 -0
  280. data/lib/new_relic/agent/instrumentation/view_component.rb +26 -0
  281. data/lib/new_relic/agent/instrumentation.rb +1 -1
  282. data/lib/new_relic/agent/internal_agent_error.rb +2 -2
  283. data/lib/new_relic/agent/javascript_instrumentor.rb +58 -48
  284. data/lib/new_relic/agent/linking_metadata.rb +44 -0
  285. data/lib/new_relic/agent/local_log_decorator.rb +37 -0
  286. data/lib/new_relic/agent/log_event_aggregator.rb +282 -0
  287. data/lib/new_relic/agent/log_event_attributes.rb +115 -0
  288. data/lib/new_relic/agent/log_once.rb +1 -1
  289. data/lib/new_relic/agent/log_priority.rb +20 -0
  290. data/lib/new_relic/agent/logging.rb +95 -52
  291. data/lib/new_relic/agent/memory_logger.rb +2 -2
  292. data/lib/new_relic/agent/messaging.rb +72 -86
  293. data/lib/new_relic/agent/method_tracer.rb +159 -154
  294. data/lib/new_relic/agent/method_tracer_helpers.rb +109 -11
  295. data/lib/new_relic/agent/monitors/cross_app_monitor.rb +26 -19
  296. data/lib/new_relic/agent/monitors/distributed_tracing_monitor.rb +5 -4
  297. data/lib/new_relic/agent/monitors/inbound_request_monitor.rb +1 -2
  298. data/lib/new_relic/agent/monitors/synthetics_monitor.rb +17 -9
  299. data/lib/new_relic/agent/monitors.rb +6 -7
  300. data/lib/new_relic/agent/new_relic_service/encoders.rb +9 -9
  301. data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +6 -6
  302. data/lib/new_relic/agent/new_relic_service/marshaller.rb +2 -2
  303. data/lib/new_relic/agent/new_relic_service/security_policy_settings.rb +4 -4
  304. data/lib/new_relic/agent/new_relic_service.rb +282 -213
  305. data/lib/new_relic/agent/{noticible_error.rb → noticeable_error.rb} +2 -5
  306. data/lib/new_relic/agent/null_logger.rb +7 -3
  307. data/lib/new_relic/agent/obfuscator.rb +7 -11
  308. data/lib/new_relic/agent/parameter_filtering.rb +29 -15
  309. data/lib/new_relic/agent/payload_metric_mapping.rb +9 -10
  310. data/lib/new_relic/agent/pipe_channel_manager.rb +34 -23
  311. data/lib/new_relic/agent/pipe_service.rb +13 -8
  312. data/lib/new_relic/agent/prepend_supportability.rb +2 -2
  313. data/lib/new_relic/agent/priority_sampled_buffer.rb +9 -12
  314. data/lib/new_relic/agent/rules_engine/replacement_rule.rb +11 -11
  315. data/lib/new_relic/agent/rules_engine/segment_terms_rule.rb +12 -14
  316. data/lib/new_relic/agent/rules_engine.rb +6 -5
  317. data/lib/new_relic/agent/sampler.rb +5 -5
  318. data/lib/new_relic/agent/sampler_collection.rb +4 -5
  319. data/lib/new_relic/agent/samplers/cpu_sampler.rb +8 -7
  320. data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +20 -17
  321. data/lib/new_relic/agent/samplers/memory_sampler.rb +32 -21
  322. data/lib/new_relic/agent/samplers/object_sampler.rb +2 -2
  323. data/lib/new_relic/agent/samplers/vm_sampler.rb +21 -19
  324. data/lib/new_relic/agent/span_event_aggregator.rb +15 -15
  325. data/lib/new_relic/agent/span_event_primitive.rb +77 -59
  326. data/lib/new_relic/agent/sql_sampler.rb +20 -21
  327. data/lib/new_relic/agent/stats.rb +79 -42
  328. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +9 -11
  329. data/lib/new_relic/agent/stats_engine/stats_hash.rb +12 -13
  330. data/lib/new_relic/agent/stats_engine.rb +8 -8
  331. data/lib/new_relic/agent/synthetics_event_aggregator.rb +8 -9
  332. data/lib/new_relic/agent/system_info.rb +113 -67
  333. data/lib/new_relic/agent/threading/agent_thread.rb +18 -14
  334. data/lib/new_relic/agent/threading/backtrace_node.rb +12 -13
  335. data/lib/new_relic/agent/threading/backtrace_service.rb +17 -21
  336. data/lib/new_relic/agent/threading/thread_profile.rb +24 -24
  337. data/lib/new_relic/agent/timestamp_sampled_buffer.rb +2 -2
  338. data/lib/new_relic/agent/tracer.rb +101 -96
  339. data/lib/new_relic/agent/transaction/abstract_segment.rb +176 -52
  340. data/lib/new_relic/agent/transaction/datastore_segment.rb +22 -18
  341. data/lib/new_relic/agent/transaction/distributed_tracer.rb +65 -57
  342. data/lib/new_relic/agent/transaction/distributed_tracing.rb +46 -48
  343. data/lib/new_relic/agent/transaction/external_request_segment.rb +52 -39
  344. data/lib/new_relic/agent/transaction/message_broker_segment.rb +31 -37
  345. data/lib/new_relic/agent/transaction/request_attributes.rb +78 -42
  346. data/lib/new_relic/agent/transaction/segment.rb +20 -10
  347. data/lib/new_relic/agent/transaction/slowest_sample_buffer.rb +1 -3
  348. data/lib/new_relic/agent/transaction/synthetics_sample_buffer.rb +2 -2
  349. data/lib/new_relic/agent/transaction/trace.rb +16 -12
  350. data/lib/new_relic/agent/transaction/trace_builder.rb +10 -10
  351. data/lib/new_relic/agent/transaction/trace_context.rb +35 -35
  352. data/lib/new_relic/agent/transaction/trace_node.rb +30 -28
  353. data/lib/new_relic/agent/transaction/tracing.rb +32 -13
  354. data/lib/new_relic/agent/transaction/transaction_sample_buffer.rb +6 -6
  355. data/lib/new_relic/agent/transaction.rb +229 -178
  356. data/lib/new_relic/agent/transaction_error_primitive.rb +43 -25
  357. data/lib/new_relic/agent/transaction_event_aggregator.rb +16 -16
  358. data/lib/new_relic/agent/transaction_event_primitive.rb +51 -33
  359. data/lib/new_relic/agent/transaction_event_recorder.rb +16 -15
  360. data/lib/new_relic/agent/transaction_metrics.rb +10 -9
  361. data/lib/new_relic/agent/transaction_sampler.rb +7 -8
  362. data/lib/new_relic/agent/transaction_time_aggregator.rb +32 -27
  363. data/lib/new_relic/agent/utilization/aws.rb +34 -4
  364. data/lib/new_relic/agent/utilization/azure.rb +6 -6
  365. data/lib/new_relic/agent/utilization/gcp.rb +11 -13
  366. data/lib/new_relic/agent/utilization/pcf.rb +6 -5
  367. data/lib/new_relic/agent/utilization/vendor.rb +45 -32
  368. data/lib/new_relic/agent/utilization_data.rb +7 -5
  369. data/lib/new_relic/agent/vm/c_ruby_vm.rb +99 -0
  370. data/lib/new_relic/agent/vm/jruby_vm.rb +1 -1
  371. data/lib/new_relic/agent/vm/monotonic_gc_profiler.rb +3 -3
  372. data/lib/new_relic/agent/vm/snapshot.rb +5 -5
  373. data/lib/new_relic/agent/vm.rb +3 -3
  374. data/lib/new_relic/agent/worker_loop.rb +10 -12
  375. data/lib/new_relic/agent.rb +204 -111
  376. data/lib/new_relic/base64.rb +25 -0
  377. data/lib/new_relic/cli/command.rb +26 -25
  378. data/lib/new_relic/cli/commands/deployments.rb +100 -49
  379. data/lib/new_relic/cli/commands/install.rb +31 -34
  380. data/lib/new_relic/coerce.rb +15 -13
  381. data/lib/new_relic/collection_helper.rb +50 -48
  382. data/lib/new_relic/constants.rb +13 -12
  383. data/lib/new_relic/control/class_methods.rb +6 -12
  384. data/lib/new_relic/control/frameworks/external.rb +2 -2
  385. data/lib/new_relic/control/frameworks/rails.rb +60 -30
  386. data/lib/new_relic/control/frameworks/rails3.rb +3 -4
  387. data/lib/new_relic/control/frameworks/rails4.rb +1 -1
  388. data/lib/new_relic/control/frameworks/rails_notifications.rb +1 -1
  389. data/lib/new_relic/control/frameworks/roda.rb +20 -0
  390. data/lib/new_relic/control/frameworks/ruby.rb +3 -3
  391. data/lib/new_relic/control/frameworks/sinatra.rb +7 -1
  392. data/lib/new_relic/control/frameworks.rb +1 -1
  393. data/lib/new_relic/control/instance_methods.rb +27 -45
  394. data/lib/new_relic/control/instrumentation.rb +25 -11
  395. data/lib/new_relic/control/private_instance_methods.rb +48 -0
  396. data/lib/new_relic/control/server_methods.rb +3 -4
  397. data/lib/new_relic/control.rb +1 -2
  398. data/lib/new_relic/delayed_job_injection.rb +1 -1
  399. data/lib/new_relic/dependency_detection.rb +141 -32
  400. data/lib/new_relic/environment_report.rb +41 -33
  401. data/lib/new_relic/helper.rb +49 -7
  402. data/lib/new_relic/language_support.rb +39 -6
  403. data/lib/new_relic/latest_changes.rb +10 -9
  404. data/lib/new_relic/local_environment.rb +42 -37
  405. data/lib/new_relic/metric_data.rb +31 -26
  406. data/lib/new_relic/metric_spec.rb +8 -6
  407. data/lib/new_relic/noticed_error.rb +43 -46
  408. data/lib/new_relic/rack/agent_hooks.rb +2 -2
  409. data/lib/new_relic/rack/agent_middleware.rb +3 -17
  410. data/lib/new_relic/rack/browser_monitoring.rb +135 -121
  411. data/lib/new_relic/rack.rb +1 -1
  412. data/lib/new_relic/recipes/capistrano3.rb +4 -62
  413. data/lib/new_relic/recipes/capistrano_legacy.rb +24 -27
  414. data/lib/new_relic/recipes/helpers/send_deployment.rb +70 -0
  415. data/lib/new_relic/recipes.rb +1 -1
  416. data/lib/new_relic/supportability_helper.rb +14 -12
  417. data/lib/new_relic/traced_thread.rb +38 -0
  418. data/lib/new_relic/version.rb +6 -17
  419. data/lib/newrelic_rpm.rb +20 -33
  420. data/lib/sequel/extensions/{newrelic_instrumentation.rb → new_relic_instrumentation.rb} +18 -21
  421. data/lib/sequel/plugins/{newrelic_instrumentation.rb → new_relic_instrumentation.rb} +9 -15
  422. data/lib/tasks/all.rb +3 -3
  423. data/lib/tasks/bump_version.rake +21 -0
  424. data/lib/tasks/config.rake +25 -119
  425. data/lib/tasks/coverage_report.rake +28 -0
  426. data/lib/tasks/helpers/config.html.erb +114 -0
  427. data/lib/tasks/helpers/format.rb +127 -0
  428. data/lib/tasks/helpers/matches.rb +12 -0
  429. data/lib/tasks/helpers/newrelicyml.rb +144 -0
  430. data/lib/tasks/helpers/prompt.rb +24 -0
  431. data/lib/tasks/helpers/version_bump.rb +62 -0
  432. data/lib/tasks/install.rake +8 -4
  433. data/lib/tasks/instrumentation_generator/README.md +63 -0
  434. data/lib/tasks/instrumentation_generator/TODO.md +33 -0
  435. data/lib/tasks/instrumentation_generator/instrumentation.thor +121 -0
  436. data/lib/tasks/instrumentation_generator/templates/Envfile.tt +9 -0
  437. data/lib/tasks/instrumentation_generator/templates/chain.tt +21 -0
  438. data/lib/tasks/instrumentation_generator/templates/chain_method.tt +7 -0
  439. data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +29 -0
  440. data/lib/tasks/instrumentation_generator/templates/instrumentation.tt +13 -0
  441. data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +3 -0
  442. data/lib/tasks/instrumentation_generator/templates/newrelic.yml.tt +19 -0
  443. data/lib/tasks/instrumentation_generator/templates/prepend.tt +13 -0
  444. data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +3 -0
  445. data/lib/tasks/instrumentation_generator/templates/test.tt +15 -0
  446. data/lib/tasks/newrelic.rb +2 -1
  447. data/lib/tasks/newrelicyml.rake +13 -0
  448. data/lib/tasks/tests.rake +83 -17
  449. data/newrelic.yml +790 -4
  450. data/newrelic_rpm.gemspec +52 -43
  451. data/recipes/newrelic.rb +2 -2
  452. data/test/agent_helper.rb +252 -198
  453. metadata +275 -95
  454. data/.gitignore +0 -37
  455. data/.project +0 -23
  456. data/.yardopts +0 -26
  457. data/Guardfile +0 -25
  458. data/ROADMAP.md +0 -24
  459. data/bin/mongrel_rpm +0 -33
  460. data/bin/newrelic_cmd +0 -5
  461. data/cert/cacert.pem +0 -1177
  462. data/config/database.yml +0 -5
  463. data/config.dot +0 -278
  464. data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +0 -44
  465. data/lib/new_relic/agent/datastores/mongo/statement_formatter.rb +0 -53
  466. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +0 -75
  467. data/lib/new_relic/agent/instrumentation/authlogic.rb +0 -25
  468. data/lib/new_relic/agent/instrumentation/data_mapper.rb +0 -204
  469. data/lib/new_relic/agent/instrumentation/excon/connection.rb +0 -49
  470. data/lib/new_relic/agent/instrumentation/http.rb +0 -49
  471. data/lib/new_relic/agent/instrumentation/merb/controller.rb +0 -44
  472. data/lib/new_relic/agent/instrumentation/merb/errors.rb +0 -33
  473. data/lib/new_relic/agent/instrumentation/net.rb +0 -70
  474. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +0 -125
  475. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +0 -46
  476. data/lib/new_relic/agent/instrumentation/rainbows_instrumentation.rb +0 -26
  477. data/lib/new_relic/agent/instrumentation/sunspot.rb +0 -33
  478. data/lib/new_relic/agent/range_extensions.rb +0 -47
  479. data/lib/new_relic/agent/supported_versions.rb +0 -275
  480. data/lib/new_relic/agent/vm/mri_vm.rb +0 -81
  481. data/lib/new_relic/control/frameworks/merb.rb +0 -29
  482. data/lib/tasks/config.html.erb +0 -32
  483. data/lib/tasks/multiverse.rake +0 -2
  484. data/lib/tasks/multiverse.rb +0 -104
  485. /data/lib/tasks/{config.text.erb → helpers/config.text.erb} +0 -0
@@ -1,14 +1,13 @@
1
- # encoding: utf-8
2
1
  # This file is distributed under New Relic's license terms.
3
2
  # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
4
 
5
- require 'base64'
6
5
  require 'json'
7
6
  require 'new_relic/agent/obfuscator'
8
7
 
9
8
  module NewRelic
10
9
  module Agent
11
- class JavascriptInstrumentor
10
+ class JavaScriptInstrumentor
12
11
  include NewRelic::Coerce
13
12
 
14
13
  RUM_KEY_LENGTH = 13
@@ -19,11 +18,11 @@ module NewRelic
19
18
 
20
19
  def log_configuration
21
20
  NewRelic::Agent.logger.debug("JS agent loader requested: #{NewRelic::Agent.config[:'browser_monitoring.loader']}",
22
- "JS agent loader debug: #{NewRelic::Agent.config[:'browser_monitoring.debug']}",
23
- "JS agent loader version: #{NewRelic::Agent.config[:'browser_monitoring.loader_version']}")
21
+ "JS agent loader debug: #{NewRelic::Agent.config[:'browser_monitoring.debug']}",
22
+ "JS agent loader version: #{NewRelic::Agent.config[:'browser_monitoring.loader_version']}")
24
23
 
25
24
  if !NewRelic::Agent.config[:'rum.enabled']
26
- NewRelic::Agent.logger.debug("Real User Monitoring is disabled for this agent. Edit your configuration to change this.")
25
+ NewRelic::Agent.logger.debug('Real User Monitoring is disabled for this agent. Edit your configuration to change this.')
27
26
  end
28
27
  end
29
28
 
@@ -38,43 +37,43 @@ module NewRelic
38
37
  def js_enabled_and_ready?
39
38
  if !enabled?
40
39
  ::NewRelic::Agent.logger.log_once(:debug, :js_agent_disabled,
41
- "JS agent instrumentation is disabled.")
40
+ 'JS agent instrumentation is disabled.')
42
41
  false
43
42
  elsif missing_config?(:js_agent_loader)
44
43
  ::NewRelic::Agent.logger.log_once(:debug, :missing_js_agent_loader,
45
- "Missing :js_agent_loader. Skipping browser instrumentation.")
44
+ 'Missing :js_agent_loader. Skipping browser instrumentation.')
46
45
  false
47
46
  elsif missing_config?(:beacon)
48
47
  ::NewRelic::Agent.logger.log_once(:debug, :missing_beacon,
49
- "Beacon configuration not received (yet?). Skipping browser instrumentation.")
48
+ 'Beacon configuration not received (yet?). Skipping browser instrumentation.')
50
49
  false
51
50
  elsif missing_config?(:browser_key)
52
51
  ::NewRelic::Agent.logger.log_once(:debug, :missing_browser_key,
53
- "Browser key is not set. Skipping browser instrumentation.")
52
+ 'Browser key is not set. Skipping browser instrumentation.')
54
53
  false
55
54
  else
56
55
  true
57
56
  end
58
57
  rescue => e
59
- ::NewRelic::Agent.logger.debug "Failure during 'js_enabled_and_ready?'", e
58
+ ::NewRelic::Agent.logger.debug("Failure during 'js_enabled_and_ready?'", e)
60
59
  false
61
60
  end
62
61
 
63
62
  def insert_js?(state)
64
63
  if !state.current_transaction
65
- ::NewRelic::Agent.logger.debug "Not in transaction. Skipping browser instrumentation."
64
+ ::NewRelic::Agent.logger.debug('Not in transaction. Skipping browser instrumentation.')
66
65
  false
67
66
  elsif !state.is_execution_traced?
68
- ::NewRelic::Agent.logger.debug "Execution is not traced. Skipping browser instrumentation."
67
+ ::NewRelic::Agent.logger.debug('Execution is not traced. Skipping browser instrumentation.')
69
68
  false
70
69
  elsif state.current_transaction.ignore_enduser?
71
- ::NewRelic::Agent.logger.debug "Ignore end user for this transaction is set. Skipping browser instrumentation."
70
+ ::NewRelic::Agent.logger.debug('Ignore end user for this transaction is set. Skipping browser instrumentation.')
72
71
  false
73
72
  else
74
73
  true
75
74
  end
76
75
  rescue => e
77
- ::NewRelic::Agent.logger.debug "Failure during insert_js", e
76
+ ::NewRelic::Agent.logger.debug('Failure during insert_js', e)
78
77
  false
79
78
  end
80
79
 
@@ -83,72 +82,78 @@ module NewRelic
83
82
  value.nil? || value.empty?
84
83
  end
85
84
 
86
- def browser_timing_header #THREAD_LOCAL_ACCESS
85
+ def browser_timing_header(nonce = nil) # THREAD_LOCAL_ACCESS
87
86
  return '' unless js_enabled_and_ready? # fast exit
88
87
 
89
88
  state = NewRelic::Agent::Tracer.state
90
89
 
91
90
  return '' unless insert_js?(state) # slower exit
92
91
 
93
- bt_config = browser_timing_config(state)
92
+ bt_config = browser_timing_config(state, nonce)
94
93
  return '' if bt_config.empty?
95
94
 
96
- bt_config + browser_timing_loader
95
+ bt_config + browser_timing_loader(nonce)
97
96
  rescue => e
98
- ::NewRelic::Agent.logger.debug "Failure during RUM browser_timing_header construction", e
97
+ ::NewRelic::Agent.logger.debug('Failure during RUM browser_timing_header construction', e)
99
98
  ''
100
99
  end
101
100
 
102
- def browser_timing_loader
103
- html_safe_if_needed("\n<script>#{Agent.config[:js_agent_loader]}</script>")
101
+ def browser_timing_loader(nonce = nil)
102
+ html_safe_if_needed("\n<script type=\"text/javascript\"#{create_nonce(nonce)}>#{Agent.config[:js_agent_loader]}</script>")
104
103
  end
105
104
 
106
- def browser_timing_config(state)
105
+ def browser_timing_config(state, nonce = nil)
107
106
  txn = state.current_transaction
108
107
  return '' if txn.nil?
109
108
 
110
109
  txn.freeze_name_and_execute_if_not_ignored do
111
110
  data = data_for_js_agent(txn)
112
111
  json = ::JSON.dump(data)
113
- return html_safe_if_needed("\n<script>window.NREUM||(NREUM={});NREUM.info=#{json}</script>")
112
+ return html_safe_if_needed("\n<script type=\"text/javascript\"#{create_nonce(nonce)}>window.NREUM||(NREUM={});NREUM.info=#{json}</script>")
114
113
  end
115
114
 
116
115
  ''
117
116
  end
118
117
 
119
- BEACON_KEY = "beacon".freeze
120
- ERROR_BEACON_KEY = "errorBeacon".freeze
121
- LICENSE_KEY_KEY = "licenseKey".freeze
122
- APPLICATIONID_KEY = "applicationID".freeze
123
- TRANSACTION_NAME_KEY = "transactionName".freeze
124
- QUEUE_TIME_KEY = "queueTime".freeze
125
- APPLICATION_TIME_KEY = "applicationTime".freeze
126
- AGENT_KEY = "agent".freeze
127
- SSL_FOR_HTTP_KEY = "sslForHttp".freeze
128
- ATTS_KEY = "atts".freeze
129
- ATTS_USER_SUBKEY = "u".freeze
130
- ATTS_AGENT_SUBKEY = "a".freeze
118
+ def create_nonce(nonce = nil)
119
+ return '' unless nonce
120
+
121
+ " nonce=\"#{nonce.to_s}\""
122
+ end
123
+
124
+ BEACON_KEY = 'beacon'.freeze
125
+ ERROR_BEACON_KEY = 'errorBeacon'.freeze
126
+ LICENSE_KEY_KEY = 'licenseKey'.freeze
127
+ APPLICATIONID_KEY = 'applicationID'.freeze
128
+ TRANSACTION_NAME_KEY = 'transactionName'.freeze
129
+ QUEUE_TIME_KEY = 'queueTime'.freeze
130
+ APPLICATION_TIME_KEY = 'applicationTime'.freeze
131
+ AGENT_KEY = 'agent'.freeze
132
+ SSL_FOR_HTTP_KEY = 'sslForHttp'.freeze
133
+ ATTS_KEY = 'atts'.freeze
134
+ ATTS_USER_SUBKEY = 'u'.freeze
135
+ ATTS_AGENT_SUBKEY = 'a'.freeze
131
136
 
132
137
  # NOTE: Internal prototyping may override this, so leave name stable!
133
138
  def data_for_js_agent(transaction)
134
- queue_time_in_seconds = [transaction.queue_time.to_f, 0.0].max
135
- start_time_in_seconds = [transaction.start_time.to_f, 0.0].max
136
- app_time_in_seconds = Time.now.to_f - start_time_in_seconds
139
+ queue_time_in_seconds = [transaction.queue_time, 0.0].max
140
+ start_time_in_seconds = [transaction.start_time, 0.0].max
141
+ app_time_in_seconds = Process.clock_gettime(Process::CLOCK_REALTIME) - start_time_in_seconds
137
142
 
138
- queue_time_in_millis = (1000.0 * queue_time_in_seconds).round
139
- app_time_in_millis = (1000.0 * app_time_in_seconds).round
143
+ queue_time_in_millis = (queue_time_in_seconds * 1000.0).round
144
+ app_time_in_millis = (app_time_in_seconds * 1000.0).round
140
145
 
141
146
  transaction_name = transaction.best_name || ::NewRelic::Agent::UNKNOWN_METRIC
142
147
 
143
148
  data = {
144
- BEACON_KEY => NewRelic::Agent.config[:beacon],
145
- ERROR_BEACON_KEY => NewRelic::Agent.config[:error_beacon],
146
- LICENSE_KEY_KEY => NewRelic::Agent.config[:browser_key],
147
- APPLICATIONID_KEY => NewRelic::Agent.config[:application_id],
149
+ BEACON_KEY => NewRelic::Agent.config[:beacon],
150
+ ERROR_BEACON_KEY => NewRelic::Agent.config[:error_beacon],
151
+ LICENSE_KEY_KEY => NewRelic::Agent.config[:browser_key],
152
+ APPLICATIONID_KEY => NewRelic::Agent.config[:application_id],
148
153
  TRANSACTION_NAME_KEY => obfuscator.obfuscate(transaction_name),
149
- QUEUE_TIME_KEY => queue_time_in_millis,
154
+ QUEUE_TIME_KEY => queue_time_in_millis,
150
155
  APPLICATION_TIME_KEY => app_time_in_millis,
151
- AGENT_KEY => NewRelic::Agent.config[:js_agent_file]
156
+ AGENT_KEY => NewRelic::Agent.config[:js_agent_file]
152
157
  }
153
158
 
154
159
  add_ssl_for_http(data)
@@ -179,9 +184,14 @@ module NewRelic
179
184
 
180
185
  def append_custom_attributes!(txn, atts)
181
186
  custom_attributes = txn.attributes.custom_attributes_for(NewRelic::Agent::AttributeFilter::DST_BROWSER_MONITORING)
182
- unless custom_attributes.empty?
183
- atts[ATTS_USER_SUBKEY] = custom_attributes
187
+ if custom_attributes.empty?
188
+ NewRelic::Agent.logger.debug("#{self.class}: No custom attributes found to append.")
189
+ return
184
190
  end
191
+
192
+ NewRelic::Agent.logger.debug("#{self.class}: Appending the following custom attribute keys for browser " \
193
+ "monitoring: #{custom_attributes.keys}")
194
+ atts[ATTS_USER_SUBKEY] = custom_attributes
185
195
  end
186
196
 
187
197
  def append_agent_attributes!(txn, atts)
@@ -0,0 +1,44 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic
6
+ module Agent
7
+ #
8
+ # This module contains helper methods related to gathering linking
9
+ # metadata for use with logs in context.
10
+ module LinkingMetadata
11
+ extend self
12
+
13
+ def append_service_linking_metadata(metadata)
14
+ raise ArgumentError, 'Missing argument `metadata`' if metadata.nil?
15
+
16
+ config = ::NewRelic::Agent.config
17
+
18
+ metadata[ENTITY_NAME_KEY] = config[:app_name][0]
19
+ metadata[ENTITY_TYPE_KEY] = ENTITY_TYPE
20
+ metadata[HOSTNAME_KEY] = Hostname.get
21
+
22
+ if entity_guid = config[:entity_guid]
23
+ metadata[ENTITY_GUID_KEY] = entity_guid
24
+ end
25
+
26
+ metadata
27
+ end
28
+
29
+ def append_trace_linking_metadata(metadata)
30
+ raise ArgumentError, 'Missing argument `metadata`' if metadata.nil?
31
+
32
+ if trace_id = Tracer.current_trace_id
33
+ metadata[TRACE_ID_KEY] = trace_id
34
+ end
35
+
36
+ if span_id = Tracer.current_span_id
37
+ metadata[SPAN_ID_KEY] = span_id
38
+ end
39
+
40
+ metadata
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,37 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic
6
+ module Agent
7
+ # This module contains helper methods related to decorating log messages
8
+ module LocalLogDecorator
9
+ extend self
10
+
11
+ def decorate(message)
12
+ return message unless decorating_enabled?
13
+
14
+ metadata = NewRelic::Agent.linking_metadata
15
+ formatted_metadata = " NR-LINKING|#{metadata[ENTITY_GUID_KEY]}|#{metadata[HOSTNAME_KEY]}|" \
16
+ "#{metadata[TRACE_ID_KEY]}|#{metadata[SPAN_ID_KEY]}|" \
17
+ "#{escape_entity_name(metadata[ENTITY_NAME_KEY])}|"
18
+
19
+ message.partition("\n").insert(1, formatted_metadata).join
20
+ end
21
+
22
+ private
23
+
24
+ def decorating_enabled?
25
+ NewRelic::Agent.config[:'application_logging.enabled'] &&
26
+ NewRelic::Agent::Instrumentation::Logger.enabled? &&
27
+ NewRelic::Agent.config[:'application_logging.local_decorating.enabled']
28
+ end
29
+
30
+ def escape_entity_name(entity_name)
31
+ return unless entity_name
32
+
33
+ URI::DEFAULT_PARSER.escape(entity_name)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,282 @@
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/event_aggregator'
6
+ require 'new_relic/agent/log_priority'
7
+ require 'new_relic/agent/log_event_attributes'
8
+
9
+ module NewRelic
10
+ module Agent
11
+ class LogEventAggregator < EventAggregator
12
+ # Per-message keys
13
+ LEVEL_KEY = 'level'.freeze
14
+ MESSAGE_KEY = 'message'.freeze
15
+ TIMESTAMP_KEY = 'timestamp'.freeze
16
+ PRIORITY_KEY = 'priority'.freeze
17
+
18
+ # Metric keys
19
+ LINES = 'Logging/lines'.freeze
20
+ DROPPED_METRIC = 'Logging/Forwarding/Dropped'.freeze
21
+ SEEN_METRIC = 'Supportability/Logging/Forwarding/Seen'.freeze
22
+ SENT_METRIC = 'Supportability/Logging/Forwarding/Sent'.freeze
23
+ OVERALL_SUPPORTABILITY_FORMAT = 'Supportability/Logging/Ruby/Logger/%s'.freeze
24
+ METRICS_SUPPORTABILITY_FORMAT = 'Supportability/Logging/Metrics/Ruby/%s'.freeze
25
+ FORWARDING_SUPPORTABILITY_FORMAT = 'Supportability/Logging/Forwarding/Ruby/%s'.freeze
26
+ DECORATING_SUPPORTABILITY_FORMAT = 'Supportability/Logging/LocalDecorating/Ruby/%s'.freeze
27
+ MAX_BYTES = 32768 # 32 * 1024 bytes (32 kibibytes)
28
+
29
+ named :LogEventAggregator
30
+ buffer_class PrioritySampledBuffer
31
+
32
+ capacity_key :'application_logging.forwarding.max_samples_stored'
33
+ enabled_key :'application_logging.enabled'
34
+
35
+ # Config keys
36
+ OVERALL_ENABLED_KEY = :'application_logging.enabled'
37
+ METRICS_ENABLED_KEY = :'application_logging.metrics.enabled'
38
+ FORWARDING_ENABLED_KEY = :'application_logging.forwarding.enabled'
39
+ DECORATING_ENABLED_KEY = :'application_logging.local_decorating.enabled'
40
+ LOG_LEVEL_KEY = :'application_logging.forwarding.log_level'
41
+ CUSTOM_ATTRIBUTES_KEY = :'application_logging.forwarding.custom_attributes'
42
+
43
+ attr_reader :attributes
44
+
45
+ def initialize(events)
46
+ super(events)
47
+ @counter_lock = Mutex.new
48
+ @seen = 0
49
+ @seen_by_severity = Hash.new(0)
50
+ @high_security = NewRelic::Agent.config[:high_security]
51
+ @instrumentation_logger_enabled = NewRelic::Agent::Instrumentation::Logger.enabled?
52
+ @attributes = NewRelic::Agent::LogEventAttributes.new
53
+ register_for_done_configuring(events)
54
+ end
55
+
56
+ def capacity
57
+ @buffer.capacity
58
+ end
59
+
60
+ def record(formatted_message, severity)
61
+ return unless enabled?
62
+
63
+ severity = 'UNKNOWN' if severity.nil? || severity.empty?
64
+
65
+ if NewRelic::Agent.config[METRICS_ENABLED_KEY]
66
+ @counter_lock.synchronize do
67
+ @seen += 1
68
+ @seen_by_severity[severity] += 1
69
+ end
70
+ end
71
+
72
+ return if severity_too_low?(severity)
73
+ return if formatted_message.nil? || formatted_message.empty?
74
+ return unless NewRelic::Agent.config[FORWARDING_ENABLED_KEY]
75
+ return if @high_security
76
+
77
+ txn = NewRelic::Agent::Transaction.tl_current
78
+ priority = LogPriority.priority_for(txn)
79
+
80
+ if txn
81
+ return txn.add_log_event(create_event(priority, formatted_message, severity))
82
+ else
83
+ return @lock.synchronize do
84
+ @buffer.append(priority: priority) do
85
+ create_event(priority, formatted_message, severity)
86
+ end
87
+ end
88
+ end
89
+ rescue
90
+ nil
91
+ end
92
+
93
+ def record_batch(txn, logs)
94
+ # Ensure we have the same shared priority
95
+ priority = LogPriority.priority_for(txn)
96
+ logs.each do |log|
97
+ log.first[PRIORITY_KEY] = priority
98
+ end
99
+
100
+ @lock.synchronize do
101
+ logs.each do |log|
102
+ @buffer.append(event: log)
103
+ end
104
+ end
105
+ end
106
+
107
+ def create_event(priority, formatted_message, severity)
108
+ formatted_message = truncate_message(formatted_message)
109
+
110
+ event = LinkingMetadata.append_trace_linking_metadata({
111
+ LEVEL_KEY => severity,
112
+ MESSAGE_KEY => formatted_message,
113
+ TIMESTAMP_KEY => Process.clock_gettime(Process::CLOCK_REALTIME) * 1000
114
+ })
115
+
116
+ [
117
+ {
118
+ PrioritySampledBuffer::PRIORITY_KEY => priority
119
+ },
120
+ event
121
+ ]
122
+ end
123
+
124
+ def add_custom_attributes(custom_attributes)
125
+ attributes.add_custom_attributes(custom_attributes)
126
+ end
127
+
128
+ # Because our transmission format (MELT) is different than historical
129
+ # agent payloads, extract the munging here to keep the service focused
130
+ # on the general harvest + transmit instead of the format.
131
+ #
132
+ # Payload shape matches the publicly documented MELT format.
133
+ # https://docs.newrelic.com/docs/logs/log-api/introduction-log-api
134
+ #
135
+ # We have to keep the aggregated payloads in a separate shape, though, to
136
+ # work with the priority sampling buffers
137
+ def self.payload_to_melt_format(data)
138
+ common_attributes = LinkingMetadata.append_service_linking_metadata({})
139
+
140
+ # To save on unnecessary data transmission, trim the entity.type
141
+ # sent by classic logs-in-context
142
+ common_attributes.delete(ENTITY_TYPE_KEY)
143
+
144
+ common_attributes.merge!(NewRelic::Agent.agent.log_event_aggregator.attributes.custom_attributes)
145
+
146
+ _, items = data
147
+ payload = [{
148
+ common: {attributes: common_attributes},
149
+ logs: items.map(&:last)
150
+ }]
151
+
152
+ return [payload, items.size]
153
+ end
154
+
155
+ def harvest!
156
+ record_customer_metrics()
157
+ super
158
+ end
159
+
160
+ def reset!
161
+ @counter_lock.synchronize do
162
+ @seen = 0
163
+ @seen_by_severity.clear
164
+ end
165
+
166
+ super
167
+ end
168
+
169
+ def enabled?
170
+ @enabled && @instrumentation_logger_enabled
171
+ end
172
+
173
+ private
174
+
175
+ # We record once-per-connect metrics for enabled/disabled state at the
176
+ # point we consider the configuration stable (i.e. once we've gotten SSC)
177
+ def register_for_done_configuring(events)
178
+ events.subscribe(:server_source_configuration_added) do
179
+ @high_security = NewRelic::Agent.config[:high_security]
180
+
181
+ record_configuration_metric(OVERALL_SUPPORTABILITY_FORMAT, OVERALL_ENABLED_KEY)
182
+ record_configuration_metric(METRICS_SUPPORTABILITY_FORMAT, METRICS_ENABLED_KEY)
183
+ record_configuration_metric(FORWARDING_SUPPORTABILITY_FORMAT, FORWARDING_ENABLED_KEY)
184
+ record_configuration_metric(DECORATING_SUPPORTABILITY_FORMAT, DECORATING_ENABLED_KEY)
185
+
186
+ add_custom_attributes(NewRelic::Agent.config[CUSTOM_ATTRIBUTES_KEY])
187
+ end
188
+ end
189
+
190
+ def record_configuration_metric(format, key)
191
+ state = NewRelic::Agent.config[key]
192
+ label = if !enabled?
193
+ 'disabled'
194
+ else
195
+ state ? 'enabled' : 'disabled'
196
+ end
197
+ NewRelic::Agent.increment_metric(format % label)
198
+ end
199
+
200
+ def after_harvest(metadata)
201
+ dropped_count = metadata[:seen] - metadata[:captured]
202
+ note_dropped_events(metadata[:seen], dropped_count)
203
+ record_supportability_metrics(metadata[:seen], metadata[:captured], dropped_count)
204
+ end
205
+
206
+ # To avoid paying the cost of metric recording on every line, we hold
207
+ # these until harvest before recording them
208
+ def record_customer_metrics
209
+ return unless enabled?
210
+ return unless NewRelic::Agent.config[METRICS_ENABLED_KEY]
211
+
212
+ @counter_lock.synchronize do
213
+ return unless @seen > 0
214
+
215
+ NewRelic::Agent.increment_metric(LINES, @seen)
216
+ @seen_by_severity.each do |(severity, count)|
217
+ NewRelic::Agent.increment_metric(line_metric_name_by_severity(severity), count)
218
+ end
219
+
220
+ @seen = 0
221
+ @seen_by_severity.clear
222
+ end
223
+ end
224
+
225
+ def line_metric_name_by_severity(severity)
226
+ @line_metrics ||= {}
227
+ @line_metrics[severity] ||= "Logging/lines/#{severity}".freeze
228
+ end
229
+
230
+ def note_dropped_events(total_count, dropped_count)
231
+ if dropped_count > 0
232
+ NewRelic::Agent.logger.warn("Dropped #{dropped_count} log events out of #{total_count}.")
233
+ end
234
+ end
235
+
236
+ def record_supportability_metrics(total_count, captured_count, dropped_count)
237
+ return unless total_count > 0
238
+
239
+ NewRelic::Agent.increment_metric(DROPPED_METRIC, dropped_count)
240
+ NewRelic::Agent.increment_metric(SEEN_METRIC, total_count)
241
+ NewRelic::Agent.increment_metric(SENT_METRIC, captured_count)
242
+ end
243
+
244
+ def truncate_message(message)
245
+ return message if message.bytesize <= MAX_BYTES
246
+
247
+ message.byteslice(0...MAX_BYTES)
248
+ end
249
+
250
+ def minimum_log_level
251
+ if Logger::Severity.constants.include?(configured_log_level_constant)
252
+ configured_log_level_constant
253
+ else
254
+ NewRelic::Agent.logger.log_once(
255
+ :error,
256
+ 'Invalid application_logging.forwarding.log_level ' \
257
+ "'#{NewRelic::Agent.config[LOG_LEVEL_KEY]}' specified! " \
258
+ "Must be one of #{Logger::Severity.constants.join('|')}. " \
259
+ "Using default level of 'debug'"
260
+ )
261
+ :DEBUG
262
+ end
263
+ end
264
+
265
+ def configured_log_level_constant
266
+ format_log_level_constant(NewRelic::Agent.config[LOG_LEVEL_KEY])
267
+ end
268
+
269
+ def format_log_level_constant(log_level)
270
+ log_level.upcase.to_sym
271
+ end
272
+
273
+ def severity_too_low?(severity)
274
+ severity_constant = format_log_level_constant(severity)
275
+ # always record custom log levels
276
+ return false unless Logger::Severity.constants.include?(severity_constant)
277
+
278
+ Logger::Severity.const_get(severity_constant) < Logger::Severity.const_get(minimum_log_level)
279
+ end
280
+ end
281
+ end
282
+ end
@@ -0,0 +1,115 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic
6
+ module Agent
7
+ class LogEventAttributes
8
+ MAX_ATTRIBUTE_COUNT = 240 # limit is 255, assume we send 15
9
+ ATTRIBUTE_KEY_CHARACTER_LIMIT = 255
10
+ ATTRIBUTE_VALUE_CHARACTER_LIMIT = 4094
11
+
12
+ def add_custom_attributes(attributes)
13
+ return if defined?(@custom_attribute_limit_reached) && @custom_attribute_limit_reached
14
+
15
+ attributes.each do |key, value|
16
+ next if absent?(key) || absent?(value)
17
+
18
+ add_custom_attribute(key, value)
19
+ end
20
+ end
21
+
22
+ def custom_attributes
23
+ @custom_attributes ||= {}
24
+ end
25
+
26
+ private
27
+
28
+ class TruncationError < StandardError
29
+ attr_reader :attribute, :limit
30
+
31
+ def initialize(attribute, limit, msg = "Can't truncate")
32
+ @attribute = attribute
33
+ @limit = limit
34
+ super(msg)
35
+ end
36
+ end
37
+
38
+ class InvalidTypeError < StandardError
39
+ attr_reader :attribute
40
+
41
+ def initialize(attribute, msg = 'Invalid attribute type')
42
+ @attribute = attribute
43
+ super(msg)
44
+ end
45
+ end
46
+
47
+ def absent?(value)
48
+ value.nil? || (value.respond_to?(:empty?) && value.empty?)
49
+ end
50
+
51
+ def add_custom_attribute(key, value)
52
+ if custom_attributes.size >= MAX_ATTRIBUTE_COUNT
53
+ NewRelic::Agent.logger.warn(
54
+ 'Too many custom log attributes defined. ' \
55
+ "Only taking the first #{MAX_ATTRIBUTE_COUNT}."
56
+ )
57
+ @custom_attribute_limit_reached = true
58
+ return
59
+ end
60
+
61
+ @custom_attributes.merge!(truncate_attributes(key_to_string(key), value))
62
+ end
63
+
64
+ def key_to_string(key)
65
+ key.is_a?(String) ? key : key.to_s
66
+ end
67
+
68
+ def truncate_attribute(attribute, limit)
69
+ case attribute
70
+ when Integer
71
+ if attribute.digits.length > limit
72
+ raise TruncationError.new(attribute, limit)
73
+ end
74
+ when Float
75
+ if attribute.to_s.length > limit
76
+ raise TruncationError.new(attribute, limit)
77
+ end
78
+ when String, Symbol
79
+ if attribute.length > limit
80
+ attribute = attribute.slice(0..(limit - 1))
81
+ end
82
+ when TrueClass, FalseClass
83
+ attribute
84
+ else
85
+ raise InvalidTypeError.new(attribute)
86
+ end
87
+
88
+ attribute
89
+ end
90
+
91
+ def truncate_attributes(key, value)
92
+ key = truncate_attribute(key, ATTRIBUTE_KEY_CHARACTER_LIMIT)
93
+ value = truncate_attribute(value, ATTRIBUTE_VALUE_CHARACTER_LIMIT)
94
+
95
+ {key => value}
96
+ rescue TruncationError => e
97
+ NewRelic::Agent.logger.warn(
98
+ "Dropping custom log attribute #{key} => #{value} \n" \
99
+ "Length exceeds character limit of #{e.limit}. " \
100
+ "Can't truncate: #{e.attribute}"
101
+ )
102
+
103
+ {}
104
+ rescue InvalidTypeError => e
105
+ NewRelic::Agent.logger.warn(
106
+ "Dropping custom log attribute #{key} => #{value} \n" \
107
+ "Invalid type of #{e.attribute.class} given. " \
108
+ "Can't send #{e.attribute}."
109
+ )
110
+
111
+ {}
112
+ end
113
+ end
114
+ end
115
+ end