newrelic_rpm 9.1.0 → 9.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (360) hide show
  1. checksums.yaml +4 -4
  2. data/.build_ignore +27 -0
  3. data/CHANGELOG.md +841 -7
  4. data/CONTRIBUTING.md +2 -9
  5. data/README.md +25 -22
  6. data/Rakefile +2 -2
  7. data/bin/newrelic +3 -9
  8. data/bin/newrelic_rpm +15 -0
  9. data/init.rb +2 -2
  10. data/lib/boot/strap.rb +102 -0
  11. data/lib/new_relic/agent/agent.rb +11 -2
  12. data/lib/new_relic/agent/agent_helpers/connect.rb +13 -8
  13. data/lib/new_relic/agent/agent_helpers/harvest.rb +3 -0
  14. data/lib/new_relic/agent/agent_helpers/shutdown.rb +4 -1
  15. data/lib/new_relic/agent/agent_helpers/special_startup.rb +1 -1
  16. data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +4 -3
  17. data/lib/new_relic/agent/agent_helpers/startup.rb +11 -3
  18. data/lib/new_relic/agent/agent_logger.rb +3 -1
  19. data/lib/new_relic/agent/attribute_filter.rb +3 -3
  20. data/lib/new_relic/agent/attribute_pre_filtering.rb +109 -0
  21. data/lib/new_relic/agent/aws.rb +68 -0
  22. data/lib/new_relic/agent/configuration/default_source.rb +918 -166
  23. data/lib/new_relic/agent/configuration/environment_source.rb +15 -3
  24. data/lib/new_relic/agent/configuration/high_security_source.rb +1 -0
  25. data/lib/new_relic/agent/configuration/manager.rb +72 -11
  26. data/lib/new_relic/agent/configuration/security_policy_source.rb +11 -0
  27. data/lib/new_relic/agent/configuration/yaml_source.rb +22 -2
  28. data/lib/new_relic/agent/connect/request_builder.rb +1 -1
  29. data/lib/new_relic/agent/custom_event_aggregator.rb +27 -1
  30. data/lib/new_relic/agent/database/obfuscation_helpers.rb +11 -11
  31. data/lib/new_relic/agent/database/obfuscator.rb +1 -0
  32. data/lib/new_relic/agent/database.rb +41 -1
  33. data/lib/new_relic/agent/database_adapter.rb +1 -1
  34. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +1 -1
  35. data/lib/new_relic/agent/datastores/redis.rb +1 -1
  36. data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +1 -1
  37. data/lib/new_relic/agent/distributed_tracing/distributed_trace_payload.rb +4 -8
  38. data/lib/new_relic/agent/distributed_tracing.rb +5 -3
  39. data/lib/new_relic/agent/error_collector.rb +40 -11
  40. data/lib/new_relic/agent/event_loop.rb +1 -1
  41. data/lib/new_relic/agent/external.rb +2 -0
  42. data/lib/new_relic/agent/harvester.rb +1 -1
  43. data/lib/new_relic/agent/health_check.rb +136 -0
  44. data/lib/new_relic/agent/http_clients/abstract.rb +4 -0
  45. data/lib/new_relic/agent/http_clients/async_http_wrappers.rb +80 -0
  46. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +1 -3
  47. data/lib/new_relic/agent/http_clients/ethon_wrappers.rb +109 -0
  48. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +0 -3
  49. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +1 -3
  50. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +0 -3
  51. data/lib/new_relic/agent/http_clients/httpx_wrappers.rb +91 -0
  52. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +1 -4
  53. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +0 -3
  54. data/lib/new_relic/agent/http_clients/uri_util.rb +1 -1
  55. data/lib/new_relic/agent/instrumentation/action_controller_other_subscriber.rb +1 -1
  56. data/lib/new_relic/agent/instrumentation/action_dispatch.rb +1 -1
  57. data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +1 -1
  58. data/lib/new_relic/agent/instrumentation/action_mailbox.rb +1 -1
  59. data/lib/new_relic/agent/instrumentation/action_mailer.rb +1 -1
  60. data/lib/new_relic/agent/instrumentation/active_job.rb +1 -1
  61. data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +6 -2
  62. data/lib/new_relic/agent/instrumentation/active_merchant.rb +3 -16
  63. data/lib/new_relic/agent/instrumentation/active_record.rb +8 -13
  64. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +8 -5
  65. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +13 -10
  66. data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +2 -2
  67. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +9 -16
  68. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/chain.rb +69 -0
  69. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/instrumentation.rb +17 -0
  70. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger/prepend.rb +37 -0
  71. data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger.rb +21 -0
  72. data/lib/new_relic/agent/instrumentation/active_support_logger/instrumentation.rb +4 -0
  73. data/lib/new_relic/agent/instrumentation/active_support_logger.rb +3 -3
  74. data/lib/new_relic/agent/instrumentation/async_http/chain.rb +23 -0
  75. data/lib/new_relic/agent/instrumentation/async_http/instrumentation.rb +37 -0
  76. data/lib/new_relic/agent/instrumentation/async_http/prepend.rb +15 -0
  77. data/lib/new_relic/agent/instrumentation/async_http.rb +27 -0
  78. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/chain.rb +21 -0
  79. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/instrumentation.rb +66 -0
  80. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose/prepend.rb +15 -0
  81. data/lib/new_relic/agent/instrumentation/aws_sdk_firehose.rb +22 -0
  82. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/chain.rb +21 -0
  83. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/instrumentation.rb +91 -0
  84. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/prepend.rb +15 -0
  85. data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis.rb +22 -0
  86. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/chain.rb +33 -0
  87. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/instrumentation.rb +93 -0
  88. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda/prepend.rb +23 -0
  89. data/lib/new_relic/agent/instrumentation/aws_sdk_lambda.rb +23 -0
  90. data/lib/new_relic/agent/instrumentation/aws_sqs/chain.rb +37 -0
  91. data/lib/new_relic/agent/instrumentation/aws_sqs/instrumentation.rb +67 -0
  92. data/lib/new_relic/agent/instrumentation/aws_sqs/prepend.rb +21 -0
  93. data/lib/new_relic/agent/instrumentation/aws_sqs.rb +23 -0
  94. data/lib/new_relic/agent/instrumentation/bunny/chain.rb +1 -1
  95. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +23 -0
  96. data/lib/new_relic/agent/instrumentation/bunny.rb +4 -5
  97. data/lib/new_relic/agent/instrumentation/concurrent_ruby/chain.rb +1 -1
  98. data/lib/new_relic/agent/instrumentation/concurrent_ruby/instrumentation.rb +3 -4
  99. data/lib/new_relic/agent/instrumentation/concurrent_ruby/prepend.rb +1 -1
  100. data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +2 -3
  101. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +5 -2
  102. data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +4 -0
  103. data/lib/new_relic/agent/instrumentation/curb.rb +4 -5
  104. data/lib/new_relic/agent/instrumentation/delayed_job/chain.rb +1 -0
  105. data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +3 -0
  106. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +0 -23
  107. data/lib/new_relic/agent/instrumentation/dynamodb/chain.rb +27 -0
  108. data/lib/new_relic/agent/instrumentation/dynamodb/instrumentation.rb +64 -0
  109. data/lib/new_relic/agent/instrumentation/dynamodb/prepend.rb +19 -0
  110. data/lib/new_relic/agent/instrumentation/dynamodb.rb +23 -0
  111. data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +2 -3
  112. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +65 -10
  113. data/lib/new_relic/agent/instrumentation/elasticsearch.rb +2 -4
  114. data/lib/new_relic/agent/instrumentation/ethon/chain.rb +39 -0
  115. data/lib/new_relic/agent/instrumentation/ethon/instrumentation.rb +105 -0
  116. data/lib/new_relic/agent/instrumentation/ethon/prepend.rb +35 -0
  117. data/lib/new_relic/agent/instrumentation/ethon.rb +35 -0
  118. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +3 -0
  119. data/lib/new_relic/agent/instrumentation/excon.rb +1 -17
  120. data/lib/new_relic/agent/instrumentation/fiber/chain.rb +11 -4
  121. data/lib/new_relic/agent/instrumentation/fiber/instrumentation.rb +2 -6
  122. data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +10 -3
  123. data/lib/new_relic/agent/instrumentation/fiber.rb +1 -3
  124. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +4 -3
  125. data/lib/new_relic/agent/instrumentation/grape.rb +1 -1
  126. data/lib/new_relic/agent/instrumentation/grpc/client/chain.rb +1 -1
  127. data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +5 -2
  128. data/lib/new_relic/agent/instrumentation/grpc/client/prepend.rb +1 -1
  129. data/lib/new_relic/agent/instrumentation/grpc/client/request_wrapper.rb +1 -1
  130. data/lib/new_relic/agent/instrumentation/grpc/server/instrumentation.rb +5 -1
  131. data/lib/new_relic/agent/instrumentation/grpc_client.rb +2 -2
  132. data/lib/new_relic/agent/instrumentation/grpc_server.rb +2 -2
  133. data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +4 -0
  134. data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -5
  135. data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +4 -0
  136. data/lib/new_relic/agent/instrumentation/httprb.rb +0 -1
  137. data/lib/new_relic/agent/instrumentation/httpx/chain.rb +20 -0
  138. data/lib/new_relic/agent/instrumentation/httpx/instrumentation.rb +51 -0
  139. data/lib/new_relic/agent/instrumentation/httpx/prepend.rb +15 -0
  140. data/lib/new_relic/agent/instrumentation/httpx.rb +23 -0
  141. data/lib/new_relic/agent/instrumentation/logger/instrumentation.rb +3 -0
  142. data/lib/new_relic/agent/instrumentation/logger.rb +1 -3
  143. data/lib/new_relic/agent/instrumentation/logstasher/chain.rb +21 -0
  144. data/lib/new_relic/agent/instrumentation/logstasher/instrumentation.rb +24 -0
  145. data/lib/new_relic/agent/instrumentation/logstasher/prepend.rb +13 -0
  146. data/lib/new_relic/agent/instrumentation/logstasher.rb +25 -0
  147. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +4 -2
  148. data/lib/new_relic/agent/instrumentation/memcache/helper.rb +2 -2
  149. data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +13 -4
  150. data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +4 -2
  151. data/lib/new_relic/agent/instrumentation/memcache.rb +4 -5
  152. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +3 -5
  153. data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +13 -3
  154. data/lib/new_relic/agent/instrumentation/net_http.rb +2 -1
  155. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +4 -2
  156. data/lib/new_relic/agent/instrumentation/opensearch/chain.rb +21 -0
  157. data/lib/new_relic/agent/instrumentation/opensearch/instrumentation.rb +66 -0
  158. data/lib/new_relic/agent/instrumentation/opensearch/prepend.rb +13 -0
  159. data/lib/new_relic/agent/instrumentation/opensearch.rb +23 -0
  160. data/lib/new_relic/agent/instrumentation/padrino/instrumentation.rb +4 -0
  161. data/lib/new_relic/agent/instrumentation/padrino.rb +3 -3
  162. data/lib/new_relic/agent/instrumentation/queue_time.rb +1 -1
  163. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +9 -0
  164. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +4 -0
  165. data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +1 -1
  166. data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +10 -5
  167. data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +4 -0
  168. data/lib/new_relic/agent/instrumentation/rake.rb +1 -2
  169. data/lib/new_relic/agent/instrumentation/rdkafka/chain.rb +72 -0
  170. data/lib/new_relic/agent/instrumentation/rdkafka/instrumentation.rb +70 -0
  171. data/lib/new_relic/agent/instrumentation/rdkafka/prepend.rb +67 -0
  172. data/lib/new_relic/agent/instrumentation/rdkafka.rb +25 -0
  173. data/lib/new_relic/agent/instrumentation/redis/cluster_middleware.rb +26 -0
  174. data/lib/new_relic/agent/instrumentation/redis/constants.rb +2 -2
  175. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +18 -11
  176. data/lib/new_relic/agent/instrumentation/redis/middleware.rb +3 -0
  177. data/lib/new_relic/agent/instrumentation/redis.rb +11 -5
  178. data/lib/new_relic/agent/instrumentation/resque/instrumentation.rb +4 -0
  179. data/lib/new_relic/agent/instrumentation/resque.rb +8 -6
  180. data/lib/new_relic/agent/instrumentation/roda/chain.rb +43 -0
  181. data/lib/new_relic/agent/instrumentation/roda/ignorer.rb +45 -0
  182. data/lib/new_relic/agent/instrumentation/roda/instrumentation.rb +68 -0
  183. data/lib/new_relic/agent/instrumentation/roda/prepend.rb +24 -0
  184. data/lib/new_relic/agent/instrumentation/roda/roda_transaction_namer.rb +29 -0
  185. data/lib/new_relic/agent/instrumentation/roda.rb +36 -0
  186. data/lib/new_relic/agent/instrumentation/ruby_kafka/chain.rb +55 -0
  187. data/lib/new_relic/agent/instrumentation/ruby_kafka/instrumentation.rb +67 -0
  188. data/lib/new_relic/agent/instrumentation/ruby_kafka/prepend.rb +60 -0
  189. data/lib/new_relic/agent/instrumentation/ruby_kafka.rb +25 -0
  190. data/lib/new_relic/agent/instrumentation/ruby_openai/chain.rb +36 -0
  191. data/lib/new_relic/agent/instrumentation/ruby_openai/instrumentation.rb +196 -0
  192. data/lib/new_relic/agent/instrumentation/ruby_openai/prepend.rb +20 -0
  193. data/lib/new_relic/agent/instrumentation/ruby_openai.rb +35 -0
  194. data/lib/new_relic/agent/instrumentation/sequel.rb +1 -1
  195. data/lib/new_relic/agent/instrumentation/sidekiq/client.rb +4 -0
  196. data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delay_extensions.rb +24 -0
  197. data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +2 -2
  198. data/lib/new_relic/agent/instrumentation/sidekiq/server.rb +26 -3
  199. data/lib/new_relic/agent/instrumentation/sidekiq.rb +13 -16
  200. data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +1 -1
  201. data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +4 -0
  202. data/lib/new_relic/agent/instrumentation/sinatra/transaction_namer.rb +1 -3
  203. data/lib/new_relic/agent/instrumentation/sinatra.rb +3 -19
  204. data/lib/new_relic/agent/instrumentation/stripe.rb +28 -0
  205. data/lib/new_relic/agent/instrumentation/stripe_subscriber.rb +98 -0
  206. data/lib/new_relic/agent/instrumentation/thread/chain.rb +1 -1
  207. data/lib/new_relic/agent/instrumentation/thread/instrumentation.rb +1 -5
  208. data/lib/new_relic/agent/instrumentation/thread/prepend.rb +1 -1
  209. data/lib/new_relic/agent/instrumentation/thread.rb +0 -2
  210. data/lib/new_relic/agent/instrumentation/tilt/instrumentation.rb +4 -0
  211. data/lib/new_relic/agent/instrumentation/tilt.rb +0 -4
  212. data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +7 -3
  213. data/lib/new_relic/agent/instrumentation/typhoeus.rb +0 -1
  214. data/lib/new_relic/agent/instrumentation/view_component/chain.rb +21 -0
  215. data/lib/new_relic/agent/instrumentation/view_component/instrumentation.rb +45 -0
  216. data/lib/{tasks/instrumentation_generator/templates/instrumentation.tt → new_relic/agent/instrumentation/view_component/prepend.rb} +4 -4
  217. data/lib/new_relic/agent/instrumentation/view_component.rb +24 -0
  218. data/lib/new_relic/agent/javascript_instrumentor.rb +2 -4
  219. data/lib/new_relic/agent/llm/chat_completion_message.rb +25 -0
  220. data/lib/new_relic/agent/llm/chat_completion_summary.rb +66 -0
  221. data/lib/new_relic/agent/llm/embedding.rb +60 -0
  222. data/lib/new_relic/agent/llm/llm_event.rb +95 -0
  223. data/lib/new_relic/agent/llm/response_headers.rb +80 -0
  224. data/lib/new_relic/agent/llm.rb +49 -0
  225. data/lib/new_relic/agent/local_log_decorator.rb +20 -3
  226. data/lib/new_relic/agent/log_event_aggregator.rb +149 -26
  227. data/lib/new_relic/agent/log_event_attributes.rb +115 -0
  228. data/lib/new_relic/agent/logging.rb +5 -5
  229. data/lib/new_relic/agent/messaging.rb +18 -7
  230. data/lib/new_relic/agent/method_tracer.rb +4 -1
  231. data/lib/new_relic/agent/method_tracer_helpers.rb +26 -5
  232. data/lib/new_relic/agent/monitors/inbound_request_monitor.rb +1 -1
  233. data/lib/new_relic/agent/monitors/synthetics_monitor.rb +12 -1
  234. data/lib/new_relic/agent/new_relic_service/encoders.rb +2 -2
  235. data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +2 -2
  236. data/lib/new_relic/agent/new_relic_service.rb +61 -28
  237. data/lib/new_relic/agent/obfuscator.rb +0 -2
  238. data/lib/new_relic/agent/opentelemetry/context/propagation/trace_propagator.rb +66 -0
  239. data/lib/new_relic/agent/opentelemetry/context/propagation.rb +15 -0
  240. data/lib/{tasks/instrumentation_generator/templates/Envfile.tt → new_relic/agent/opentelemetry/context.rb} +9 -5
  241. data/lib/new_relic/agent/opentelemetry/trace/span.rb +31 -0
  242. data/lib/new_relic/agent/opentelemetry/trace/tracer.rb +129 -0
  243. data/lib/new_relic/agent/opentelemetry/trace/tracer_provider.rb +18 -0
  244. data/lib/new_relic/agent/opentelemetry/trace.rb +15 -0
  245. data/lib/new_relic/agent/opentelemetry/transaction_patch.rb +69 -0
  246. data/lib/new_relic/agent/opentelemetry_bridge.rb +32 -0
  247. data/lib/new_relic/agent/parameter_filtering.rb +1 -1
  248. data/lib/new_relic/agent/pipe_channel_manager.rb +2 -2
  249. data/lib/new_relic/agent/pipe_service.rb +1 -1
  250. data/lib/new_relic/agent/rules_engine/segment_terms_rule.rb +1 -2
  251. data/lib/new_relic/agent/rules_engine.rb +1 -1
  252. data/lib/new_relic/agent/sampler.rb +1 -0
  253. data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -1
  254. data/lib/new_relic/agent/samplers/memory_sampler.rb +1 -1
  255. data/lib/new_relic/agent/serverless_handler.rb +406 -0
  256. data/lib/new_relic/agent/serverless_handler_event_sources.json +155 -0
  257. data/lib/new_relic/agent/serverless_handler_event_sources.rb +49 -0
  258. data/lib/new_relic/agent/span_event_primitive.rb +32 -15
  259. data/lib/new_relic/agent/sql_sampler.rb +0 -1
  260. data/lib/new_relic/agent/system_info.rb +40 -0
  261. data/lib/new_relic/agent/threading/agent_thread.rb +1 -2
  262. data/lib/new_relic/agent/threading/backtrace_node.rb +10 -1
  263. data/lib/new_relic/agent/tracer.rb +16 -16
  264. data/lib/new_relic/agent/transaction/abstract_segment.rb +103 -41
  265. data/lib/new_relic/agent/transaction/datastore_segment.rb +1 -1
  266. data/lib/new_relic/agent/transaction/distributed_tracer.rb +3 -3
  267. data/lib/new_relic/agent/transaction/distributed_tracing.rb +7 -8
  268. data/lib/new_relic/agent/transaction/external_request_segment.rb +5 -12
  269. data/lib/new_relic/agent/transaction/message_broker_segment.rb +5 -3
  270. data/lib/new_relic/agent/transaction/request_attributes.rb +54 -11
  271. data/lib/new_relic/agent/transaction/trace_context.rb +34 -5
  272. data/lib/new_relic/agent/transaction/tracing.rb +20 -4
  273. data/lib/new_relic/agent/transaction.rb +38 -13
  274. data/lib/new_relic/agent/transaction_error_primitive.rb +39 -19
  275. data/lib/new_relic/agent/transaction_event_primitive.rb +19 -0
  276. data/lib/new_relic/agent/transaction_time_aggregator.rb +1 -1
  277. data/lib/new_relic/agent/utilization/ecs.rb +22 -0
  278. data/lib/new_relic/agent/utilization/ecs_v4.rb +22 -0
  279. data/lib/new_relic/agent/utilization/gcp.rb +1 -3
  280. data/lib/new_relic/agent/utilization/vendor.rb +5 -7
  281. data/lib/new_relic/agent/utilization_data.rb +40 -5
  282. data/lib/new_relic/agent/vm/{mri_vm.rb → c_ruby_vm.rb} +10 -18
  283. data/lib/new_relic/agent/vm.rb +2 -2
  284. data/lib/new_relic/agent/worker_loop.rb +1 -1
  285. data/lib/new_relic/agent.rb +286 -17
  286. data/lib/new_relic/base64.rb +25 -0
  287. data/lib/new_relic/cli/command.rb +6 -3
  288. data/lib/new_relic/constants.rb +8 -0
  289. data/lib/new_relic/control/class_methods.rb +1 -7
  290. data/lib/new_relic/control/frameworks/grape.rb +14 -0
  291. data/lib/new_relic/control/frameworks/padrino.rb +14 -0
  292. data/lib/new_relic/control/frameworks/rails.rb +17 -5
  293. data/lib/new_relic/control/frameworks/rails4.rb +1 -3
  294. data/lib/new_relic/control/frameworks/roda.rb +20 -0
  295. data/lib/new_relic/control/instance_methods.rb +13 -0
  296. data/lib/new_relic/control/instrumentation.rb +2 -16
  297. data/lib/new_relic/control/private_instance_methods.rb +4 -0
  298. data/lib/new_relic/control/security_interface.rb +57 -0
  299. data/lib/new_relic/control.rb +1 -1
  300. data/lib/new_relic/dependency_detection.rb +25 -13
  301. data/lib/new_relic/environment_report.rb +2 -2
  302. data/lib/new_relic/helper.rb +22 -0
  303. data/lib/new_relic/language_support.rb +12 -1
  304. data/lib/new_relic/latest_changes.rb +1 -1
  305. data/lib/new_relic/local_environment.rb +31 -18
  306. data/lib/new_relic/noticed_error.rb +5 -2
  307. data/lib/new_relic/rack/agent_hooks.rb +1 -1
  308. data/lib/new_relic/rack/agent_middleware.rb +0 -16
  309. data/lib/new_relic/rack/browser_monitoring.rb +29 -13
  310. data/lib/new_relic/supportability_helper.rb +5 -1
  311. data/lib/new_relic/thread_local_storage.rb +31 -0
  312. data/lib/new_relic/traced_thread.rb +2 -3
  313. data/lib/new_relic/version.rb +1 -1
  314. data/lib/sequel/extensions/new_relic_instrumentation.rb +4 -3
  315. data/lib/tasks/bump_version.rake +21 -0
  316. data/lib/tasks/config.rake +11 -5
  317. data/lib/tasks/coverage_report.rake +1 -1
  318. data/lib/tasks/gha.rake +31 -0
  319. data/lib/tasks/helpers/config.html.erb +94 -0
  320. data/lib/tasks/helpers/format.rb +11 -7
  321. data/lib/tasks/helpers/newrelicyml.rb +211 -0
  322. data/lib/tasks/helpers/version_bump.rb +62 -0
  323. data/lib/tasks/newrelic.rb +1 -0
  324. data/lib/tasks/newrelicyml.rake +13 -0
  325. data/lib/tasks/tests.rake +71 -0
  326. data/newrelic.yml +657 -251
  327. data/newrelic_rpm.gemspec +17 -10
  328. data/test/agent_helper.rb +38 -4
  329. metadata +230 -44
  330. data/.gitignore +0 -43
  331. data/.project +0 -23
  332. data/.rubocop.yml +0 -1909
  333. data/.rubocop_todo.yml +0 -61
  334. data/.simplecov +0 -15
  335. data/.snyk +0 -11
  336. data/.yardopts +0 -27
  337. data/Brewfile +0 -12
  338. data/DOCKER.md +0 -167
  339. data/Dockerfile +0 -10
  340. data/Guardfile +0 -26
  341. data/bin/newrelic_cmd +0 -6
  342. data/config/database.yml +0 -5
  343. data/config.dot +0 -278
  344. data/docker-compose.yml +0 -107
  345. data/lefthook.yml +0 -9
  346. data/lib/new_relic/agent/range_extensions.rb +0 -27
  347. data/lib/tasks/helpers/removers.rb +0 -33
  348. data/lib/tasks/instrumentation_generator/README.md +0 -63
  349. data/lib/tasks/instrumentation_generator/TODO.md +0 -33
  350. data/lib/tasks/instrumentation_generator/instrumentation.thor +0 -121
  351. data/lib/tasks/instrumentation_generator/templates/chain.tt +0 -22
  352. data/lib/tasks/instrumentation_generator/templates/chain_method.tt +0 -8
  353. data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +0 -29
  354. data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +0 -3
  355. data/lib/tasks/instrumentation_generator/templates/newrelic.yml.tt +0 -19
  356. data/lib/tasks/instrumentation_generator/templates/prepend.tt +0 -13
  357. data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +0 -3
  358. data/lib/tasks/instrumentation_generator/templates/test.tt +0 -15
  359. data/lib/tasks/multiverse.rake +0 -6
  360. data/lib/tasks/multiverse.rb +0 -83
