newrelic_rpm 5.7.0.350 → 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (360) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -0
  3. data/.yardopts +1 -0
  4. data/CHANGELOG.md +788 -0
  5. data/CONTRIBUTING.md +106 -19
  6. data/Gemfile +6 -2
  7. data/Guardfile +18 -1
  8. data/LICENSE +208 -38
  9. data/README.md +80 -84
  10. data/ROADMAP.md +24 -0
  11. data/Rakefile +2 -0
  12. data/THIRD_PARTY_NOTICES.md +213 -0
  13. data/bin/nrdebug +1 -1
  14. data/init.rb +1 -1
  15. data/install.rb +1 -1
  16. data/lib/new_relic/agent/adaptive_sampler.rb +1 -1
  17. data/lib/new_relic/agent/agent.rb +176 -191
  18. data/lib/new_relic/agent/agent_logger.rb +5 -1
  19. data/lib/new_relic/agent/attribute_filter.rb +8 -8
  20. data/lib/new_relic/agent/attribute_processing.rb +1 -1
  21. data/lib/new_relic/agent/attributes.rb +152 -0
  22. data/lib/new_relic/agent/audit_logger.rb +11 -1
  23. data/lib/new_relic/agent/autostart.rb +19 -15
  24. data/lib/new_relic/agent/chained_call.rb +1 -1
  25. data/lib/new_relic/agent/commands/agent_command.rb +1 -1
  26. data/lib/new_relic/agent/commands/agent_command_router.rb +3 -22
  27. data/lib/new_relic/agent/commands/thread_profiler_session.rb +1 -1
  28. data/lib/new_relic/agent/configuration/default_source.rb +447 -89
  29. data/lib/new_relic/agent/configuration/dotted_hash.rb +1 -1
  30. data/lib/new_relic/agent/configuration/environment_source.rb +5 -3
  31. data/lib/new_relic/agent/configuration/event_harvest_config.rb +45 -0
  32. data/lib/new_relic/agent/configuration/high_security_source.rb +2 -1
  33. data/lib/new_relic/agent/configuration/manager.rb +16 -12
  34. data/lib/new_relic/agent/configuration/manual_source.rb +1 -1
  35. data/lib/new_relic/agent/configuration/mask_defaults.rb +1 -1
  36. data/lib/new_relic/agent/configuration/security_policy_source.rb +1 -1
  37. data/lib/new_relic/agent/configuration/server_source.rb +39 -4
  38. data/lib/new_relic/agent/configuration/yaml_source.rb +12 -7
  39. data/lib/new_relic/agent/configuration.rb +1 -1
  40. data/lib/new_relic/agent/connect/request_builder.rb +61 -0
  41. data/lib/new_relic/agent/connect/response_handler.rb +61 -0
  42. data/lib/new_relic/agent/custom_event_aggregator.rb +1 -1
  43. data/lib/new_relic/agent/database/explain_plan_helpers.rb +1 -1
  44. data/lib/new_relic/agent/database/obfuscation_helpers.rb +2 -2
  45. data/lib/new_relic/agent/database/obfuscator.rb +1 -1
  46. data/lib/new_relic/agent/database/postgres_explain_obfuscator.rb +1 -1
  47. data/lib/new_relic/agent/database.rb +2 -3
  48. data/lib/new_relic/agent/database_adapter.rb +33 -0
  49. data/lib/new_relic/agent/datastores/metric_helper.rb +2 -3
  50. data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +3 -3
  51. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +1 -1
  52. data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +9 -9
  53. data/lib/new_relic/agent/datastores/mongo/statement_formatter.rb +1 -1
  54. data/lib/new_relic/agent/datastores/mongo.rb +2 -2
  55. data/lib/new_relic/agent/datastores/redis.rb +1 -5
  56. data/lib/new_relic/agent/datastores.rb +7 -9
  57. data/lib/new_relic/agent/deprecator.rb +1 -1
  58. data/lib/new_relic/agent/{cross_app_payload.rb → distributed_tracing/cross_app_payload.rb} +3 -2
  59. data/lib/new_relic/agent/{cross_app_tracing.rb → distributed_tracing/cross_app_tracing.rb} +61 -46
  60. data/lib/new_relic/agent/distributed_tracing/distributed_trace_attributes.rb +84 -0
  61. data/lib/new_relic/agent/distributed_tracing/distributed_trace_metrics.rb +75 -0
  62. data/lib/new_relic/agent/{distributed_trace_payload.rb → distributed_tracing/distributed_trace_payload.rb} +32 -113
  63. data/lib/new_relic/agent/distributed_tracing/distributed_trace_transport_type.rb +39 -0
  64. data/lib/new_relic/agent/distributed_tracing/trace_context.rb +246 -0
  65. data/lib/new_relic/agent/distributed_tracing/trace_context_payload.rb +126 -0
  66. data/lib/new_relic/agent/distributed_tracing.rb +115 -32
  67. data/lib/new_relic/agent/encoding_normalizer.rb +1 -1
  68. data/lib/new_relic/agent/error_collector.rb +37 -20
  69. data/lib/new_relic/agent/error_event_aggregator.rb +10 -7
  70. data/lib/new_relic/agent/error_trace_aggregator.rb +2 -1
  71. data/lib/new_relic/agent/event_aggregator.rb +27 -33
  72. data/lib/new_relic/agent/event_buffer.rb +1 -1
  73. data/lib/new_relic/agent/event_listener.rb +1 -1
  74. data/lib/new_relic/agent/event_loop.rb +1 -1
  75. data/lib/new_relic/agent/external.rb +13 -11
  76. data/lib/new_relic/agent/guid_generator.rb +28 -0
  77. data/lib/new_relic/agent/harvester.rb +1 -1
  78. data/lib/new_relic/agent/heap.rb +1 -1
  79. data/lib/new_relic/agent/hostname.rb +16 -2
  80. data/lib/new_relic/agent/http_clients/abstract.rb +82 -0
  81. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +25 -20
  82. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +29 -14
  83. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +18 -22
  84. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +11 -12
  85. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +17 -5
  86. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +5 -7
  87. data/lib/new_relic/agent/http_clients/uri_util.rb +12 -11
  88. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +26 -43
  89. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +53 -73
  90. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +81 -56
  91. data/lib/new_relic/agent/instrumentation/active_job.rb +7 -8
  92. data/lib/new_relic/agent/instrumentation/active_merchant.rb +1 -1
  93. data/lib/new_relic/agent/instrumentation/active_record.rb +85 -38
  94. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +17 -6
  95. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +152 -0
  96. data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +35 -11
  97. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +47 -49
  98. data/lib/new_relic/agent/instrumentation/active_storage.rb +1 -1
  99. data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +13 -9
  100. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +10 -9
  101. data/lib/new_relic/agent/instrumentation/authlogic.rb +1 -1
  102. data/lib/new_relic/agent/instrumentation/bunny/chain.rb +45 -0
  103. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +152 -0
  104. data/lib/new_relic/agent/instrumentation/bunny/prepend.rb +35 -0
  105. data/lib/new_relic/agent/instrumentation/bunny.rb +13 -132
  106. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +10 -4
  107. data/lib/new_relic/agent/instrumentation/curb/chain.rb +93 -0
  108. data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +222 -0
  109. data/lib/new_relic/agent/instrumentation/curb/prepend.rb +63 -0
  110. data/lib/new_relic/agent/instrumentation/curb.rb +11 -183
  111. data/lib/new_relic/agent/instrumentation/data_mapper.rb +5 -3
  112. data/lib/new_relic/agent/instrumentation/delayed_job/chain.rb +38 -0
  113. data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +53 -0
  114. data/lib/new_relic/agent/instrumentation/delayed_job/prepend.rb +34 -0
  115. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +9 -49
  116. data/lib/new_relic/agent/instrumentation/excon/connection.rb +8 -5
  117. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +3 -2
  118. data/lib/new_relic/agent/instrumentation/excon.rb +4 -3
  119. data/lib/new_relic/agent/instrumentation/grape/chain.rb +25 -0
  120. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +100 -0
  121. data/lib/new_relic/agent/instrumentation/grape/prepend.rb +17 -0
  122. data/lib/new_relic/agent/instrumentation/grape.rb +14 -118
  123. data/lib/new_relic/agent/instrumentation/httpclient/chain.rb +25 -0
  124. data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +38 -0
  125. data/lib/new_relic/agent/instrumentation/httpclient/prepend.rb +17 -0
  126. data/lib/new_relic/agent/instrumentation/httpclient.rb +10 -30
  127. data/lib/new_relic/agent/instrumentation/httprb/chain.rb +22 -0
  128. data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +30 -0
  129. data/lib/new_relic/agent/instrumentation/httprb/prepend.rb +15 -0
  130. data/lib/new_relic/agent/instrumentation/httprb.rb +29 -0
  131. data/lib/new_relic/agent/instrumentation/ignore_actions.rb +1 -1
  132. data/lib/new_relic/agent/instrumentation/memcache/chain.rb +16 -0
  133. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +39 -118
  134. data/lib/new_relic/agent/instrumentation/memcache/helper.rb +56 -0
  135. data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +88 -0
  136. data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +88 -0
  137. data/lib/new_relic/agent/instrumentation/memcache.rb +55 -68
  138. data/lib/new_relic/agent/instrumentation/merb/controller.rb +1 -1
  139. data/lib/new_relic/agent/instrumentation/merb/errors.rb +1 -1
  140. data/lib/new_relic/agent/instrumentation/middleware_proxy.rb +4 -2
  141. data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +20 -11
  142. data/lib/new_relic/agent/instrumentation/mongo.rb +17 -4
  143. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +36 -3
  144. data/lib/new_relic/agent/instrumentation/net_http/chain.rb +25 -0
  145. data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +40 -0
  146. data/lib/new_relic/agent/instrumentation/net_http/prepend.rb +21 -0
  147. data/lib/new_relic/agent/instrumentation/net_http.rb +39 -0
  148. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +100 -0
  149. data/lib/new_relic/agent/instrumentation/padrino/chain.rb +34 -0
  150. data/lib/new_relic/agent/instrumentation/padrino/instrumentation.rb +27 -0
  151. data/lib/new_relic/agent/instrumentation/padrino/prepend.rb +20 -0
  152. data/lib/new_relic/agent/instrumentation/padrino.rb +19 -52
  153. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +1 -1
  154. data/lib/new_relic/agent/instrumentation/queue_time.rb +1 -1
  155. data/lib/new_relic/agent/instrumentation/rack/chain.rb +57 -0
  156. data/lib/new_relic/agent/instrumentation/rack/helpers.rb +32 -0
  157. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +73 -0
  158. data/lib/new_relic/agent/instrumentation/rack/prepend.rb +36 -0
  159. data/lib/new_relic/agent/instrumentation/rack.rb +30 -138
  160. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +1 -1
  161. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +1 -1
  162. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +1 -1
  163. data/lib/new_relic/agent/instrumentation/rails_middleware.rb +1 -1
  164. data/lib/new_relic/agent/instrumentation/{rails5 → rails_notifications}/action_cable.rb +6 -7
  165. data/lib/new_relic/agent/instrumentation/{rails5 → rails_notifications}/action_controller.rb +4 -4
  166. data/lib/new_relic/agent/instrumentation/{rails4 → rails_notifications}/action_view.rb +4 -4
  167. data/lib/new_relic/agent/instrumentation/rainbows_instrumentation.rb +1 -1
  168. data/lib/new_relic/agent/instrumentation/rake/chain.rb +25 -0
  169. data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +144 -0
  170. data/lib/new_relic/agent/instrumentation/rake/prepend.rb +14 -0
  171. data/lib/new_relic/agent/instrumentation/rake.rb +14 -155
  172. data/lib/new_relic/agent/instrumentation/redis/chain.rb +34 -0
  173. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +65 -0
  174. data/lib/new_relic/agent/instrumentation/redis/prepend.rb +24 -0
  175. data/lib/new_relic/agent/instrumentation/redis.rb +11 -104
  176. data/lib/new_relic/agent/instrumentation/resque/chain.rb +22 -0
  177. data/lib/new_relic/agent/instrumentation/resque/instrumentation.rb +33 -0
  178. data/lib/new_relic/agent/instrumentation/resque/prepend.rb +16 -0
  179. data/lib/new_relic/agent/instrumentation/resque.rb +9 -26
  180. data/lib/new_relic/agent/instrumentation/sequel.rb +1 -1
  181. data/lib/new_relic/agent/instrumentation/sequel_helper.rb +1 -1
  182. data/lib/new_relic/agent/instrumentation/sidekiq.rb +48 -24
  183. data/lib/new_relic/agent/instrumentation/sinatra/chain.rb +55 -0
  184. data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +30 -35
  185. data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +118 -0
  186. data/lib/new_relic/agent/instrumentation/sinatra/prepend.rb +33 -0
  187. data/lib/new_relic/agent/instrumentation/sinatra/transaction_namer.rb +1 -1
  188. data/lib/new_relic/agent/instrumentation/sinatra.rb +21 -160
  189. data/lib/new_relic/agent/instrumentation/sunspot.rb +1 -1
  190. data/lib/new_relic/agent/instrumentation/typhoeus/chain.rb +22 -0
  191. data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +82 -0
  192. data/lib/new_relic/agent/instrumentation/typhoeus/prepend.rb +14 -0
  193. data/lib/new_relic/agent/instrumentation/typhoeus.rb +12 -74
  194. data/lib/new_relic/agent/instrumentation.rb +1 -1
  195. data/lib/new_relic/agent/internal_agent_error.rb +1 -1
  196. data/lib/new_relic/agent/javascript_instrumentor.rb +3 -3
  197. data/lib/new_relic/agent/log_once.rb +1 -1
  198. data/lib/new_relic/agent/logging.rb +139 -0
  199. data/lib/new_relic/agent/memory_logger.rb +1 -1
  200. data/lib/new_relic/agent/messaging.rb +15 -82
  201. data/lib/new_relic/agent/method_tracer.rb +10 -8
  202. data/lib/new_relic/agent/method_tracer_helpers.rb +5 -5
  203. data/lib/new_relic/agent/monitors/cross_app_monitor.rb +110 -0
  204. data/lib/new_relic/agent/monitors/distributed_tracing_monitor.rb +27 -0
  205. data/lib/new_relic/agent/{inbound_request_monitor.rb → monitors/inbound_request_monitor.rb} +4 -4
  206. data/lib/new_relic/agent/{synthetics_monitor.rb → monitors/synthetics_monitor.rb} +4 -7
  207. data/lib/new_relic/agent/monitors.rb +27 -0
  208. data/lib/new_relic/agent/new_relic_service/encoders.rb +1 -1
  209. data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +1 -2
  210. data/lib/new_relic/agent/new_relic_service/marshaller.rb +6 -27
  211. data/lib/new_relic/agent/new_relic_service/security_policy_settings.rb +1 -1
  212. data/lib/new_relic/agent/new_relic_service.rb +95 -40
  213. data/lib/new_relic/agent/noticible_error.rb +22 -0
  214. data/lib/new_relic/agent/null_logger.rb +1 -1
  215. data/lib/new_relic/agent/obfuscator.rb +1 -1
  216. data/lib/new_relic/agent/parameter_filtering.rb +19 -6
  217. data/lib/new_relic/agent/payload_metric_mapping.rb +1 -1
  218. data/lib/new_relic/agent/pipe_channel_manager.rb +1 -1
  219. data/lib/new_relic/agent/pipe_service.rb +1 -1
  220. data/lib/new_relic/agent/prepend_supportability.rb +1 -1
  221. data/lib/new_relic/agent/priority_sampled_buffer.rb +9 -4
  222. data/lib/new_relic/agent/range_extensions.rb +1 -1
  223. data/lib/new_relic/agent/rules_engine/replacement_rule.rb +1 -1
  224. data/lib/new_relic/agent/rules_engine/segment_terms_rule.rb +1 -1
  225. data/lib/new_relic/agent/rules_engine.rb +1 -1
  226. data/lib/new_relic/agent/sampler.rb +1 -1
  227. data/lib/new_relic/agent/sampler_collection.rb +1 -1
  228. data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -1
  229. data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +1 -1
  230. data/lib/new_relic/agent/samplers/memory_sampler.rb +2 -2
  231. data/lib/new_relic/agent/samplers/object_sampler.rb +1 -1
  232. data/lib/new_relic/agent/samplers/vm_sampler.rb +1 -1
  233. data/lib/new_relic/agent/span_event_aggregator.rb +3 -5
  234. data/lib/new_relic/agent/span_event_primitive.rb +108 -54
  235. data/lib/new_relic/agent/sql_sampler.rb +10 -10
  236. data/lib/new_relic/agent/stats.rb +1 -1
  237. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +2 -2
  238. data/lib/new_relic/agent/stats_engine/stats_hash.rb +1 -1
  239. data/lib/new_relic/agent/stats_engine.rb +3 -3
  240. data/lib/new_relic/agent/supported_versions.rb +3 -3
  241. data/lib/new_relic/agent/synthetics_event_aggregator.rb +1 -1
  242. data/lib/new_relic/agent/system_info.rb +18 -4
  243. data/lib/new_relic/agent/threading/agent_thread.rb +2 -2
  244. data/lib/new_relic/agent/threading/backtrace_node.rb +1 -1
  245. data/lib/new_relic/agent/threading/backtrace_service.rb +4 -4
  246. data/lib/new_relic/agent/threading/thread_profile.rb +10 -24
  247. data/lib/new_relic/agent/timestamp_sampled_buffer.rb +1 -1
  248. data/lib/new_relic/agent/tracer.rb +509 -0
  249. data/lib/new_relic/agent/transaction/abstract_segment.rb +33 -6
  250. data/lib/new_relic/agent/transaction/datastore_segment.rb +1 -1
  251. data/lib/new_relic/agent/transaction/distributed_tracer.rb +177 -0
  252. data/lib/new_relic/agent/transaction/distributed_tracing.rb +59 -149
  253. data/lib/new_relic/agent/transaction/external_request_segment.rb +32 -39
  254. data/lib/new_relic/agent/transaction/message_broker_segment.rb +5 -12
  255. data/lib/new_relic/agent/transaction/request_attributes.rb +1 -1
  256. data/lib/new_relic/agent/transaction/segment.rb +28 -2
  257. data/lib/new_relic/agent/transaction/slowest_sample_buffer.rb +1 -1
  258. data/lib/new_relic/agent/transaction/synthetics_sample_buffer.rb +1 -1
  259. data/lib/new_relic/agent/transaction/trace.rb +6 -13
  260. data/lib/new_relic/agent/transaction/trace_builder.rb +1 -2
  261. data/lib/new_relic/agent/transaction/trace_context.rb +168 -0
  262. data/lib/new_relic/agent/transaction/trace_node.rb +11 -9
  263. data/lib/new_relic/agent/transaction/tracing.rb +1 -100
  264. data/lib/new_relic/agent/transaction/transaction_sample_buffer.rb +1 -1
  265. data/lib/new_relic/agent/transaction.rb +140 -170
  266. data/lib/new_relic/agent/transaction_error_primitive.rb +11 -16
  267. data/lib/new_relic/agent/transaction_event_aggregator.rb +1 -1
  268. data/lib/new_relic/agent/transaction_event_primitive.rb +29 -40
  269. data/lib/new_relic/agent/transaction_event_recorder.rb +4 -4
  270. data/lib/new_relic/agent/transaction_metrics.rb +1 -1
  271. data/lib/new_relic/agent/transaction_sampler.rb +2 -6
  272. data/lib/new_relic/agent/transaction_time_aggregator.rb +20 -6
  273. data/lib/new_relic/agent/utilization/aws.rb +1 -1
  274. data/lib/new_relic/agent/utilization/azure.rb +1 -1
  275. data/lib/new_relic/agent/utilization/gcp.rb +1 -1
  276. data/lib/new_relic/agent/utilization/pcf.rb +1 -1
  277. data/lib/new_relic/agent/utilization/vendor.rb +1 -1
  278. data/lib/new_relic/agent/utilization_data.rb +37 -2
  279. data/lib/new_relic/agent/vm/jruby_vm.rb +1 -1
  280. data/lib/new_relic/agent/vm/monotonic_gc_profiler.rb +1 -1
  281. data/lib/new_relic/agent/vm/mri_vm.rb +7 -5
  282. data/lib/new_relic/agent/vm/snapshot.rb +1 -1
  283. data/lib/new_relic/agent/vm.rb +1 -1
  284. data/lib/new_relic/agent/worker_loop.rb +1 -1
  285. data/lib/new_relic/agent.rb +106 -18
  286. data/lib/new_relic/cli/command.rb +1 -1
  287. data/lib/new_relic/cli/commands/deployments.rb +2 -3
  288. data/lib/new_relic/cli/commands/install.rb +4 -3
  289. data/lib/new_relic/coerce.rb +32 -7
  290. data/lib/new_relic/collection_helper.rb +1 -1
  291. data/lib/new_relic/constants.rb +42 -0
  292. data/lib/new_relic/control/class_methods.rb +8 -2
  293. data/lib/new_relic/control/frameworks/external.rb +1 -1
  294. data/lib/new_relic/control/frameworks/merb.rb +1 -1
  295. data/lib/new_relic/control/frameworks/rails.rb +12 -10
  296. data/lib/new_relic/control/frameworks/rails3.rb +1 -1
  297. data/lib/new_relic/control/frameworks/rails4.rb +1 -1
  298. data/lib/new_relic/control/frameworks/{rails5.rb → rails_notifications.rb} +2 -2
  299. data/lib/new_relic/control/frameworks/ruby.rb +1 -1
  300. data/lib/new_relic/control/frameworks/sinatra.rb +1 -1
  301. data/lib/new_relic/control/frameworks.rb +1 -1
  302. data/lib/new_relic/control/instance_methods.rb +12 -2
  303. data/lib/new_relic/control/instrumentation.rb +1 -1
  304. data/lib/new_relic/control/server_methods.rb +1 -1
  305. data/lib/new_relic/control.rb +1 -1
  306. data/lib/new_relic/delayed_job_injection.rb +1 -1
  307. data/lib/new_relic/dependency_detection.rb +124 -14
  308. data/lib/new_relic/environment_report.rb +2 -4
  309. data/lib/new_relic/helper.rb +1 -1
  310. data/lib/new_relic/language_support.rb +1 -1
  311. data/lib/new_relic/latest_changes.rb +2 -2
  312. data/lib/new_relic/local_environment.rb +1 -1
  313. data/lib/new_relic/metric_data.rb +1 -1
  314. data/lib/new_relic/metric_spec.rb +1 -1
  315. data/lib/new_relic/noticed_error.rb +35 -18
  316. data/lib/new_relic/rack/agent_hooks.rb +1 -1
  317. data/lib/new_relic/rack/agent_middleware.rb +2 -2
  318. data/lib/new_relic/rack/browser_monitoring.rb +16 -9
  319. data/lib/new_relic/rack.rb +1 -1
  320. data/lib/new_relic/recipes/capistrano3.rb +1 -1
  321. data/lib/new_relic/recipes/capistrano_legacy.rb +1 -1
  322. data/lib/new_relic/recipes.rb +1 -1
  323. data/lib/new_relic/supportability_helper.rb +16 -1
  324. data/lib/new_relic/version.rb +3 -3
  325. data/lib/newrelic_rpm.rb +1 -1
  326. data/lib/sequel/extensions/newrelic_instrumentation.rb +1 -1
  327. data/lib/sequel/plugins/newrelic_instrumentation.rb +1 -1
  328. data/lib/tasks/all.rb +1 -1
  329. data/lib/tasks/config.rake +1 -2
  330. data/lib/tasks/multiverse.rb +35 -1
  331. data/lib/tasks/newrelic.rb +1 -1
  332. data/lib/tasks/tests.rake +6 -1
  333. data/newrelic_rpm.gemspec +22 -17
  334. data/recipes/newrelic.rb +1 -1
  335. data/test/agent_helper.rb +358 -78
  336. metadata +147 -66
  337. data/.travis.yml +0 -228
  338. data/cert/cacert.pem +0 -1177
  339. data/lib/new_relic/agent/commands/xray_session.rb +0 -55
  340. data/lib/new_relic/agent/commands/xray_session_collection.rb +0 -161
  341. data/lib/new_relic/agent/cross_app_monitor.rb +0 -110
  342. data/lib/new_relic/agent/distributed_trace_monitor.rb +0 -41
  343. data/lib/new_relic/agent/http_clients/abstract_request.rb +0 -31
  344. data/lib/new_relic/agent/instrumentation/active_record_4.rb +0 -42
  345. data/lib/new_relic/agent/instrumentation/active_record_5.rb +0 -41
  346. data/lib/new_relic/agent/instrumentation/evented_subscriber.rb +0 -104
  347. data/lib/new_relic/agent/instrumentation/http.rb +0 -46
  348. data/lib/new_relic/agent/instrumentation/net.rb +0 -50
  349. data/lib/new_relic/agent/instrumentation/rails4/action_controller.rb +0 -32
  350. data/lib/new_relic/agent/instrumentation/rails5/action_view.rb +0 -27
  351. data/lib/new_relic/agent/transaction/attributes.rb +0 -154
  352. data/lib/new_relic/agent/transaction/xray_sample_buffer.rb +0 -64
  353. data/lib/new_relic/agent/transaction_state.rb +0 -186
  354. data/lib/new_relic/build.rb +0 -2
  355. data/lib/new_relic/metrics.rb +0 -13
  356. data/lib/tasks/versions.html.erb +0 -28
  357. data/lib/tasks/versions.postface.html +0 -8
  358. data/lib/tasks/versions.preface.html +0 -9
  359. data/lib/tasks/versions.rake +0 -65
  360. data/lib/tasks/versions.txt.erb +0 -14
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  # This file is distributed under New Relic's license terms.
3
- # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
3
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
4
 
