newrelic_rpm 6.3.0.355 → 9.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (468) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -1
  3. data/.rubocop.yml +1845 -0
  4. data/.rubocop_todo.yml +61 -0
  5. data/.simplecov +16 -0
  6. data/.snyk +11 -0
  7. data/.yardopts +1 -0
  8. data/Brewfile +13 -0
  9. data/CHANGELOG.md +4102 -2416
  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 +25 -6
  15. data/LICENSE +202 -38
  16. data/README.md +86 -87
  17. data/Rakefile +32 -32
  18. data/THIRD_PARTY_NOTICES.md +28 -0
  19. data/Thorfile +5 -0
  20. data/bin/newrelic +4 -2
  21. data/bin/newrelic_cmd +2 -0
  22. data/bin/nrdebug +86 -63
  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 +115 -882
  30. data/lib/new_relic/agent/agent_helpers/connect.rb +222 -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 +175 -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 +30 -22
  38. data/lib/new_relic/agent/attribute_filter.rb +70 -53
  39. data/lib/new_relic/agent/attribute_processing.rb +10 -10
  40. data/lib/new_relic/agent/attributes.rb +153 -0
  41. data/lib/new_relic/agent/audit_logger.rb +22 -7
  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 +5 -5
  45. data/lib/new_relic/agent/commands/agent_command_router.rb +18 -35
  46. data/lib/new_relic/agent/commands/thread_profiler_session.rb +17 -15
  47. data/lib/new_relic/agent/configuration/default_source.rb +1456 -1100
  48. data/lib/new_relic/agent/configuration/dotted_hash.rb +7 -6
  49. data/lib/new_relic/agent/configuration/environment_source.rb +17 -13
  50. data/lib/new_relic/agent/configuration/event_harvest_config.rb +68 -0
  51. data/lib/new_relic/agent/configuration/high_security_source.rb +12 -12
  52. data/lib/new_relic/agent/configuration/manager.rb +97 -80
  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 +93 -96
  56. data/lib/new_relic/agent/configuration/server_source.rb +66 -40
  57. data/lib/new_relic/agent/configuration/yaml_source.rb +44 -15
  58. data/lib/new_relic/agent/configuration.rb +2 -2
  59. data/lib/new_relic/agent/connect/request_builder.rb +25 -27
  60. data/lib/new_relic/agent/connect/response_handler.rb +7 -10
  61. data/lib/new_relic/agent/custom_event_aggregator.rb +16 -16
  62. data/lib/new_relic/agent/database/explain_plan_helpers.rb +6 -7
  63. data/lib/new_relic/agent/database/obfuscation_helpers.rb +18 -17
  64. data/lib/new_relic/agent/database/obfuscator.rb +5 -5
  65. data/lib/new_relic/agent/database/postgres_explain_obfuscator.rb +4 -4
  66. data/lib/new_relic/agent/database.rb +47 -56
  67. data/lib/new_relic/agent/database_adapter.rb +35 -0
  68. data/lib/new_relic/agent/datastores/metric_helper.rb +22 -23
  69. data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +9 -8
  70. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +18 -22
  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 +10 -16
  74. data/lib/new_relic/agent/datastores.rb +14 -16
  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} +90 -70
  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 +129 -65
  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 +11 -8
  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 +28 -26
  94. data/lib/new_relic/agent/external.rb +19 -52
  95. data/lib/new_relic/agent/guid_generator.rb +30 -0
  96. data/lib/new_relic/agent/harvester.rb +6 -9
  97. data/lib/new_relic/agent/heap.rb +9 -10
  98. data/lib/new_relic/agent/hostname.rb +22 -9
  99. data/lib/new_relic/agent/http_clients/abstract.rb +69 -0
  100. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +30 -26
  101. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +37 -21
  102. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +22 -23
  103. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +18 -17
  104. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +28 -8
  105. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +17 -17
  106. data/lib/new_relic/agent/http_clients/uri_util.rb +13 -14
  107. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +22 -55
  108. data/lib/new_relic/agent/instrumentation/action_controller_other_subscriber.rb +42 -0
  109. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +60 -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 +34 -14
  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 +97 -47
  121. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +97 -73
  122. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +70 -76
  123. data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +36 -12
  124. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +65 -66
  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 -138
  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 +75 -63
  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 +16 -201
  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 +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 +31 -52
  152. data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +29 -0
  153. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +67 -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 +10 -8
  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 +17 -124
  166. data/lib/new_relic/agent/instrumentation/grpc/client/chain.rb +97 -0
  167. data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +90 -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 +6 -7
  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 +60 -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 +103 -0
  195. data/lib/new_relic/agent/instrumentation/memcache.rb +57 -71
  196. data/lib/new_relic/agent/instrumentation/middleware_proxy.rb +16 -15
  197. data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +11 -11
  198. data/lib/new_relic/agent/instrumentation/mongo.rb +7 -132
  199. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +53 -17
  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 +22 -57
  217. data/lib/new_relic/agent/instrumentation/rails_middleware.rb +5 -5
  218. data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +10 -10
  219. data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +18 -6
  220. data/lib/new_relic/agent/instrumentation/rails_notifications/action_view.rb +9 -6
  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 -158
  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 +94 -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 +13 -13
  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 +30 -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 +126 -0
  246. data/lib/new_relic/agent/instrumentation/sinatra/prepend.rb +33 -0
  247. data/lib/new_relic/agent/instrumentation/sinatra/transaction_namer.rb +4 -4
  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 +42 -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 +60 -49
  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 +182 -0
  270. data/lib/new_relic/agent/memory_logger.rb +3 -3
  271. data/lib/new_relic/agent/messaging.rb +74 -156
  272. data/lib/new_relic/agent/method_tracer.rb +157 -150
  273. data/lib/new_relic/agent/method_tracer_helpers.rb +89 -12
  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} +8 -13
  278. data/lib/new_relic/agent/monitors.rb +26 -0
  279. data/lib/new_relic/agent/new_relic_service/encoders.rb +8 -8
  280. data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +7 -7
  281. data/lib/new_relic/agent/new_relic_service/marshaller.rb +3 -3
  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 +273 -202
  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 +30 -16
  288. data/lib/new_relic/agent/payload_metric_mapping.rb +10 -11
  289. data/lib/new_relic/agent/pipe_channel_manager.rb +34 -23
  290. data/lib/new_relic/agent/pipe_service.rb +14 -9
  291. data/lib/new_relic/agent/prepend_supportability.rb +3 -3
  292. data/lib/new_relic/agent/priority_sampled_buffer.rb +17 -15
  293. data/lib/new_relic/agent/rules_engine/replacement_rule.rb +12 -12
  294. data/lib/new_relic/agent/rules_engine/segment_terms_rule.rb +13 -14
  295. data/lib/new_relic/agent/rules_engine.rb +6 -5
  296. data/lib/new_relic/agent/sampler.rb +6 -6
  297. data/lib/new_relic/agent/sampler_collection.rb +5 -6
  298. data/lib/new_relic/agent/samplers/cpu_sampler.rb +9 -8
  299. data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +21 -18
  300. data/lib/new_relic/agent/samplers/memory_sampler.rb +33 -22
  301. data/lib/new_relic/agent/samplers/object_sampler.rb +3 -3
  302. data/lib/new_relic/agent/samplers/vm_sampler.rb +22 -20
  303. data/lib/new_relic/agent/span_event_aggregator.rb +17 -19
  304. data/lib/new_relic/agent/span_event_primitive.rb +118 -58
  305. data/lib/new_relic/agent/sql_sampler.rb +23 -23
  306. data/lib/new_relic/agent/stats.rb +80 -43
  307. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +11 -13
  308. data/lib/new_relic/agent/stats_engine/stats_hash.rb +13 -14
  309. data/lib/new_relic/agent/stats_engine.rb +9 -9
  310. data/lib/new_relic/agent/synthetics_event_aggregator.rb +9 -10
  311. data/lib/new_relic/agent/system_info.rb +97 -68
  312. data/lib/new_relic/agent/threading/agent_thread.rb +19 -15
  313. data/lib/new_relic/agent/threading/backtrace_node.rb +13 -14
  314. data/lib/new_relic/agent/threading/backtrace_service.rb +21 -25
  315. data/lib/new_relic/agent/threading/thread_profile.rb +32 -46
  316. data/lib/new_relic/agent/timestamp_sampled_buffer.rb +3 -3
  317. data/lib/new_relic/agent/tracer.rb +159 -107
  318. data/lib/new_relic/agent/transaction/abstract_segment.rb +147 -51
  319. data/lib/new_relic/agent/transaction/datastore_segment.rb +23 -19
  320. data/lib/new_relic/agent/transaction/distributed_tracer.rb +185 -0
  321. data/lib/new_relic/agent/transaction/distributed_tracing.rb +73 -164
  322. data/lib/new_relic/agent/transaction/external_request_segment.rb +67 -64
  323. data/lib/new_relic/agent/transaction/message_broker_segment.rb +34 -46
  324. data/lib/new_relic/agent/transaction/request_attributes.rb +40 -40
  325. data/lib/new_relic/agent/transaction/segment.rb +46 -10
  326. data/lib/new_relic/agent/transaction/slowest_sample_buffer.rb +2 -4
  327. data/lib/new_relic/agent/transaction/synthetics_sample_buffer.rb +3 -3
  328. data/lib/new_relic/agent/transaction/trace.rb +22 -25
  329. data/lib/new_relic/agent/transaction/trace_builder.rb +11 -12
  330. data/lib/new_relic/agent/transaction/trace_context.rb +168 -0
  331. data/lib/new_relic/agent/transaction/trace_node.rb +36 -32
  332. data/lib/new_relic/agent/transaction/tracing.rb +16 -13
  333. data/lib/new_relic/agent/transaction/transaction_sample_buffer.rb +7 -7
  334. data/lib/new_relic/agent/transaction.rb +248 -205
  335. data/lib/new_relic/agent/transaction_error_primitive.rb +34 -37
  336. data/lib/new_relic/agent/transaction_event_aggregator.rb +17 -17
  337. data/lib/new_relic/agent/transaction_event_primitive.rb +44 -56
  338. data/lib/new_relic/agent/transaction_event_recorder.rb +17 -16
  339. data/lib/new_relic/agent/transaction_metrics.rb +11 -10
  340. data/lib/new_relic/agent/transaction_sampler.rb +9 -14
  341. data/lib/new_relic/agent/transaction_time_aggregator.rb +33 -28
  342. data/lib/new_relic/agent/utilization/aws.rb +35 -5
  343. data/lib/new_relic/agent/utilization/azure.rb +7 -7
  344. data/lib/new_relic/agent/utilization/gcp.rb +11 -11
  345. data/lib/new_relic/agent/utilization/pcf.rb +7 -6
  346. data/lib/new_relic/agent/utilization/vendor.rb +45 -30
  347. data/lib/new_relic/agent/utilization_data.rb +8 -6
  348. data/lib/new_relic/agent/vm/jruby_vm.rb +2 -2
  349. data/lib/new_relic/agent/vm/monotonic_gc_profiler.rb +4 -4
  350. data/lib/new_relic/agent/vm/mri_vm.rb +54 -26
  351. data/lib/new_relic/agent/vm/snapshot.rb +6 -6
  352. data/lib/new_relic/agent/vm.rb +2 -2
  353. data/lib/new_relic/agent/worker_loop.rb +11 -13
  354. data/lib/new_relic/agent.rb +219 -89
  355. data/lib/new_relic/cli/command.rb +22 -24
  356. data/lib/new_relic/cli/commands/deployments.rb +102 -52
  357. data/lib/new_relic/cli/commands/install.rb +33 -35
  358. data/lib/new_relic/coerce.rb +42 -15
  359. data/lib/new_relic/collection_helper.rb +51 -49
  360. data/lib/new_relic/constants.rb +38 -0
  361. data/lib/new_relic/control/class_methods.rb +6 -6
  362. data/lib/new_relic/control/frameworks/external.rb +3 -3
  363. data/lib/new_relic/control/frameworks/rails.rb +50 -32
  364. data/lib/new_relic/control/frameworks/rails3.rb +4 -5
  365. data/lib/new_relic/control/frameworks/rails4.rb +2 -2
  366. data/lib/new_relic/control/frameworks/rails_notifications.rb +2 -2
  367. data/lib/new_relic/control/frameworks/ruby.rb +4 -4
  368. data/lib/new_relic/control/frameworks/sinatra.rb +8 -2
  369. data/lib/new_relic/control/frameworks.rb +2 -2
  370. data/lib/new_relic/control/instance_methods.rb +33 -42
  371. data/lib/new_relic/control/instrumentation.rb +40 -12
  372. data/lib/new_relic/control/private_instance_methods.rb +48 -0
  373. data/lib/new_relic/control/server_methods.rb +4 -5
  374. data/lib/new_relic/control.rb +2 -3
  375. data/lib/new_relic/delayed_job_injection.rb +2 -2
  376. data/lib/new_relic/dependency_detection.rb +129 -31
  377. data/lib/new_relic/environment_report.rb +42 -36
  378. data/lib/new_relic/helper.rb +50 -8
  379. data/lib/new_relic/language_support.rb +31 -7
  380. data/lib/new_relic/latest_changes.rb +11 -10
  381. data/lib/new_relic/local_environment.rb +23 -27
  382. data/lib/new_relic/metric_data.rb +32 -27
  383. data/lib/new_relic/metric_spec.rb +9 -7
  384. data/lib/new_relic/noticed_error.rb +60 -45
  385. data/lib/new_relic/rack/agent_hooks.rb +2 -2
  386. data/lib/new_relic/rack/agent_middleware.rb +6 -4
  387. data/lib/new_relic/rack/browser_monitoring.rb +136 -115
  388. data/lib/new_relic/rack.rb +2 -2
  389. data/lib/new_relic/recipes/capistrano3.rb +5 -63
  390. data/lib/new_relic/recipes/capistrano_legacy.rb +25 -28
  391. data/lib/new_relic/recipes/helpers/send_deployment.rb +70 -0
  392. data/lib/new_relic/recipes.rb +2 -2
  393. data/lib/new_relic/supportability_helper.rb +23 -7
  394. data/lib/new_relic/traced_thread.rb +39 -0
  395. data/lib/new_relic/version.rb +7 -18
  396. data/lib/newrelic_rpm.rb +21 -34
  397. data/lib/sequel/extensions/{newrelic_instrumentation.rb → new_relic_instrumentation.rb} +18 -21
  398. data/lib/sequel/plugins/{newrelic_instrumentation.rb → new_relic_instrumentation.rb} +10 -16
  399. data/lib/tasks/all.rb +4 -4
  400. data/lib/tasks/config.rake +24 -120
  401. data/lib/tasks/coverage_report.rake +28 -0
  402. data/lib/tasks/helpers/config.html.erb +21 -0
  403. data/lib/tasks/helpers/format.rb +123 -0
  404. data/lib/tasks/helpers/matches.rb +12 -0
  405. data/lib/tasks/helpers/prompt.rb +24 -0
  406. data/lib/tasks/helpers/removers.rb +33 -0
  407. data/lib/tasks/install.rake +8 -4
  408. data/lib/tasks/instrumentation_generator/README.md +63 -0
  409. data/lib/tasks/instrumentation_generator/TODO.md +33 -0
  410. data/lib/tasks/instrumentation_generator/instrumentation.thor +121 -0
  411. data/lib/tasks/instrumentation_generator/templates/Envfile.tt +9 -0
  412. data/lib/tasks/instrumentation_generator/templates/chain.tt +22 -0
  413. data/lib/tasks/instrumentation_generator/templates/chain_method.tt +8 -0
  414. data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +29 -0
  415. data/lib/tasks/instrumentation_generator/templates/instrumentation.tt +13 -0
  416. data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +3 -0
  417. data/lib/tasks/instrumentation_generator/templates/newrelic.yml.tt +19 -0
  418. data/lib/tasks/instrumentation_generator/templates/prepend.tt +13 -0
  419. data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +3 -0
  420. data/lib/tasks/instrumentation_generator/templates/test.tt +15 -0
  421. data/lib/tasks/multiverse.rake +4 -0
  422. data/lib/tasks/multiverse.rb +23 -9
  423. data/lib/tasks/newrelic.rb +3 -2
  424. data/lib/tasks/tests.rake +17 -17
  425. data/newrelic.yml +672 -3
  426. data/newrelic_rpm.gemspec +50 -34
  427. data/recipes/newrelic.rb +3 -3
  428. data/test/agent_helper.rb +414 -98
  429. metadata +302 -93
  430. data/.travis.yml +0 -170
  431. data/bin/mongrel_rpm +0 -33
  432. data/cert/cacert.pem +0 -1177
  433. data/lib/new_relic/agent/commands/xray_session.rb +0 -55
  434. data/lib/new_relic/agent/commands/xray_session_collection.rb +0 -161
  435. data/lib/new_relic/agent/configuration/event_data.rb +0 -39
  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 -40
  440. data/lib/new_relic/agent/distributed_trace_payload.rb +0 -242
  441. data/lib/new_relic/agent/http_clients/abstract_request.rb +0 -31
  442. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +0 -74
  443. data/lib/new_relic/agent/instrumentation/authlogic.rb +0 -25
  444. data/lib/new_relic/agent/instrumentation/data_mapper.rb +0 -202
  445. data/lib/new_relic/agent/instrumentation/evented_subscriber.rb +0 -135
  446. data/lib/new_relic/agent/instrumentation/excon/connection.rb +0 -46
  447. data/lib/new_relic/agent/instrumentation/http.rb +0 -46
  448. data/lib/new_relic/agent/instrumentation/merb/controller.rb +0 -44
  449. data/lib/new_relic/agent/instrumentation/merb/errors.rb +0 -33
  450. data/lib/new_relic/agent/instrumentation/net.rb +0 -50
  451. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +0 -125
  452. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +0 -46
  453. data/lib/new_relic/agent/instrumentation/rainbows_instrumentation.rb +0 -26
  454. data/lib/new_relic/agent/instrumentation/sunspot.rb +0 -33
  455. data/lib/new_relic/agent/range_extensions.rb +0 -47
  456. data/lib/new_relic/agent/supported_versions.rb +0 -275
  457. data/lib/new_relic/agent/transaction/attributes.rb +0 -154
  458. data/lib/new_relic/agent/transaction/xray_sample_buffer.rb +0 -64
  459. data/lib/new_relic/build.rb +0 -2
  460. data/lib/new_relic/control/frameworks/merb.rb +0 -29
  461. data/lib/new_relic/metrics.rb +0 -13
  462. data/lib/tasks/config.html.erb +0 -32
  463. data/lib/tasks/versions.html.erb +0 -28
  464. data/lib/tasks/versions.postface.html +0 -8
  465. data/lib/tasks/versions.preface.html +0 -9
  466. data/lib/tasks/versions.rake +0 -65
  467. data/lib/tasks/versions.txt.erb +0 -14
  468. /data/lib/tasks/{config.text.erb → helpers/config.text.erb} +0 -0