@@ -20,15 +20,15 @@ module NewRelic
20
20
  # examine in order to look for a RUM insertion point.
21
21
  SCAN_LIMIT = 50_000
22
22
 
23
- CONTENT_TYPE = 'Content-Type'.freeze
24
- CONTENT_DISPOSITION = 'Content-Disposition'.freeze
25
- CONTENT_LENGTH = 'Content-Length'.freeze
26
- ATTACHMENT = 'attachment'.freeze
27
- TEXT_HTML = 'text/html'.freeze
23
+ CONTENT_TYPE = 'Content-Type'
24
+ CONTENT_DISPOSITION = 'Content-Disposition'
25
+ CONTENT_LENGTH = 'Content-Length'
26
+ ATTACHMENT = /attachment/.freeze
27
+ TEXT_HTML = %r{text/html}.freeze
28
28
 
29
- BODY_START = '<body'.freeze
30
- HEAD_START = '<head'.freeze
31
- GT = '>'.freeze
29
+ BODY_START = '<body'
30
+ HEAD_START = '<head'
31
+ GT = '>'
32
32
 
33
33
  ALREADY_INSTRUMENTED_KEY = 'newrelic.browser_monitoring_already_instrumented'
34
34
  CHARSET_RE = /<\s*meta[^>]+charset\s*=[^>]*>/im.freeze