5
5
  require 'socket'
6
6
  require 'net/https'
@@ -8,6 +8,8 @@ require 'net/http'
8
8
  require 'logger'
9
9
  require 'zlib'
10
10
  require 'stringio'
11
+ require 'new_relic/constants'
12
+ require 'new_relic/coerce'
11
13
  require 'new_relic/agent/autostart'
12
14
  require 'new_relic/agent/harvester'
13
15
  require 'new_relic/agent/hostname'
@@ -17,9 +19,8 @@ require 'new_relic/agent/configuration/manager'
17
19
  require 'new_relic/agent/database'
18
20
  require 'new_relic/agent/commands/agent_command_router'
19
21
  require 'new_relic/agent/event_listener'
20
- require 'new_relic/agent/cross_app_monitor'
21
- require 'new_relic/agent/distributed_trace_monitor'
22
- require 'new_relic/agent/synthetics_monitor'
22
+ require 'new_relic/agent/distributed_tracing'
23
+ require 'new_relic/agent/monitors'
23
24
  require 'new_relic/agent/transaction_event_recorder'
24
25
  require 'new_relic/agent/custom_event_aggregator'
25
26
  require 'new_relic/agent/span_event_aggregator'
@@ -30,6 +31,8 @@ require 'new_relic/agent/utilization_data'
30
31
  require 'new_relic/environment_report'