@@ -0,0 +1,123 @@
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 Format
6
+ def output(format)
7
+ config_hash = build_config_hash
8
+ sections = flatten_config_hash(config_hash)
9
+
10
+ puts build_erb(format).result(binding).split("\n").map(&:rstrip).join("\n").gsub('. ', '. ')
11
+ sections # silences unused warning to return this
12
+ end
13
+
14
+ private
15
+
16
+ def add_data_to_sections(sections)
17
+ sections.each do |section|
18
+ section_key = section[0]
19
+ section.insert(1, format_name(section_key))
20
+ section.insert(2, SECTION_DESCRIPTIONS[section_key])
21
+ end
22
+ end
23
+
24
+ def build_config_hash
25
+ sections = Hash.new { |hash, key| hash[key] = [] }
26
+ NewRelic::Agent::Configuration::DEFAULTS.each do |key, value|
27
+ next unless value[:public]
28
+
29
+ key = key.to_s
30
+ section_key = section_key(key, key.split('.'))
31
+ sections[section_key] << format_sections(key, value)
32
+ end
33
+ sections
34
+ end
35
+
36
+ def build_erb(format)
37
+ require 'erb'
38
+ path = File.join(File.dirname(__FILE__), "config.#{format}.erb")
39
+ template = File.read(File.expand_path(path))
40
+ ERB.new(template)
41
+ end
42
+
43
+ def flatten_config_hash(config_hash)
44
+ sections = []
45
+ config = [GENERAL, 'transaction_tracer', 'error_collector',
46
+ 'browser_monitoring', 'transaction_events',
47
+ 'application_logging']
48
+
49
+ config.each { |config| sections << pluck(config, config_hash) }
50
+
51
+ sections.concat(config_hash.to_a.sort_by { |a| a.first })
52
+ add_data_to_sections(sections)
53
+
54
+ sections
55
+ end
56
+
57
+ def format_default_value(spec)
58
+ return spec[:documentation_default] if !spec[:documentation_default].nil?
59
+
60
+ if spec[:default].is_a?(Proc)
61
+ '(Dynamic)'
62
+ else
63
+ "#{spec[:default].inspect}"
64
+ end
65
+ end
66
+
67
+ def format_description(value)
68
+ description = ''
69
+ description += '<b>DEPRECATED</b> ' if value[:deprecated]
70
+ description += value[:description]
71
+ description
72
+ end
73
+
74
+ def format_env_var(key)
75
+ return 'None' if NON_ENV_CONFIGS.include?(key)
76
+
77
+ "NEW_RELIC_#{key.tr('.', '_').upcase}"
78
+ end
79
+
80
+ def format_name(key)
81
+ name = NAME_OVERRIDES[key]
82
+ return name if name
83
+
84
+ key.split('_')
85
+ .each { |fragment| fragment[0] = fragment[0].upcase }
86
+ .join(' ')
87
+ end
88
+
89
+ def format_sections(key, value)
90
+ {
91
+ :key => key,
92
+ :type => format_type(value[:type]),
93
+ :description => format_description(value),
94
+ :default => format_default_value(value),
95
+ :env_var => format_env_var(key)
96
+ }
97
+ end
98
+
99
+ def format_type(type)
100
+ if type == NewRelic::Agent::Configuration::Boolean
101
+ 'Boolean'
102
+ else
103
+ type
104
+ end
105
+ end
106
+
107
+ def pluck(key, config_hash)
108
+ value = config_hash.delete(key)
109
+ [key, value]
110
+ end
111
+
112
+ def section_key(key, components)
113
+ if /^disable_/.match?(key) # "disable_httpclient"
114
+ DISABLING
115
+ elsif components.length >= 2 && !(components[1] == 'attributes') # "analytics_events.enabled"
116
+ components.first
117
+ elsif components[1] == 'attributes' # "transaction_tracer.attributes.enabled"
118
+ ATTRIBUTES
119
+ else
120
+ GENERAL
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,12 @@
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 Matches
6
+ def look_for_seed(tasks)
7
+ matches = tasks.map { |t| /(seed=.*?)[,\]]/.match(t) }.compact
8
+ if matches.any?
9
+ matches.first[1]
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,24 @@
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 Prompt
6
+ def prompt_to_continue(command, destination = 'local')
7
+ puts "The following rsync command will be executed to update the #{destination} copy of the specs:"
8
+ puts
9
+ puts command
10
+ puts
11
+ puts "CAUTION: Any unsaved changes that exist within the #{destination} content will be OVERWRITTEN!"
12
+ if destination.eql?('local')
13
+ puts 'CAUTION 2: Before continuing, make sure your local repo is on the correct, synced branch!'
14
+ end
15
+ puts
16
+ print "Do you wish to continue? ('y' to continue, return to cancel) [n] "
17
+ continue = STDIN.gets.chomp
18
+ if continue.casecmp('y') == 0
19
+ system(command)
20
+ else
21
+ puts 'Cancelled'
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module Removers
6
+ def remove_local_multiverse_databases
7
+ list_databases_command = %(echo "show databases" | mysql -u root)
8
+ databases = `#{list_databases_command}`.chomp!.split("\n").select { |s| s.include?('multiverse') }
9
+ databases.each do |database|
10
+ puts "Dropping #{database}"
11
+ `echo "drop database #{database}" | mysql -u root`
12
+ end
13
+ rescue => error
14
+ puts 'ERROR: Cannot get MySQL databases...'
15
+ puts error.message
16
+ end
17
+
18
+ def remove_generated_gemfiles
19
+ file_path = File.expand_path('test/multiverse/suites')
20
+ Dir.glob(File.join(file_path, '**', 'Gemfile*')).each do |fn|
21
+ puts "Removing #{fn.gsub(file_path, '.../suites')}"
22
+ FileUtils.rm(fn)
23
+ end
24
+ end
25
+
26
+ def remove_generated_gemfile_lockfiles
27
+ file_path = File.expand_path('test/environments')
28
+ Dir.glob(File.join(file_path, '**', 'Gemfile.lock')).each do |fn|
29
+ puts "Removing #{fn.gsub(file_path, '.../environments')}"
30
+ FileUtils.rm(fn)
31
+ end
32
+ end
33
+ end
@@ -1,11 +1,15 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
1
5
  namespace :newrelic do