@@ -38,7 +38,7 @@ module NewRelic
38
38
  result = @app.call(env)
39
39
  (status, headers, response) = result
40
40
 
41
- js_to_inject = NewRelic::Agent.browser_timing_header
41
+ js_to_inject = NewRelic::Agent.browser_timing_header(nonce(env))
42
42
  if (js_to_inject != NewRelic::EMPTY_STR) && should_instrument?(env, status, headers)
43
43
  response_string = autoinstrument_source(response, js_to_inject)
44
44
  if headers.key?(CONTENT_LENGTH)
@@ -58,6 +58,14 @@ module NewRelic
58
58
  end
59
59
  end
60
60
 
61
+ def nonce(env)
62
+ return unless NewRelic::Agent.config[:'browser_monitoring.content_security_policy_nonce']
63
+ return unless NewRelic::Agent.config[:framework] == :rails_notifications
64
+ return unless defined?(ActionDispatch::ContentSecurityPolicy::Request)
65
+
66
+ env[ActionDispatch::ContentSecurityPolicy::Request::NONCE]
67
+ end
68
+
61
69
  def should_instrument?(env, status, headers)
62
70
  NewRelic::Agent.config[:'browser_monitoring.auto_instrument'] &&
63
71
  status == 200 &&
@@ -65,6 +73,10 @@ module NewRelic
65
73
  html?(headers) &&