31
32
  require 'new_relic/agent/attribute_filter'
32
33
  require 'new_relic/agent/adaptive_sampler'
34
+ require 'new_relic/agent/connect/request_builder'
35
+ require 'new_relic/agent/connect/response_handler'
33
36
 
34
37
  module NewRelic
35
38
  module Agent
@@ -46,35 +49,33 @@ module NewRelic
46
49
  def initialize
47
50
  @started = false
48
51
  @event_loop = nil
52
+ @worker_thread = nil
49
53
 
50
54
  @service = NewRelicService.new
51
55
 
52
- @events = NewRelic::Agent::EventListener.new
53
- @stats_engine = NewRelic::Agent::StatsEngine.new
54
- @transaction_sampler = NewRelic::Agent::TransactionSampler.new
55
- @sql_sampler = NewRelic::Agent::SqlSampler.new
56
- @agent_command_router = NewRelic::Agent::Commands::AgentCommandRouter.new(@events)
57
- @cross_app_monitor = NewRelic::Agent::CrossAppMonitor.new(@events)
58
- @distributed_trace_monitor = NewRelic::Agent::DistributedTraceMonitor.new(@events)
59
- @synthetics_monitor = NewRelic::Agent::SyntheticsMonitor.new(@events)
60
- @error_collector = NewRelic::Agent::ErrorCollector.new
61
- @transaction_rules = NewRelic::Agent::RulesEngine.new
62
- @harvest_samplers = NewRelic::Agent::SamplerCollection.new(@events)
63
- @monotonic_gc_profiler = NewRelic::Agent::VM::MonotonicGCProfiler.new
64
- @javascript_instrumentor = NewRelic::Agent::JavascriptInstrumentor.new(@events)
65
- @adaptive_sampler = NewRelic::Agent::AdaptiveSampler.new(self.class.config[:sampling_target],
66
- self.class.config[:sampling_target_period_in_seconds])
67
-
68
- @harvester = NewRelic::Agent::Harvester.new(@events)
56
+ @events = EventListener.new
57
+ @stats_engine = StatsEngine.new
58
+ @transaction_sampler = TransactionSampler.new
59
+ @sql_sampler = SqlSampler.new
60
+ @agent_command_router = Commands::AgentCommandRouter.new @events
61
+ @monitors = Monitors.new @events
62
+ @error_collector = ErrorCollector.new @events
63
+ @transaction_rules = RulesEngine.new
64
+ @harvest_samplers = SamplerCollection.new @events
65
+ @monotonic_gc_profiler = VM::MonotonicGCProfiler.new
66
+ @javascript_instrumentor = JavascriptInstrumentor.new @events
67
+ @adaptive_sampler = AdaptiveSampler.new(Agent.config[:sampling_target],
68
+ Agent.config[:sampling_target_period_in_seconds])
69
+
70
+ @harvester = Harvester.new @events
69
71
  @after_fork_lock = Mutex.new