2
- desc "Install a default config/newrelic.yml file"
6
+ desc 'Install a default config/newrelic.yml file'
3
7
  task :install do
4
- load File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "install.rb"))
8
+ load File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'install.rb'))
5
9
  end
6
10
 
7
- desc "Gratefulness is always appreciated"
11
+ desc 'Gratefulness is always appreciated'
8
12
  task :thanks do
9
- puts "The Ruby agent team is grateful to Jim Weirich for his kindness and his code. He will be missed."
13
+ puts 'The Ruby agent team is grateful to Jim Weirich for his kindness and his code. He will be missed.'
10
14
  end
11
15
  end
@@ -0,0 +1,63 @@
1
+ # Instrumentation Generator
2
+
3
+ ## Usage
4
+
5
+ `thor list` can be passed to get a list of all available thor commands
6
+
7
+ ### instrumentation:scaffold
8
+
9
+ This task requires one parameter by default: the name of the library or class you are instrumenting. This task generates the basic file structure needed to add new instrumentation to the Ruby agent.
10
+
11
+ Run it using:
12
+
13
+ `thor instrumentation:scaffold gem_name`
14
+
15
+ It accepts two optional parameters:
16
+
17
+ - `--method`: the name of a method to instrument. Only one method can be accepted at this time. Defaults to `method_to_instrument`
18
+ - `--args`: the arguments for the instrumented method. A comma-separated list can be given if there are multiple arguments. Defaults to `*args`.
19
+
20
+ With the optional parameters, the task can be run like so:
21
+
22
+ `thor instrumentation:scaffold gem_name --method=method_to_instrument --args=arg1,arg2,arg3`
23
+
24
+ ### WIP: instrumentation:add_new_method
25
+
26
+ Are you trying add instrumentation for a method within library we already instrument? This task is for you! Instead of building the entire scaffold, this task inserts only the changes needed within the `instrumentation.rb` and test files to instrument the new method. It requires one argument, the name of the existing instrumentation to add the method to. If the instrumented library does not already exist, it will create a new scaffold for that library.
27
+
28
+ Run it using:
29
+
30
+ `thor instrumentation:scaffold gem_name`
31
+
32
+ It accepts two optional parameters:
33
+
34
+ - `--method`: the name of a method to instrument. Only one method can be accepted at this time. Defaults to `method_to_instrument`
35
+ - `--args`: the arguments for the instrumented method. A comma-separated list can be given if there are multiple arguments. Defaults to `*args`.
36
+
37
+ With the optional parameters, the task can be run like so:
38
+
39
+ `thor instrumentation:add_new_method gem_name --method=method_to_instrument --args=arg1,arg2,arg3`
40
+
41
+ ## Idea
42
+
43
+ Create a CLI, similar to Rails’ generators and scaffold scripts, to create the required files and basic classes for instrumenting new libraries. The hope is that the parts of adding new instrumentation that is repetitive can be eliminated and/or reduced so that it takes less time to add new instrumentation and we can spend development time considering the best attributes to collect and interactions to measure. I also hope this project will reduce the overall toil related to adding new instrumentation.
44
+
45
+ The files we create with little variation besides library and method names are:
46
+
47
+ - Lib
48
+ - Dependency detection
49
+ - Chain
50
+ - Prepend
51
+ - Instrumentation
52
+ - Tests
53
+ - configuration/newrelic.yml
54
+ - Envfile
55
+ - Test file
56
+
57
+ Furthermore, we also create very similar snippets inside the default source configuration file that could be generated by this project as well.
58
+
59
+ ## Outcome
60
+
61
+ A prototype outside the agent was first created. This prototype generated the required files to add instrumentation. The prototype accepted three arguments: name (name of the library), method (method to instrument), args (arguments for the method). This prototype has evolved into the current directory.
62
+
63
+ This project leverages the Ruby gem Thor, a toolkit for building powerful command-line interfaces used in Bundler, Vagrant, Rails and others powers this CLI.
@@ -0,0 +1,33 @@
1
+ # TODO
2
+
3
+ # - [X] Create instrumentation file
4
+
5
+ # - [X] Create chain file
6
+
7
+ # - [X] Create prepend file
8
+
9
+ # - [X] Create dependency detection file
10
+
11
+ # - [X] Add config to default source
12
+
13
+ # - [X] Create multiverse suite
14
+
15
+ # - [X] Create Envfile
16
+
17
+ # - [X] Create test file with examples
18
+
19
+ # - [X] Create option for method names to instrument
20
+
21
+ # - [X] Add entry to newrelic.yml
22
+
23
+ # - [ ] Append a new method to instrument to an existing instrumentation class (with tests?)
24
+
25
+ # - [ ] Documentation: examples of what to add in each gap (Good examples of tests, instrumentation, etc. as comments to guide users)
26
+
27
+ # - [ ] Handle multi-word gem names (camel case for classes, handle hyphens, concurrent-ruby as example)
28
+
29
+ # - [ ] Allow multiple method arguments to be passed to the command line
30
+
31
+ # - [ ] Add tests for the instrumentation_generator code
32
+
33
+ # - [ ] See if instrumentation PRs can get automatically generated when an already instrumented library adds methods to its codebase
@@ -0,0 +1,121 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require_relative '../../new_relic/language_support'
6
+ require 'thor'
7
+
8
+ class Instrumentation < Thor
9
+ include Thor::Actions
10
+
11
+ INSTRUMENTATION_ROOT = 'lib/new_relic/agent/instrumentation/'
12
+ MULTIVERSE_SUITE_ROOT = 'test/multiverse/suites/'
13
+ DEFAULT_SOURCE_LOCATION = 'lib/new_relic/agent/configuration/default_source.rb'
14
+ NEWRELIC_YML_LOCATION = 'newrelic.yml'
15
+
16
+ desc('scaffold NAME', 'Scaffold the required files for adding new instrumentation')
17
+ long_desc <<~LONGDESC
18
+ `instrumentation scaffold` requires one parameter by default: the name of the
19
+ library or class you are instrumenting. This task generates the basic
20
+ file structure needed to add new instrumentation to the Ruby agent.
21
+ LONGDESC
22
+
23
+ source_root(File.dirname(__FILE__))
24
+
25
+ option :method,
26
+ default: 'method_to_instrument',
27
+ desc: 'The method you would like to prepend or chain instrumentation onto'
28
+ option :args,
29
+ default: '*args',
30
+ desc: 'The arguments associated with the original method'
31
+
32
+ def scaffold(name)
33
+ @name = name
34
+ @method = options[:method] if options[:method]
35
+ @args = options[:args] if options[:args]
36
+ @class_name = ::NewRelic::LanguageSupport.camelize(name)
37
+ base_path = "#{INSTRUMENTATION_ROOT}#{name.downcase}"
38
+
39
+ empty_directory(base_path)
40
+ create_instrumentation_files(base_path)
41
+ append_to_default_source(name)
42
+ append_to_newrelic_yml(name)
43
+ create_tests(name)
44
+ end
45
+
46
+ desc 'add_new_method NAME', 'Inserts a new method into an existing piece of instrumentation'
47
+
48
+ option :method, required: true, desc: 'The name of the method to instrument'
49
+ option :args, default: '*args', desc: 'The arguments associated with the instrumented method'
50
+
51
+ def add_new_method(name, method_name)
52
+ # Verify that existing instrumentation exists
53
+ # if it doesn't, should we just call the #scaffold method instead since we have all the stuff
54
+ # otherwise, inject the new method into the instrumentation matching the first arg
55
+ # add to only chain, instrumentation, prepend
56
+ # move the method content to a partial
57
+ end
58
+
59
+ private
60
+
61
+ def create_instrumentation_files(base_path)
62
+ %w[chain instrumentation prepend].each do |file|
63
+ template("templates/#{file}.tt", "#{base_path}/#{file}.rb")
64
+ end
65
+
66
+ template('templates/dependency_detection.tt', "#{base_path}.rb")
67
+ end
68
+
69
+ def create_tests(name)
70
+ @name = name
71
+ @instrumentation_method_global_erb_snippet = '<%= $instrumentation_method %>'
72
+ base_path = "#{MULTIVERSE_SUITE_ROOT}#{@name.downcase}"
73
+ empty_directory(base_path)
74
+ template('templates/Envfile.tt', "#{base_path}/Envfile")
75
+ template('templates/test.tt', "#{base_path}/#{@name.downcase}_instrumentation_test.rb")
76
+
77
+ empty_directory("#{base_path}/config")
78
+ template('templates/newrelic.yml.tt', "#{base_path}/config/newrelic.yml")
79
+ end
80
+
81
+ def append_to_default_source(name)
82
+ insert_into_file(
83
+ DEFAULT_SOURCE_LOCATION,
84
+ config_block(name.downcase),
85
+ after: ":description => 'Controls auto-instrumentation of bunny at start up. May be one of [auto|prepend|chain|disabled].'
86
+ },\n"
87
+ )
88
+ end
89
+
90
+ def append_to_newrelic_yml(name)
91
+ insert_into_file(
92
+ NEWRELIC_YML_LOCATION,
93
+ yaml_block(name),
94
+ after: "# instrumentation.bunny: auto\n"
95
+ )
96
+ end
97
+
98
+ def config_block(name)
99
+ <<~CONFIG
100
+ :'instrumentation.#{name.downcase}' => {
101
+ :default => 'auto',
102
+ :public => true,
103
+ :type => String,
104
+ :dynamic_name => true,
105
+ :allowed_from_server => false,
106
+ :description => 'Controls auto-instrumentation of the #{name} library at start up. May be one of [auto|prepend|chain|disabled].'
107
+ },
108
+ CONFIG
109
+ end
110
+
111
+ def yaml_block(name)
112
+ <<~HEREDOC
113
+
114
+ # Controls auto-instrumentation of #{name} at start up.
115
+ # May be one of [auto|prepend|chain|disabled]
116
+ # instrumentation.#{name.downcase}: auto
117
+ HEREDOC
118
+ end
119
+ end
120
+
121
+ Instrumentation.start(ARGV)
@@ -0,0 +1,9 @@
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
+ instrumentation_methods :chain, :prepend
6
+
7
+ gemfile <<~RB
8
+ gem '<%= @name.downcase %>'
9
+ RB
@@ -0,0 +1,22 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module <%= @class_name %>::Chain
7
+ def self.instrument!
8
+ ::<%= @class_name %>.class_eval do
9
+ include NewRelic::Agent::Instrumentation::<%= @class_name %>
10
+
11
+ alias_method(:<%= @method.downcase %>_without_new_relic, :<%= @method.downcase %>)
12
+ alias_method(:<%= @method.downcase %>, :<%= @method.downcase %>_with_new_relic)
13
+
14
+ def <%= @method.downcase %><%= "(#{@args})" unless @args.empty? %>
15
+ <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %> do
16
+ <%= @method.downcase %>_without_new_relic<%= "(#{@args})" unless @args.empty? %>
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ alias_method(:<%= @method.downcase %>_without_new_relic, :<%= @method.downcase %>)
2
+ alias_method(:<%= @method.downcase %>, :<%= @method.downcase %>_with_new_relic)
3
+
4
+ def <%= @method.downcase %><%= "(#{@args})" unless @args.empty? %>
5
+ <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %> do
6
+ <%= @method.downcase %>_without_new_relic<%= "(#{@args})" unless @args.empty? %>
7
+ end
8
+ end
@@ -0,0 +1,29 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require_relative '<%= @name.downcase %>/instrumentation'
6
+ require_relative '<%= @name.downcase %>/chain'
7
+ require_relative '<%= @name.downcase %>/prepend'
8
+
9
+ DependencyDetection.defer do
10
+ named :<%= @name.match?(/\-|\_/) ? "'#{@name.downcase}'" : @name.downcase %>
11
+
12
+ depends_on do
13
+ # The class that needs to be defined to prepend/chain onto. This can be used
14
+ # to determine whether the library is installed.
15
+ defined?(::<%= @class_name %>)
16
+ # Add any additional requirements to verify whether this instrumentation
17
+ # should be installed
18
+ end
19
+
20
+ executes do
21
+ ::NewRelic::Agent.logger.info('Installing <%= @name.downcase %> instrumentation')
22
+
23
+ if use_prepend?
24
+ prepend_instrument ::<%= @class_name %>, NewRelic::Agent::Instrumentation::<%= @class_name %>::Prepend
25
+ else
26
+ chain_instrument NewRelic::Agent::Instrumentation::<%= @class_name %>::Chain
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,13 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module <%= @class_name %>
7
+
8
+ def <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %>
9
+ # add instrumentation content here
10
+ yield
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ def <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %>
2
+ # add instrumentation content here
3
+ end
@@ -0,0 +1,19 @@
1
+ ---
2
+ development:
3
+ error_collector:
4
+ enabled: true
5
+ apdex_t: 0.5
6
+ monitor_mode: true
7
+ license_key: bootstrap_newrelic_admin_license_key_000
8
+ instrumentation:
9
+ <%= @name.downcase %>: <%= @instrumentation_method_global_erb_snippet %>
10
+ app_name: test
11
+ log_level: debug
12
+ host: 127.0.0.1
13
+ api_host: 127.0.0.1
14
+ transaction_trace:
15
+ record_sql: obfuscated
16
+ enabled: true
17
+ stack_trace_threshold: 0.5
18
+ transaction_threshold: 1.0
19
+ capture_params: false
@@ -0,0 +1,13 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module <%= @class_name %>::Prepend
7
+ include NewRelic::Agent::Instrumentation::<%= @class_name %>
8
+
9
+ def <%= @method.downcase %><%= "(#{@args})" unless @args.empty? %>
10
+ <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %> { super }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ def <%= @method.downcase %><%= "(#{@args})" unless @args.empty? %>
2
+ <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %> { super }
3
+ end
@@ -0,0 +1,15 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ class <%= @class_name %>InstrumentationTest < Minitest::Test
6
+ def setup
7
+ @stats_engine = NewRelic::Agent.instance.stats_engine
8
+ end
9
+
10
+ def teardown
11
+ NewRelic::Agent.instance.stats_engine.clear_stats
12
+ end
13
+
14
+ # Add tests here
15
+ end
@@ -1,2 +1,6 @@
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
+
1
5
  # Guts of task are in a .rb file to allow requiring from external gems