66
74
  !attachment?(headers) &&
67
75
  !streaming?(env, headers)
76
+ rescue StandardError => e
77
+ NewRelic::Agent.logger.error('RUM instrumentation applicability check failed on exception:' \
78
+ "#{e.class} - #{e.message}")
79
+ false
68
80
  end
69
81
 
70
82
  private
@@ -100,15 +112,19 @@ module NewRelic
100
112
 
101
113
  def html?(headers)
102
114
  # needs else branch coverage
103
- headers[CONTENT_TYPE] && headers[CONTENT_TYPE].include?(TEXT_HTML) # rubocop:disable Style/SafeNavigation
115
+ headers[CONTENT_TYPE]&.match?(TEXT_HTML)
104
116
  end
105
117
 
106
118
  def attachment?(headers)
107
- headers[CONTENT_DISPOSITION]&.include?(ATTACHMENT)
119
+ headers[CONTENT_DISPOSITION]&.match?(ATTACHMENT)
108
120
  end
109
121
 
110
122
  def streaming?(env, headers)
111
- # Chunked transfer encoding is a streaming data transfer mechanism available only in HTTP/1.1
123
+ # Up until version 8.0, Rails would set 'Transfer-Encoding' to 'chunked'
124
+ # to trigger the desired HTTP/1.1 based streaming functionality in Rack.
125
+ # With version v8.0+, Rails assumes that the web server will be using
126
+ # Rack v3+ or an equally modern alternative and simply leaves the
127
+ # streaming behavior up to them.
112
128
  return true if headers && headers['Transfer-Encoding'] == 'chunked'