70
72
 
71
- @transaction_event_recorder = NewRelic::Agent::TransactionEventRecorder.new
72
- @custom_event_aggregator = NewRelic::Agent::CustomEventAggregator.new
73
- @span_event_aggregator = NewRelic::Agent::SpanEventAggregator.new
73
+ @transaction_event_recorder = TransactionEventRecorder.new @events
74
+ @custom_event_aggregator = CustomEventAggregator.new @events
75
+ @span_event_aggregator = SpanEventAggregator.new @events
74
76
 
75
77
  @connect_state = :pending
76
78
  @connect_attempts = 0
77
- @environment_report = nil
78
79
  @waited_on_connect = nil
79
80
  @connected_pid = nil
80
81
 
@@ -87,13 +88,13 @@ module NewRelic
87
88
  def setup_attribute_filter
88
89
  refresh_attribute_filter
89
90
 
90
- @events.subscribe(:finished_configuring) do
91
+ @events.subscribe(:initial_configuration_complete) do
91
92
  refresh_attribute_filter
92
93
  end
93
94
  end
94
95
 
95
96
  def refresh_attribute_filter
96
- @attribute_filter = NewRelic::Agent::AttributeFilter.new(NewRelic::Agent.config)
97
+ @attribute_filter = AttributeFilter.new(Agent.config)
97
98
  end