2
6
  require "#{File.join(File.dirname(__FILE__))}/multiverse"
@@ -1,6 +1,7 @@
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
6
  # Rake task for running Ruby agent multiverse tests. This file may be required
6
7
  # from third party gems. It is also used by the agent itself to run multiverse.
@@ -35,36 +36,49 @@
35
36
  # # Runs with a specific test seed
36
37
  # bundle exec rake test:multiverse[my_gem,seed=1337]
37
38
 
39
+ require_relative 'helpers/removers'
40
+ include Removers
41
+
38
42
  namespace :test do
39
- desc "Run functional test suite for New Relic"
43
+ desc 'Run functional test suite for New Relic'
40
44
  task :multiverse, [:suite, :param1, :param2, :param3, :param4] => ['multiverse:env'] do |_, args|
41
45
  Multiverse::Runner.run(args.suite, Multiverse::Runner.parse_args(args))
42
46
  end
43
47
 
44
48
  namespace :multiverse do
49
+ # task :prerequisites
45
50
 
46
51
  task :env do
47
52
  # ENV['SUITES_DIRECTORY'] = File.expand_path('../../test/multiverse/suites', __FILE__)
48
53
  require File.expand_path('../../../test/multiverse/lib/multiverse', __FILE__)
49
54
  end
50
55
 