113
129
 
114
130
  defined?(ActionController::Live) &&
@@ -143,7 +159,7 @@ module NewRelic
143
159
  end
144
160
 
145
161
  # Per "The Response > The Body" section of Rack spec, we should close
146
- # if our response is able. http://rack.rubyforge.org/doc/SPEC.html
162
+ # if our response is able. https://github.com/rack/rack/blob/main/SPEC.rdoc
147
163
  def close_old_response(response)
148
164
  response.close if response.respond_to?(:close)
149
165
  end
@@ -13,6 +13,7 @@ module NewRelic
13
13
  :insert_distributed_trace_headers,
14
14
  :accept_distributed_trace_headers,
15
15
  :add_custom_attributes,
16
+ :add_custom_log_attributes,
16
17
  :add_custom_span_attributes,
17
18
  :add_instrumentation,
18
19
  :add_method_tracer,
@@ -42,9 +43,12 @@ module NewRelic
42
43
  :process_response_metadata,
43
44
  :record_custom_event,
44
45
  :record_metric,
46
+ :record_llm_feedback_event,
45
47
  :recording_web_transaction?,
46
48
  :require_test_helper,
47
49
  :set_error_group_callback,
50
+ :set_llm_token_count_callback,
51
+ :set_segment_callback,
48
52
  :set_sql_obfuscator,
49
53
  :set_transaction_name,
50
54
  :set_user_id,
@@ -78,7 +82,7 @@ module NewRelic
78
82
  "Expected #{klass} for `#{name}` but got #{arg.class}"
79
83
 
80
84
  NewRelic::Agent.logger.warn(message)
81
- nil
85
+ false
82
86
  end
83
87
  end
84
88
  end
@@ -0,0 +1,31 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic
6
+ module ThreadLocalStorage
7
+ def self.get(thread, key)
8
+ if Agent.config[:thread_local_tracer_state]
9
+ thread.thread_variable_get(key)
10
+ else
11
+ thread[key]
12
+ end
13
+ end
14
+
15
+ def self.set(thread, key, value)
16
+ if Agent.config[:thread_local_tracer_state]
17
+ thread.thread_variable_set(key, value)
18
+ else
19
+ thread[key] = value
20
+ end
21
+ end
22
+
23
+ def self.[](key)
24
+ get(::Thread.current, key)
25
+ end
26
+
27
+ def self.[]=(key, value)
28
+ set(::Thread.current, key, value)
29
+ end
30
+ end
31
+ end
@@ -22,15 +22,14 @@ module NewRelic
22
22
  # @api public
23
23
  def initialize(*args, &block)
24
24
  NewRelic::Agent.record_api_supportability_metric(:traced_thread)
25
- traced_block = create_traced_block(*args, &block)
25
+ traced_block = create_traced_block(&block)
26
26
  super(*args, &traced_block)
27
27
  end
28
28
 
29
- def create_traced_block(*args, &block)
29
+ def create_traced_block(&block)
30
30
  return block if NewRelic::Agent.config[:'instrumentation.thread.tracing'] # if this is on, don't double trace
31
31
 
32
32
  NewRelic::Agent::Tracer.thread_block_with_current_transaction(
33
- *args,
34
33
  segment_name: 'Ruby/TracedThread',
35
34
  &block
36
35
  )
@@ -6,7 +6,7 @@
6
6
  module NewRelic
7
7
  module VERSION # :nodoc:
8
8
  MAJOR = 9
9
- MINOR = 1
9
+ MINOR = 21
10
10
  TINY = 0
11
11
 
12
12
  STRING = "#{MAJOR}.#{MINOR}.#{TINY}"
@@ -27,7 +27,7 @@ module Sequel
27
27
  # If you don't want your models or database connections to be instrumented,
28
28
  # you can disable them by setting `disable_database_instrumentation` in
29
29
  # your `newrelic.yml` to `true`. It will also honor the
30
- # `disable_activerecord_instrumentation` setting.
30
+ # `disable_active_record_instrumentation` setting.
31
31
  #
32
32
  module NewRelicInstrumentation
33
33
  module Naming
@@ -78,8 +78,9 @@ module Sequel
78
78
  end
79
79
 
80
80
  THREAD_SAFE_CONNECTION_POOL_CLASSES = [
81
- (defined?(::Sequel::ThreadedConnectionPool) && ::Sequel::ThreadedConnectionPool)
82
- ].freeze
81
+ (defined?(::Sequel::ThreadedConnectionPool) && ::Sequel::ThreadedConnectionPool),
82
+ (defined?(::Sequel::TimedQueueConnectionPool) && NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '3.2') && ::Sequel::TimedQueueConnectionPool)
83
+ ].compact.freeze
83
84
 
84
85
  def explainer_for(sql)
85
86
  proc do |*|
@@ -0,0 +1,21 @@
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 'helpers/version_bump'
6
+
7
+ namespace :newrelic do
8
+ namespace :version do
9
+ desc 'Returns the current version'
10
+ task :current do
11
+ puts "#{NewRelic::VERSION::STRING}"
12
+ end
13
+
14
+ desc 'Update version file and changelog to next version'
15
+ task :bump, [:format] => [] do |t, args|
16
+ new_version = VersionBump.update_version
17
+ VersionBump.update_changelog(new_version)
18
+ puts "New version: #{new_version}"
19
+ end
20
+ end
21
+ end
@@ -19,14 +19,20 @@ namespace :newrelic do
19
19
  DISABLING => 'Use these settings to toggle instrumentation types during agent startup.',
20
20
  ATTRIBUTES => '[Attributes](/docs/features/agent-attributes) are key-value pairs containing information that determines the properties of an event or transaction. These key-value pairs can be viewed within transaction traces in APM, traced errors in APM, transaction events in dashboards, and page views in dashboards. You can customize exactly which attributes will be sent to each of these destinations',