98
99
 
99
100
  # contains all the class-level methods for NewRelic::Agent::Agent
@@ -126,17 +127,20 @@ module NewRelic
126
127
  # cross application tracing ids and encoding
127
128
  attr_reader :cross_process_id
128
129
  attr_reader :cross_app_encoding_bytes
129
- attr_reader :cross_app_monitor
130
130
  # service for communicating with collector
131
131
  attr_accessor :service
132
132
  # Global events dispatcher. This will provides our primary mechanism
133
133
  # for agent-wide events, such as finishing configuration, error notification
134
134
  # and request before/after from Rack.
135
135
  attr_reader :events
136
+
137
+ # listens and responds to events that need to process headers
138
+ # for synthetics and distributed tracing
139
+ attr_reader :monitors
136
140
  # Transaction and metric renaming rules as provided by the
137
141
  # collector on connect. The former are applied during txns,
138
142
  # the latter during harvest.
139
- attr_reader :transaction_rules
143
+ attr_accessor :transaction_rules
140
144
  # Responsbile for restarting the harvest thread
141
145
  attr_reader :harvester
142
146
  # GC::Profiler.total_time is not monotonic so we wrap it.
@@ -146,6 +150,7 @@ module NewRelic
146
150
  attr_reader :transaction_event_recorder
147
151
  attr_reader :attribute_filter
148
152
  attr_reader :adaptive_sampler
153
+ attr_reader :environment_report
149
154
 
150
155
  def transaction_event_aggregator
151
156
  @transaction_event_recorder.transaction_event_aggregator
@@ -155,6 +160,10 @@ module NewRelic
155
160
  @transaction_event_recorder.synthetics_event_aggregator
156
161
  end
157
162
 
163
+ def agent_id=(agent_id)
164
+ @service.agent_id = agent_id
165
+ end
166
+
158
167
  # This method should be called in a forked process after a fork.
159
168
  # It assumes the parent process initialized the agent, but does
160
169
  # not assume the agent started.
@@ -200,7 +209,7 @@ module NewRelic
200
209
  end
201
210
 
202
211
  def install_pipe_service(channel_id)
203
- @service = NewRelic::Agent::PipeService.new(channel_id)
212
+ @service = PipeService.new(channel_id)
204
213
  if connected?
205
214
  @connected_pid = Process.pid
206
215
  else
@@ -231,12 +240,25 @@ module NewRelic
231
240
  end
232
241
 
233
242
  def revert_to_default_configuration
234
- NewRelic::Agent.config.remove_config_type(:manual)
235
- NewRelic::Agent.config.remove_config_type(:server)
243
+ Agent.config.remove_config_type(:manual)
244
+ Agent.config.remove_config_type(:server)
236
245
  end
237
246
 
247
+ # If the @worker_thread encounters an error during the attempt to connect to the collector
248
+ # then the connect attempts enter an exponential backoff retry loop. To avoid potential
249
+ # race conditions with shutting down while also attempting to reconnect, we join the
250
+ # @worker_thread with a timeout threshold. This allows potentially connecting and flushing
251
+ # pending data to the server, but without waiting indefinitely for a reconnect to succeed.
252
+ # The use-case where this typically arises is in cronjob scheduled rake tasks where there's
253
+ # also some network stability/latency issues happening.
238
254
  def stop_event_loop
239
255
  @event_loop.stop if @event_loop
256
+ # Wait the end of the event loop thread.
257
+ if @worker_thread
258
+ unless @worker_thread.join(3)
259
+ ::NewRelic::Agent.logger.debug "Event loop thread did not stop within 3 seconds"
260
+ end
261
+ end
240
262
  end
241
263
 
242
264
  def trap_signals_for_litespeed
@@ -262,7 +284,7 @@ module NewRelic
262
284
  # should not record sql in the current thread. Returns the
263
285
  # previous value, if there is one
264
286
  def set_record_sql(should_record) #THREAD_LOCAL_ACCESS
265
- state = TransactionState.tl_get
287
+ state = Tracer.state
266
288
  prev = state.record_sql
267
289
  state.record_sql = should_record
268
290
  prev.nil? || prev
@@ -273,13 +295,13 @@ module NewRelic
273
295
  # children of a transaction without affecting the tracing of
274
296
  # the whole transaction
275
297
  def push_trace_execution_flag(should_trace=false) #THREAD_LOCAL_ACCESS
276
- TransactionState.tl_get.push_traced(should_trace)
298
+ Tracer.state.push_traced(should_trace)
277
299
  end
278
300
 
279
301
  # Pop the current trace execution status. Restore trace execution status
280
302
  # to what it was before we pushed the current flag.
281
303
  def pop_trace_execution_flag #THREAD_LOCAL_ACCESS
282
- TransactionState.tl_get.pop_traced
304
+ Tracer.state.pop_traced
283
305
  end
284
306
 
285
307
  # Herein lies the corpse of the former 'start' method. May
@@ -327,7 +349,7 @@ module NewRelic
327
349
  end
328
350
 
329
351
  def log_app_name
330
- ::NewRelic::Agent.logger.info "Application: #{Agent.config.app_names.join(", ")}"
352
+ ::NewRelic::Agent.logger.info "Application: #{Agent.config[:app_name].join(", ")}"
331
353
  end
332
354
 
333
355
  def log_ignore_url_regexes
@@ -340,7 +362,7 @@ module NewRelic
340
362
 
341
363
  # Logs the configured application names
342
364
  def app_name_configured?
343
- names = Agent.config.app_names
365
+ names = Agent.config[:app_name]
344
366
  return names.respond_to?(:any?) && names.any?
345
367
  end
346
368
 