51
- desc "Clean cached gemfiles from Bundler.bundle_path"
56
+ task :clobber do
57
+ remove_local_multiverse_databases
58
+ remove_generated_gemfiles
59
+ remove_generated_gemfile_lockfiles
60
+ end
61
+
62
+ desc 'Clean cached gemfiles from Bundler.bundle_path'
52
63
  task :clean_gemfile_cache do
53
- glob = File.expand_path 'multiverse-cache/Gemfile.*.lock', Bundler.bundle_path
64
+ glob = File.expand_path('multiverse-cache/Gemfile.*.lock', Bundler.bundle_path)
54
65
  File.delete(*Dir[glob])
55
66
  end
56
67
 
57
- desc "Test the multiverse testing framework by executing tests in test/multiverse/test. Get meta with it."
68
+ desc 'Test the multiverse testing framework by executing tests in test/multiverse/test. Get meta with it.'
58
69
  task :self, [:suite, :mode] do |_, args|
59
- args.with_defaults(:suite => "", :mode => "")
60
- puts ("Testing the multiverse testing framework...")
70
+ args.with_defaults(:suite => '', :mode => '')
71
+ puts ('Testing the multiverse testing framework...')
61
72
  test_files = FileList['test/multiverse/test/*_test.rb']
62
- ruby test_files.join(" ")
73
+ ruby test_files.join(' ')
63
74
  end
64
75
 
65
76
  task :prime, [:suite] => [:env] do |_, args|
66
77
  Multiverse::Runner.prime(args.suite, Multiverse::Runner.parse_args(args))
67
78
  end
68
79
 
80
+ task :gem_manifest => :env do
81
+ Multiverse::GemManifest.new.report
82
+ end
69
83
  end
70
84
  end
@@ -1,6 +1,7 @@
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
6
  # If you are looking to instrument rake tasks in a Rails environment, but the
6
7
  # task doesn't depend on :environment, this task may be included to ensure that