21
21
  'transaction_tracer' => 'The [transaction traces](/docs/apm/traces/transaction-traces/transaction-traces) feature collects detailed information from a selection of transactions, including a summary of the calling sequence, a breakdown of time spent, and a list of SQL queries and their query plans (on mysql and postgresql). Available features depend on your New Relic subscription level.',
22
- 'error_collector' => "The agent collects and reports all uncaught exceptions by default. These configuration options allow you to customize the error collection.\n\nFor information on ignored and expected errors, [see this page on Error Analytics in APM](/docs/agents/manage-apm-agents/agent-data/manage-errors-apm-collect-ignore-or-mark-expected/). To set expected errors via the `NewRelic::Agent.notice_error` Ruby method, [consult the Ruby Agent API](/docs/agents/ruby-agent/api-guides/sending-handled-errors-new-relic/).",
23
- 'browser_monitoring' => "The browser monitoring [page load timing](/docs/browser/new-relic-browser/page-load-timing/page-load-timing-process) feature (sometimes referred to as real user monitoring or RUM) gives you insight into the performance real users are experiencing with your website. This is accomplished by measuring the time it takes for your users' browsers to download and render your web pages by injecting a small amount of JavaScript code into the header and footer of each page.",
24
- 'analytics_events' => '[New Relic dashboards](/docs/query-your-data/explore-query-data/dashboards/introduction-new-relic-one-dashboards) is a resource to gather and visualize data about your software and what it says about your business. With it you can quickly and easily create real-time dashboards to get immediate answers about end-user experiences, clickstreams, mobile activities, and server transactions.'
22
+ 'error_collector' => "The agent collects and reports all uncaught exceptions by default. These configuration options allow you to customize the error collection.\n\nFor information on ignored and expected errors, [see this page on Error Analytics in APM](/docs/agents/manage-apm-agents/agent-data/manage-errors-apm-collect-ignore-or-mark-expected/). To set expected errors via the `NewRelic::Agent.notice_error` Ruby method, [consult the Ruby agent API](/docs/agents/ruby-agent/api-guides/sending-handled-errors-new-relic/).",
23
+ 'browser_monitoring' => "The <InlinePopover type='browser' /> [page load timing](/docs/browser/new-relic-browser/page-load-timing/page-load-timing-process) feature (sometimes referred to as real user monitoring or RUM) gives you insight into the performance real users are experiencing with your website. This is accomplished by measuring the time it takes for your users' browsers to download and render your web pages by injecting a small amount of JavaScript code into the header and footer of each page.",
24
+ 'application_logging' => "The Ruby agent supports [APM logs in context](/docs/apm/new-relic-apm/getting-started/get-started-logs-context). For some tips on configuring logs for the Ruby agent, see [Configure Ruby logs in context](/docs/logs/logs-context/configure-logs-context-ruby).\n\nAvailable logging-related config options include:",
25
+ 'analytics_events' => '[New Relic dashboards](/docs/query-your-data/explore-query-data/dashboards/introduction-new-relic-one-dashboards) is a resource to gather and visualize data about your software and what it says about your business. With it you can quickly and easily create real-time dashboards to get immediate answers about end-user experiences, clickstreams, mobile activities, and server transactions.',
26
+ 'ai_monitoring' => "This section includes Ruby agent configurations for setting up AI monitoring.\n\n<Callout variant='important'>You need to enable distributed tracing to capture trace and feedback data. It is turned on by default in Ruby agents 8.0.0 and higher.</Callout>",
27
+ 'security_agent' => "[New Relic Interactive Application Security Testing](https://docs.newrelic.com/docs/iast/introduction/) (IAST) tests your applications for any exploitable vulnerability by replaying the generated HTTP request with vulnerable payloads.\n\n<Callout variant='important'>Run IAST with non-production deployments only to avoid exposing vulnerabilities on your production software. \
28
+ IAST mode requires Ruby agent version 9.12.0 or higher and the [newrelic_security](https://rubygems.org/gems/newrelic_security) gem. Security agent configurations are disabled by default.</Callout>"
25
29
  }
26
30
 
27
31
  NAME_OVERRIDES = {
28
- 'slow_sql' => 'Slow SQL',
29
- 'custom_insights_events' => 'Custom Events'
32
+ 'slow_sql' => 'Slow SQL [#slow-sql]',
33
+ 'custom_insights_events' => 'Custom Events [#custom-events]',
34
+ 'ai_monitoring' => 'AI Monitoring [#ai-monitoring]',
35
+ 'security_agent' => 'Security Agent [#security-agent]'
30
36
  }
31
37
 
32
38
  desc 'Describe available New Relic configuration settings'
@@ -1,6 +1,6 @@
1
- # frozen_string_literal: true
2
1
  # This file is distributed under New Relic's license terms.
3
2
  # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
4
 
5
5
  if ENV['CI']
6
6
  namespace :coverage do