@@ -373,10 +395,8 @@ module NewRelic
373
395
  end
374
396
 
375
397
  def should_install_exit_handler?
376
- (
377
- Agent.config[:send_data_on_exit] &&
378
- !sinatra_classic_app?
379
- )
398
+ return false unless Agent.config[:send_data_on_exit]
399
+ !sinatra_classic_app? || Agent.config[:force_install_exit_handler]
380
400
  end
381
401
 
382
402
  def install_exit_handler
@@ -451,11 +471,11 @@ module NewRelic
451
471
  def defer_for_resque?
452
472
  NewRelic::Agent.config[:dispatcher] == :resque &&
453
473
  NewRelic::LanguageSupport.can_fork? &&
454
- !NewRelic::Agent::PipeChannelManager.listener.started?
474
+ !PipeChannelManager.listener.started?
455
475
  end
456
476
 
457
477
  def in_resque_child_process?
458
- defined?(@service) && @service.is_a?(NewRelic::Agent::PipeService)
478
+ defined?(@service) && @service.is_a?(PipeService)
459
479
  end
460
480
 
461
481
  # Sanity-check the agent configuration and start the agent,
@@ -476,8 +496,8 @@ module NewRelic
476
496
  @harvester.mark_started
477
497
 
478
498
  unless in_resque_child_process?
479
- generate_environment_report
480
499
  install_exit_handler
500
+ environment_for_connect
481
501
  @harvest_samplers.load_samplers unless Agent.config[:disable_samplers]
482
502
  end
483
503
 
@@ -527,7 +547,7 @@ module NewRelic
527
547
  check_config_and_start_agent
528
548
  log_version_and_pid
529
549
 
530
- events.subscribe(:finished_configuring) do
550
+ events.subscribe(:initial_configuration_complete) do
531
551
  log_ignore_url_regexes
532
552
  end
533
553
  end
@@ -543,7 +563,7 @@ module NewRelic
543
563
  @sql_sampler.reset!
544
564
 
545
565
  if Agent.config[:clear_transaction_state_after_fork]
546
- TransactionState.tl_clear
566
+ Tracer.clear_state
547
567
  end
548
568
  end
549
569
 
@@ -551,13 +571,16 @@ module NewRelic
551
571
  # This is necessary for cases where we're in a forked child and Ruby
552
572
  # might be holding locks for background thread that aren't there anymore.
553
573
  def reset_objects_with_locks
554
- @stats_engine = NewRelic::Agent::StatsEngine.new
574
+ @stats_engine = StatsEngine.new
555
575
  end
556
576
 
557
577
  def flush_pipe_data
558
- if connected? && @service.is_a?(::NewRelic::Agent::PipeService)
578
+ if connected? && @service.is_a?(PipeService)
559
579
  transmit_data
560
- transmit_event_data
580
+ transmit_analytic_event_data
581
+ transmit_custom_event_data
582
+ transmit_error_event_data
583
+ transmit_span_event_data
561
584
  end
562
585
  end
563
586
 
@@ -571,40 +594,48 @@ module NewRelic
571
594
  EventLoop.new
572
595
  end
573
596
 
574
- # Never allow any data type to be reported more frequently than once
575
- # per second.
576
- MIN_ALLOWED_REPORT_PERIOD = 1.0
597
+ LOG_ONCE_KEYS_RESET_PERIOD = 60.0
577
598
 
578
- def report_period_for(method)
579
- config_key = "data_report_periods.#{method}".to_sym
580
- period = Agent.config[config_key]
581
- if !period
582
- period = Agent.config[:data_report_period]
583
- ::NewRelic::Agent.logger.warn("Could not find configured period for #{method}, falling back to data_report_period (#{period} s)")
584
- end
585
- if period < MIN_ALLOWED_REPORT_PERIOD
586
- ::NewRelic::Agent.logger.warn("Configured #{config_key} was #{period}, but minimum allowed is #{MIN_ALLOWED_REPORT_PERIOD}, using #{MIN_ALLOWED_REPORT_PERIOD}.")
587
- period = MIN_ALLOWED_REPORT_PERIOD
588
- end
589
- period
599
+ # Certain event types may sometimes need to be on the same interval as metrics,
600
+ # so we will check config assigned in EventHarvestConfig to determine the interval
601
+ # on which to report them
602
+ def interval_for event_type
603
+ interval = Agent.config[:"event_report_period.#{event_type}"]
604
+ :"#{interval}_second_harvest"
590
605
  end
591
606
 
592
- LOG_ONCE_KEYS_RESET_PERIOD = 60.0
607
+ ANALYTIC_EVENT_DATA = "analytic_event_data".freeze
608
+ CUSTOM_EVENT_DATA = "custom_event_data".freeze
609
+ ERROR_EVENT_DATA = "error_event_data".freeze
610
+ SPAN_EVENT_DATA = "span_event_data".freeze
593
611
 
594
612
  def create_and_run_event_loop
613
+ data_harvest = :"#{Agent.config[:data_report_period]}_second_harvest"
614
+ event_harvest = :"#{Agent.config[:event_report_period]}_second_harvest"
615
+
595
616
  @event_loop = create_event_loop
596
- @event_loop.on(:report_data) do
617
+ @event_loop.on(data_harvest) do
597
618
  transmit_data
598
619
  end
599
- @event_loop.on(:report_event_data) do
600
- transmit_event_data
620
+
621
+ @event_loop.on(interval_for ANALYTIC_EVENT_DATA) do
622
+ transmit_analytic_event_data
623
+ end
624
+ @event_loop.on(interval_for CUSTOM_EVENT_DATA) do
625
+ transmit_custom_event_data
626
+ end
627
+ @event_loop.on(interval_for ERROR_EVENT_DATA) do
628
+ transmit_error_event_data
629
+ end
630
+ @event_loop.on(interval_for SPAN_EVENT_DATA) do
631
+ transmit_span_event_data
601
632
  end
602
633
  @event_loop.on(:reset_log_once_keys) do
603
634
  ::NewRelic::Agent.logger.clear_already_logged
604
635
  end
605
- @event_loop.fire_every(Agent.config[:data_report_period], :report_data)
606
- @event_loop.fire_every(report_period_for(:analytic_event_data), :report_event_data)
607
- @event_loop.fire_every(LOG_ONCE_KEYS_RESET_PERIOD, :reset_log_once_keys)
636
+ @event_loop.fire_every(Agent.config[:data_report_period], data_harvest)
637
+ @event_loop.fire_every(Agent.config[:event_report_period], event_harvest)
638
+ @event_loop.fire_every(LOG_ONCE_KEYS_RESET_PERIOD, :reset_log_once_keys)
608
639
 
609
640
  @event_loop.run
610
641
  end
@@ -624,7 +655,7 @@ module NewRelic
624
655
  # is the worker thread that gathers data and talks to the
625
656
  # server.
626
657
  def handle_force_disconnect(error)
627
- ::NewRelic::Agent.logger.warn "New Relic forced this agent to disconnect (#{error.message})"
658
+ ::NewRelic::Agent.logger.warn "Agent received a ForceDisconnectException from the server, disconnecting. (#{error.message})"
628
659
  disconnect
629
660
  end
630
661
 
@@ -632,7 +663,7 @@ module NewRelic
632
663
  # it and disconnecting the agent, since we are now in an
633
664
  # unknown state.
634
665
  def handle_other_error(error)
635
- ::NewRelic::Agent.logger.error "Unhandled error in worker thread, disconnecting this agent process:"
666
+ ::NewRelic::Agent.logger.error "Unhandled error in worker thread, disconnecting."
636
667
  # These errors are fatal (that is, they will prevent the agent from
637
668
  # reporting entirely), so we really want backtraces when they happen
638
669
  ::NewRelic::Agent.logger.log_exception(:error, error)
@@ -688,7 +719,7 @@ module NewRelic
688
719
  end
689
720
 
690
721
  ::NewRelic::Agent.logger.debug "Creating Ruby Agent worker thread."
691
- @worker_thread = NewRelic::Agent::Threading::AgentThread.create('Worker Loop') do
722
+ @worker_thread = Threading::AgentThread.create('Worker Loop') do
692
723
  deferred_work!(connection_options)
693
724
  end
694
725
  end
@@ -731,10 +762,8 @@ module NewRelic
731
762
  # /agents/agent-specs/Collector-Response-Handling.md, retry
732
763
  # connections after a specific backoff sequence to prevent
733
764
  # hammering the server.
734
- CONNECT_RETRY_PERIODS = [15, 15, 30, 60, 120, 300]
735
-
736
765
  def connect_retry_period
737
- CONNECT_RETRY_PERIODS[connect_attempts] || 300
766
+ NewRelic::CONNECT_RETRY_PERIODS[connect_attempts] || NewRelic::MAX_RETRY_PERIOD
738
767
  end
739
768
 
740
769
  def note_connect_failure
@@ -768,106 +797,59 @@ module NewRelic
768
797
  shutdown
769
798
  end
770
799
 
771
- def generate_environment_report
772
- @environment_report = environment_for_connect
773
- end
774
-
775
800
  # Checks whether we should send environment info, and if so,
776
801
  # returns the snapshot from the local environment.
777
802
  # Generating the EnvironmentReport has the potential to trigger
778
803
  # require calls in Rails environments, so this method should only
779
804
  # be called synchronously from on the main thread.
780
805
  def environment_for_connect
781
- Agent.config[:send_environment_info] ? Array(EnvironmentReport.new) : []
806
+ @environment_report ||= Agent.config[:send_environment_info] ? Array(EnvironmentReport.new) : []
782
807
  end
783
808
 
784
- # We've seen objects in the environment report (Rails.env in
785
- # particular) that can't seralize to JSON. Cope with that here and
786
- # clear out so downstream code doesn't have to check again.
787
- def sanitize_environment_report
788
- if !@service.valid_to_marshal?(@environment_report)
789
- @environment_report = []
790
- end
809
+ # Constructs and memoizes an event_harvest_config hash to be used in
810
+ # the payload sent during connect (and reconnect)
811
+ def event_harvest_config
812
+ @event_harvest_config ||= Configuration::EventHarvestConfig.from_config(Agent.config)
791
813
  end
792
814
 
793
- # Initializes the hash of settings that we send to the
794
- # server. Returns a literal hash containing the options
795
- def connect_settings
796
- sanitize_environment_report
797
-
798
- {
799
- :pid => $$,
800
- :host => local_host,
801
- :display_host => Agent.config[:'process_host.display_name'],
802
- :app_name => Agent.config.app_names,
803
- :language => 'ruby',
804
- :labels => Agent.config.parsed_labels,
805
- :agent_version => NewRelic::VERSION::STRING,
806
- :environment => @environment_report,
807
- :settings => Agent.config.to_collector_hash,
808
- :high_security => Agent.config[:high_security],
809
- :utilization => UtilizationData.new.to_collector_hash,
810
- :identifier => "ruby:#{local_host}:#{Agent.config.app_names.sort.join(',')}"
811
- }
812
- end
813
-
814
- # Returns connect data passed back from the server
815
+ # Builds the payload to send to the connect service,
816
+ # connects, then configures the agent using the response from
817
+ # the connect service
815
818
  def connect_to_server
816
- @service.connect(connect_settings)
817
- end
819
+ request_builder = ::NewRelic::Agent::Connect::RequestBuilder.new \
820
+ @service,
821
+ Agent.config,
822
+ event_harvest_config,
823
+ environment_for_connect
824
+ connect_response = @service.connect request_builder.connect_payload
818
825
 
819
- # apdex_f is always 4 times the apdex_t
820
- def apdex_f
821
- (4 * Agent.config[:apdex_t]).to_f
822
- end
826
+ response_handler = ::NewRelic::Agent::Connect::ResponseHandler.new(self, Agent.config)
827
+ response_handler.configure_agent(connect_response)
823
828
 
824
- # Sets the collector host and connects to the server, then
825
- # invokes the final configuration with the returned data
826
- def query_server_for_configuration
827
- finish_setup(connect_to_server)
829
+ log_connection connect_response if connect_response
830
+ connect_response
828
831
  end
829
832
 
830
- # Takes a hash of configuration data returned from the
831
- # server and uses it to set local variables and to
832
- # initialize various parts of the agent that are configured
833
- # separately.
834
- #
835
- # Can accommodate most arbitrary data - anything extra is
836
- # ignored unless we say to do something with it here.
837
- def finish_setup(config_data)
838
- return if config_data == nil
839
-
840
- @service.agent_id = config_data['agent_run_id']
841
-
842
- security_policies = config_data.delete('security_policies')
843
-
844
- add_server_side_config(config_data)
845
- add_security_policy_config(security_policies) if security_policies
846
-
847
- log_connection!(config_data)
848
- @transaction_rules = RulesEngine.create_transaction_rules(config_data)
849
- @stats_engine.metric_rules = RulesEngine.create_metric_rules(config_data)
850
-
851
- # If you're adding something else here to respond to the server-side config,
852
- # use Agent.instance.events.subscribe(:finished_configuring) callback instead!
833
+ # Logs when we connect to the server, for debugging purposes
834
+ # - makes sure we know if an agent has not connected
835
+ def log_connection(config_data)
836
+ ::NewRelic::Agent.logger.debug "Connected to NewRelic Service at #{@service.collector.name}"
837
+ ::NewRelic::Agent.logger.debug "Agent Run = #{@service.agent_id}."
838
+ ::NewRelic::Agent.logger.debug "Connection data = #{config_data.inspect}"
839
+ if config_data['messages'] && config_data['messages'].any?
840
+ log_collector_messages(config_data['messages'])
841
+ end
853
842
  end
854
843
 
855
- def add_server_side_config(config_data)
856
- if config_data['agent_config']
857
- ::NewRelic::Agent.logger.debug "Using config from server"
844
+ def log_collector_messages(messages)
845
+ messages.each do |message|
846
+ ::NewRelic::Agent.logger.send(message['level'].downcase, message['message'])
858
847
  end
859
-
860
- ::NewRelic::Agent.logger.debug "Server provided config: #{config_data.inspect}"
861
- server_config = NewRelic::Agent::Configuration::ServerSource.new(config_data, Agent.config)
862
- Agent.config.replace_or_add_config(server_config)
863
848
  end
864
849
 
865
- def add_security_policy_config(security_policies)
866
- ::NewRelic::Agent.logger.info 'Installing security policies'
867
- security_policy_source = NewRelic::Agent::Configuration::SecurityPolicySource.new(security_policies)
868
- Agent.config.replace_or_add_config(security_policy_source)
869
- # drop data collected before applying security policies
870
- drop_buffered_data
850
+ # apdex_f is always 4 times the apdex_t
851
+ def apdex_f
852
+ (4 * Agent.config[:apdex_t]).to_f
871
853
  end
872
854
 
873
855
  class WaitOnConnectTimeout < StandardError