@@ -0,0 +1,31 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require 'yaml'
6
+ require_relative 'helpers/version_bump'
7
+
8
+ # gha = GitHub Actions
9
+ namespace :gha do
10
+ # See .github/versions.yml
11
+ desc 'Update 3rd party action versions across all workflows'
12
+ task :update_versions do
13
+ gh_dir = File.expand_path('../../../.github', __FILE__)
14
+ info = YAML.load_file(File.join(gh_dir, 'versions.yml'))
15
+ workflows = Dir.glob(File.join(gh_dir, 'workflows', '*.yml'))
16
+ workflows.each do |workflow|
17
+ original = File.read(workflow)
18
+ modified = original.dup
19
+ info.each do |action, settings|
20
+ modified.gsub!(/uses: #{action}.*$/, "uses: #{action}@#{settings[:sha]} # tag #{settings[:tag]}")
21
+ end
22
+
23
+ if original != modified
24
+ File.open(workflow, 'w') { |f| f.puts modified }
25
+ puts "Updated #{workflow} with changes"
26
+ else
27
+ puts "#{workflow} remains unchanged"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,3 +1,97 @@
1
+ ---
2
+ title: Ruby agent configuration
3
+ tags:
4
+ - Agents
5
+ - Ruby agent
6
+ - Configuration
7
+ metaDescription: 'APM for Ruby: how to configure the Ruby agent, including editing the config file and setting environment variables.'
8
+ redirects:
9
+ - /docs/agents/ruby-agent/configuration/ruby-agent-configuration
10
+ - /docs/ruby/ruby-agent-configuration
11
+ - /docs/agents/ruby-agent/installation-and-configuration/ruby-agent-configuration
12
+ - /docs/agents/ruby-agent/installation-configuration/ruby-agent-configuration
13
+ freshnessValidatedDate: never
14
+ ---
15
+
16
+ <CONTRIBUTOR_NOTE>
17
+ This file is automatically generated from values defined in `lib/new_relic/agent/configuration/default_source.rb`.
18
+ Make all changes directly to `default_source.rb.`
19
+ Submit PRs or raise issues at: https://github.com/newrelic/newrelic-ruby-agent
20
+ </CONTRIBUTOR_NOTE>
21
+
22
+ You can configure the New Relic Ruby agent with settings in a configuration file, environment variables, or programmatically with server-side configuration. This document summarizes the configuration options available for the Ruby agent.
23
+
24
+ If the default value for a configuration option is `(Dynamic)`, this means the Ruby agent calculates the default at runtime. The value for the config setting defaults to the value of another setting as appropriate.
25
+
26
+ ## Configuration methods and precedence [#Options]
27
+
28
+ The primary (default) method to configure the Ruby agent is via the configuration file (`newrelic.yml`) in the `config` subdirectory. To set configuration values using environment variables:
29
+
30
+ 1. Add the prefix `NEW_RELIC_` to the setting's name.
31
+ 2. Replace any periods `.` with underscores `_`.
32
+
33
+ You can also configure a few values in the UI via [server-side configuration](/docs/agents/manage-apm-agents/configuration/server-side-agent-configuration).
34
+
35
+ The Ruby agent follows this order of precedence for configuration:
36
+
37
+ 1. Environment variables
38
+ 2. Server-side configuration
39
+ 3. Configuration file (`newrelic.yml`)
40
+ 4. Default configuration settings
41
+
42
+ In other words, environment variables override all other configuration settings and info, server-side configuration overrides the configuration file and default config settings, and so on.
43
+
44
+ ## View and edit config file options [#Edit]
45
+
46
+ The Ruby agent's `newrelic.yml` is a standard YAML configuration file. It typically includes a `Defaults` section at the top, plus sections below for each application environment (`Development`, `Test`, `Staging`, and `Production`).
47
+
48
+ The Ruby agent determines which section of the `newrelic.yml` config file to read from by looking at certain environment variables to derive the application's environment. This can be useful when you want to use `info` for the `log_level` config setting in your production environment, and you want more verbose `log_level` config settings (such as `debug`) in your development environment.
49
+
50
+ Here is an example `newrelic.yml` config file:
51
+
52
+ ```yaml
53
+ common: &default_settings
54
+ license_key: 'YOUR_LICENSE_KEY'
55
+ app_name: 'My Application Name'
56
+ production:
57
+ <<: *default_settings
58
+ log_level: info
59
+ development:
60
+ <<: *default_settings
61
+ log_level: debug
62
+ ```
63
+
64
+ The Ruby agent looks for the following environment variables, in this order, to find the application environment:
65
+
66
+ 1. `NEW_RELIC_ENV`
67
+ 2. `RUBY_ENV`
68
+ 3. `RAILS_ENV`
69
+ 4. `APP_ENV`
70
+ 5. `RACK_ENV`
71
+
72
+ If the Ruby agent doesn't detect values for any of those environment variables, it will default the application environment to `development` and read from the `development` section of the `newrelic.yml` config file.
73
+
74
+ When running the Ruby agent in a Rails app, the agent first looks for the `NEW_RELIC_ENV` environment variable to find the application environment and which section of the `newrelic.yml` to use. If `NEW_RELIC_ENV` is not present, the agent uses the Rails environment (`RAILS_ENV`).
75
+
76
+ When you edit the config file, be sure to:
77
+
78
+ * Indent only with two spaces.
79
+ * Indent only where relevant, in sections such as **`error_collector`**.
80
+
81
+ If you do not indent correctly, the agent may throw an `Unable to parse configuration file` error on startup.
82
+
83
+ To view the most current list of available Ruby agent configuration options, use the `rake newrelic:config:docs` command. This document describes the most common options.
84
+
85
+ ## Update the config file [#Updates]
86
+
87
+ This documentation applies to the Ruby agent's latest release. For details on earlier versions, refer to the comments in `newrelic.yml` itself.
88
+
89
+ To update `newrelic.yml` file after a new release, use the template in the base directory of the agent gem. When you update to new gem versions, examine or diff `config/newrelic.yml` and `newrelic.yml` in the [installation directory](/docs/agents/manage-apm-agents/troubleshooting/find-agent-root-directory#ruby-agent) to take advantage of new configuration options.
90
+
91
+ <Callout variant="important">
92
+ Updating the gem does not automatically update `config/newrelic.yml`.
93
+ </Callout>
94
+
1
95
  <% sections.each do |(section_key, section_name, section_description, configs)| %>
2
96
  ## <%=section_name%>
3
97
 
@@ -3,16 +3,19 @@
3
3
  # frozen_string_literal: true
4
4
 
5
5
  module Format
6
- def output(format)
7
- config_hash = build_config_hash
8
- sections = flatten_config_hash(config_hash)
6
+ DEFAULT_CONFIG_PATH = 'ruby-agent-configuration.mdx'
9
7
 
10
- puts build_erb(format).result(binding).split("\n").map(&:rstrip).join("\n").gsub('. ', '. ')
11
- sections # silences unused warning to return this
8
+ def output(format)
9
+ result = build_erb(format).result(binding).split("\n").map(&:rstrip).join("\n").gsub('. ', '. ')
10
+ File.write(DEFAULT_CONFIG_PATH, result)
12
11
  end
13
12
 
14
13
  private
15
14
 
15
+ def sections
16
+ @sections ||= flatten_config_hash(build_config_hash)
17
+ end
18
+
16
19
  def add_data_to_sections(sections)
17
20
  sections.each do |section|
18
21
  section_key = section[0]
@@ -66,7 +69,7 @@ module Format
66
69
 
67
70
  def format_description(value)
68
71
  description = ''
69
- description += '<b>DEPRECATED</b> ' if value[:deprecated]
72
+ description += '<DNT>**DEPRECATED**</DNT> ' if value[:deprecated]
70
73
  description += value[:description]
71
74
  description
72
75
  end
@@ -81,9 +84,10 @@ module Format
81
84
  name = NAME_OVERRIDES[key]
82
85
  return name if name
83
86
 
84
- key.split('_')
87
+ title = key.split('_')
85
88
  .each { |fragment| fragment[0] = fragment[0].upcase }
86
89
  .join(' ')
90
+ "#{title} [##{key.tr('_', '-')}]"
87
91
  end
88
92
 
89
93
  def format_sections(key, value)
@@ -0,0 +1,211 @@
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/agent/configuration/default_source'
6
+
7
+ module NewRelicYML
8
+ CRITICAL = [:'agent_enabled', :'app_name', :'license_key', :'log_level']
9
+ DEFAULTS = NewRelic::Agent::Configuration::DEFAULTS
10
+ # Skip because not configurable via yml
11
+ SKIP = [:'defer_rails_initialization']
12
+ # Don't evaluate Procs, instead use set values
13
+ PROCS = {:'config_path' => 'newrelic.yml',
14
+ :'process_host.display_name' => 'default hostname',
15
+ :'transaction_tracer.transaction_threshold' => 1.0}
16
+
17
+ HEADER = <<~HEADER
18
+ #
19
+ # This file configures the New Relic agent. New Relic monitors Ruby, Java,
20
+ # .NET, PHP, Python, Node, and Go applications with deep visibility and low
21
+ # overhead. For more information, visit www.newrelic.com.
22
+
23
+ # Generated <%= Time.now.strftime('%B %d, %Y') %><%= ", for version \#{@agent_version}" if @agent_version %>
24
+ #<%= "\\n# \#{generated_for_user}\\n#" if generated_for_user %>
25
+ # For full documentation of agent configuration options, please refer to
26
+ # https://docs.newrelic.com/docs/agents/ruby-agent/installation-configuration/ruby-agent-configuration
27
+
28
+ common: &default_settings
29
+ # Required license key associated with your New Relic account.
30
+ license_key: <%= license_key %>
31
+
32
+ # Your application name. Renaming here affects where data displays in New
33
+ # Relic. For more details, see https://docs.newrelic.com/docs/apm/new-relic-apm/maintenance/renaming-applications
34
+ app_name: <%= app_name %>
35
+
36
+ # To disable the agent regardless of other settings, uncomment the following:
37
+ # agent_enabled: false
38
+
39
+ # Logging level for log/newrelic_agent.log; options are error, warn, info, or
40
+ # debug.
41
+ log_level: info
42
+
43
+ # All of the following configuration options are optional. Review them, and
44
+ # uncomment or edit them if they appear relevant to your application needs.
45
+
46
+ HEADER
47
+
48
+ SECURITY_BEGIN = <<-SECURITY
49
+ # BEGIN security agent
50
+ #
51
+ # NOTE: At this time, the security agent is intended for use only within
52
+ # a dedicated security testing environment with data that can tolerate
53
+ # modification or deletion. The security agent is available as a
54
+ # separate Ruby gem, newrelic_security. It is recommended that this
55
+ # separate gem only be introduced to a security testing environment
56
+ # by leveraging Bundler grouping like so:
57
+ #
58
+ # # Gemfile
59
+ # gem 'newrelic_rpm' # New Relic APM observability agent
60
+ # gem 'newrelic-infinite_tracing' # New Relic Infinite Tracing
61
+ #
62
+ # group :security do
63
+ # gem 'newrelic_security', require: false # New Relic security agent
64
+ # end
65
+ #
66
+ # NOTE: All "security.*" configuration parameters are related only to the
67
+ # security agent, and all other configuration parameters that may
68
+ # have "security" in the name somewhere are related to the APM agent.
69
+
70
+ SECURITY
71
+
72
+ SECURITY_END = <<-SECURITY
73
+ # END security agent
74
+ SECURITY
75
+
76
+ FOOTER = <<~FOOTER
77
+ # Environment-specific settings are in this section.
78
+ # RAILS_ENV or RACK_ENV (as appropriate) is used to determine the environment.
79
+ # If your application has other named environments, configure them here.
80
+ development:
81
+ <<: *default_settings
82
+ app_name: <%= app_name %> (Development)
83
+
84
+ test:
85
+ <<: *default_settings
86
+ # It doesn't make sense to report to New Relic from automated test runs.
87
+ monitor_mode: false
88
+
89
+ staging:
90
+ <<: *default_settings
91
+ app_name: <%= app_name %> (Staging)
92
+
93
+ production:
94
+ <<: *default_settings
95
+ FOOTER
96
+
97
+ def self.get_configs(defaults)
98
+ agent_configs = {}
99
+ security_configs = {}
100
+
101
+ defaults.sort.each do |key, value|
102
+ next if CRITICAL.include?(key) || SKIP.include?(key)
103
+
104
+ next unless public_config?(value) && !deprecated?(value)
105
+
106
+ # TODO: OLD RUBIES < 2.6
107
+ # Remove `to_s`. `start_with?` doesn't accept symbols in Ruby <2.6
108
+ if key.to_s.start_with?('security.')
109
+ description, default = build_config(key, value)
110
+ security_configs[key] = {description: description, default: default}
111
+ next
112
+ end
113
+
114
+ description, default = build_config(key, value)
115
+ agent_configs[key] = {description: description, default: default}
116
+ end
117
+
118
+ [agent_configs, security_configs]
119
+ end
120
+
121
+ def self.build_config(key, value)
122
+ sanitized_description = sanitize_description(value[:description])
123
+ description = format_description(sanitized_description)
124
+ default = default_value(key, value)
125
+
126
+ [description, default]
127
+ end
128
+
129
+ def self.public_config?(value)
130
+ value[:public] == true
131
+ end
132
+
133
+ def self.deprecated?(value)
134
+ value[:deprecated] == true
135
+ end
136
+
137
+ def self.sanitize_description(description)
138
+ # remove callouts
139
+ description = description.split("\n").reject { |line| line.match?('</?Callout') }.join("\n")
140
+ # remove InlinePopover, keep the text inside type
141
+ description.gsub!(/<InlinePopover type="(.*)" \/>/, '\1')
142
+ # remove hyperlinks
143
+ description.gsub!(/\[([^\]]+)\]\([^\)]+\)/, '\1')
144
+ # delete lines with code fences including the language
145
+ description.gsub!(/```[a-zA-Z0-9_]*\n(.*?)```/m, '\1')
146
+ # remove single pairs of backticks
147
+ description.gsub!(/`([^`]+)`/, '\1')
148
+ # removed href links
149
+ description.gsub!(/<a href="(.*)">(.*)<\/a>/, '\2')
150
+
151
+ description
152
+ end
153
+
154
+ def self.format_description(description)
155
+ # remove all tab characters
156
+ description.delete!("\t")
157
+ # remove leading and trailing whitespace
158
+ description.strip!
159
+ # wrap text after 80 characters, assuming we're at one tabstop's (two
160
+ # spaces') level of indentation already, keep leading whitespace
161
+ description.gsub!(/(.{1,78})(\s|\Z)/, "\\1\n")
162
+ # add hashtags to lines
163
+ description = description.split("\n").map { |line| " # #{line}" }.join("\n")
164
+
165
+ description
166
+ end
167
+
168
+ def self.default_value(key, config_hash)
169
+ if PROCS.include?(key)
170
+ PROCS[key]
171
+ else
172
+ default = config_hash[:documentation_default].nil? ? config_hash[:default] : config_hash[:documentation_default]
173
+ default = 'nil' if default.nil?
174
+ default = '""' if default == ''
175
+
176
+ default
177
+ end
178
+ end
179
+
180
+ def self.agent_configs_yml(agent_configs)
181
+ agent_yml = ''
182
+ agent_configs.each do |key, value|
183
+ agent_yml += "#{value[:description]}\n # #{key}: #{value[:default]}\n\n"
184
+ end
185
+
186
+ agent_yml
187
+ end
188
+
189
+ def self.security_configs_yml(security_configs)
190
+ security_yml = ''
191
+ security_configs.each do |key, value|
192
+ security_yml += "#{value[:description]}\n # #{key}: #{value[:default]}\n\n"
193
+ end
194
+
195
+ security_yml
196
+ end
197
+
198
+ def self.build_string(defaults)
199
+ agent_configs, security_configs = get_configs(defaults)
200
+ agent_string = agent_configs_yml(agent_configs)
201
+ security_string = security_configs_yml(security_configs)
202
+
203
+ agent_string + SECURITY_BEGIN + security_string + SECURITY_END + "\n"
204
+ end
205
+
206
+ # :nocov:
207
+ def self.write_file(defaults = DEFAULTS)
208
+ File.write('newrelic.yml', HEADER + build_string(defaults) + FOOTER)
209
+ end
210
+ # :nocov:
211
+ end