@@ -899,22 +881,6 @@ module NewRelic
899
881
  end
900
882
  end
901
883
 
902
- # Logs when we connect to the server, for debugging purposes
903
- # - makes sure we know if an agent has not connected
904
- def log_connection!(config_data)
905
- ::NewRelic::Agent.logger.debug "Connected to NewRelic Service at #{@service.collector.name}"
906
- ::NewRelic::Agent.logger.debug "Agent Run = #{@service.agent_id}."
907
- ::NewRelic::Agent.logger.debug "Connection data = #{config_data.inspect}"
908
- if config_data['messages'] && config_data['messages'].any?
909
- log_collector_messages(config_data['messages'])
910
- end
911
- end
912
-
913
- def log_collector_messages(messages)
914
- messages.each do |message|
915
- ::NewRelic::Agent.logger.send(message['level'].downcase, message['message'])
916
- end
917
- end
918
884
  end
919
885
  include Connect
920
886
 
@@ -974,7 +940,7 @@ module NewRelic
974
940
  return unless should_connect?(opts[:force_reconnect])
975
941
 
976
942
  ::NewRelic::Agent.logger.debug "Connecting Process to New Relic: #$0"
977
- query_server_for_configuration
943
+ connect_to_server
978
944
  @connected_pid = $$
979
945
  @connect_state = :connected
980
946
  signal_connected
@@ -985,6 +951,10 @@ module NewRelic
985
951
  rescue NewRelic::Agent::UnrecoverableAgentException => e
986
952
  handle_unrecoverable_agent_error(e)
987
953
  rescue StandardError, Timeout::Error, NewRelic::Agent::ServerConnectionException => e
954
+ # Allow a killed (aborting) thread to continue exiting during shutdown.
955
+ # See: https://github.com/newrelic/newrelic-ruby-agent/issues/340
956
+ raise if Thread.current.status == 'aborting'
957
+
988
958
  log_error(e)
989
959
  if opts[:keep_retrying]
990
960
  note_connect_failure
@@ -998,15 +968,6 @@ module NewRelic
998
968
  raise
999
969
  end
1000
970
 
1001
- # Who am I? Well, this method can tell you your hostname.
1002
- def determine_host
1003
- NewRelic::Agent::Hostname.get
1004
- end
1005
-
1006
- def local_host
1007
- @local_host ||= determine_host
1008
- end
1009
-
1010
971
  # Delegates to the control class to determine the root
1011
972
  # directory of this project
1012
973
  def determine_home_directory
@@ -1077,7 +1038,7 @@ module NewRelic
1077
1038
  end
1078
1039
 
1079
1040
  def harvest_and_send_timeslice_data
1080
- NewRelic::Agent::TransactionTimeAggregator.harvest!
1041
+ TransactionTimeAggregator.harvest!
1081
1042
  harvest_and_send_from_container(@stats_engine, :metric_data)
1082
1043
  end
1083
1044
 
@@ -1106,19 +1067,27 @@ module NewRelic
1106
1067
  def harvest_and_send_analytic_event_data
1107
1068
  harvest_and_send_from_container(transaction_event_aggregator, :analytic_event_data)
1108
1069
  harvest_and_send_from_container(synthetics_event_aggregator, :analytic_event_data)
1109
- harvest_and_send_from_container(@custom_event_aggregator, :custom_event_data)
1110
- harvest_and_send_from_container(span_event_aggregator, :span_event_data)
1070
+ end
1071
+
1072
+ def harvest_and_send_custom_event_data
1073
+ harvest_and_send_from_container(@custom_event_aggregator, :custom_event_data)
1111
1074
  end
1112
1075
 
1113
1076
  def harvest_and_send_error_event_data
1114
1077
  harvest_and_send_from_container @error_collector.error_event_aggregator, :error_event_data
1115
1078
  end
1116
1079
 
1080
+ def harvest_and_send_span_event_data
1081
+ harvest_and_send_from_container(span_event_aggregator, :span_event_data)
1082
+ end
1083
+
1117
1084
  def check_for_and_handle_agent_commands
1118
1085
  begin
1119
1086
  @agent_command_router.check_for_and_handle_agent_commands
1120
1087
  rescue ForceRestartException, ForceDisconnectException
1121
1088
  raise
1089
+ rescue UnrecoverableServerException => e
1090
+ NewRelic::Agent.logger.warn("get_agent_commands message was rejected by remote service, discarding. Error: ", e)
1122
1091
  rescue ServerConnectionException => e
1123
1092
  log_remote_unavailable(:get_agent_commands, e)
1124
1093
  rescue => e
@@ -1132,18 +1101,30 @@ module NewRelic
1132
1101
  NewRelic::Agent.record_metric("Supportability/remote_unavailable/#{endpoint.to_s}", 0.0)
1133
1102
  end
1134
1103
 
1135
- def transmit_event_data
1136
- transmit_single_data_type(:harvest_and_send_analytic_event_data, "TransactionEvent")
1104
+ TRANSACTION_EVENT = "TransactionEvent".freeze
1105
+ def transmit_analytic_event_data
1106
+ transmit_single_data_type(:harvest_and_send_analytic_event_data, TRANSACTION_EVENT)
1107
+ end
1108
+
1109
+ CUSTOM_EVENT = "CustomEvent".freeze
1110
+ def transmit_custom_event_data
1111
+ transmit_single_data_type(:harvest_and_send_custom_event_data, CUSTOM_EVENT)
1112
+ end
1113
+
1114
+ ERROR_EVENT = "ErrorEvent".freeze
1115
+ def transmit_error_event_data
1116
+ transmit_single_data_type(:harvest_and_send_error_event_data, ERROR_EVENT)
1137
1117
  end
1138
1118
 
1119
+ SPAN_EVENT = "SpanEvent".freeze
1139
1120
  def transmit_span_event_data
1140
- transmit_single_data_type(:harvest_and_send_span_event_data, "SpanEvent")
1121
+ transmit_single_data_type(:harvest_and_send_span_event_data, SPAN_EVENT)
1141
1122
  end
1142
1123
 
1143
1124
  def transmit_single_data_type(harvest_method, supportability_name)
1144
1125
  now = Time.now
1145
1126
 
1146
- msg = "Sending #{harvest_method.to_s.gsub("harvest_and_send_", "")} to New Relic Service"
1127
+ msg = "Sending #{supportability_name} data to New Relic Service"
1147
1128
  ::NewRelic::Agent.logger.debug msg
1148
1129
 
1149
1130
  @service.session do # use http keep-alive
@@ -1165,6 +1146,7 @@ module NewRelic
1165
1146
  harvest_and_send_transaction_traces
1166
1147
  harvest_and_send_slowest_sql
1167
1148
  harvest_and_send_timeslice_data
1149
+ harvest_and_send_span_event_data
1168
1150
 
1169
1151
  check_for_and_handle_agent_commands
1170
1152
  harvest_and_send_for_agent_commands
@@ -1189,7 +1171,10 @@ module NewRelic
1189
1171
 
1190
1172
  @events.notify(:before_shutdown)
1191
1173
  transmit_data
1192
- transmit_event_data
1174
+ transmit_analytic_event_data
1175
+ transmit_custom_event_data
1176
+ transmit_error_event_data
1177
+ transmit_span_event_data
1193
1178
 
1194
1179
  if @connected_pid == $$ && !@service.kind_of?(NewRelic::Agent::NewRelicService)
1195
1180
  ::NewRelic::Agent.logger.debug "Sending New Relic service agent run shutdown message"