datadog 2.8.0 → 2.39.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 (1035) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1009 -1
  3. data/README.md +0 -1
  4. data/bin/ddprofrb +4 -4
  5. data/ext/LIBDATADOG_DEVELOPMENT.md +3 -0
  6. data/ext/datadog_profiling_native_extension/clock_id.h +11 -3
  7. data/ext/datadog_profiling_native_extension/clock_id_from_mach.c +66 -0
  8. data/ext/datadog_profiling_native_extension/clock_id_from_pthread.c +3 -2
  9. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +500 -188
  10. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +5 -5
  11. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
  12. data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.c +3 -2
  13. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +34 -20
  14. data/ext/datadog_profiling_native_extension/collectors_stack.c +319 -101
  15. data/ext/datadog_profiling_native_extension/collectors_stack.h +27 -5
  16. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +985 -504
  17. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +19 -5
  18. data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +239 -0
  19. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +66 -5
  20. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +50 -1
  21. data/ext/datadog_profiling_native_extension/encoded_profile.c +80 -0
  22. data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
  23. data/ext/datadog_profiling_native_extension/extconf.rb +53 -35
  24. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +6 -43
  25. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +15 -55
  26. data/ext/datadog_profiling_native_extension/heap_recorder.c +487 -497
  27. data/ext/datadog_profiling_native_extension/heap_recorder.h +17 -8
  28. data/ext/datadog_profiling_native_extension/http_transport.c +108 -144
  29. data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +18 -15
  30. data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +8 -10
  31. data/ext/datadog_profiling_native_extension/macos_sampler_thread.h +55 -0
  32. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +0 -13
  33. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +136 -60
  34. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +22 -5
  35. data/ext/datadog_profiling_native_extension/profiling.c +84 -27
  36. data/ext/datadog_profiling_native_extension/ruby_helpers.c +67 -62
  37. data/ext/datadog_profiling_native_extension/ruby_helpers.h +20 -16
  38. data/ext/datadog_profiling_native_extension/setup_signal_handler.c +34 -10
  39. data/ext/datadog_profiling_native_extension/setup_signal_handler.h +2 -1
  40. data/ext/datadog_profiling_native_extension/stack_recorder.c +326 -217
  41. data/ext/datadog_profiling_native_extension/stack_recorder.h +4 -2
  42. data/ext/datadog_profiling_native_extension/time_helpers.h +14 -8
  43. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +48 -0
  44. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +36 -0
  45. data/ext/libdatadog_api/crashtracker.c +27 -24
  46. data/ext/libdatadog_api/crashtracker.h +5 -0
  47. data/ext/libdatadog_api/crashtracker_report_exception.c +126 -0
  48. data/ext/libdatadog_api/datadog_ruby_common.c +66 -5
  49. data/ext/libdatadog_api/datadog_ruby_common.h +50 -1
  50. data/ext/libdatadog_api/ddsketch.c +102 -0
  51. data/ext/libdatadog_api/di.c +203 -0
  52. data/ext/libdatadog_api/extconf.rb +41 -45
  53. data/ext/libdatadog_api/feature_flags.c +580 -0
  54. data/ext/libdatadog_api/feature_flags.h +5 -0
  55. data/ext/libdatadog_api/helpers.h +27 -0
  56. data/ext/libdatadog_api/init.c +27 -0
  57. data/ext/libdatadog_api/library_config.c +173 -0
  58. data/ext/libdatadog_api/library_config.h +25 -0
  59. data/ext/libdatadog_api/process_discovery.c +118 -0
  60. data/ext/libdatadog_api/process_discovery.h +5 -0
  61. data/ext/libdatadog_extconf_helpers.rb +111 -18
  62. data/lib/datadog/ai_guard/api_client.rb +84 -0
  63. data/lib/datadog/ai_guard/autoload.rb +10 -0
  64. data/lib/datadog/ai_guard/component.rb +44 -0
  65. data/lib/datadog/ai_guard/configuration/ext.rb +17 -0
  66. data/lib/datadog/ai_guard/configuration.rb +115 -0
  67. data/lib/datadog/ai_guard/contrib/auto_instrument.rb +24 -0
  68. data/lib/datadog/ai_guard/contrib/integration.rb +37 -0
  69. data/lib/datadog/ai_guard/contrib/rack/integration.rb +42 -0
  70. data/lib/datadog/ai_guard/contrib/rack/patcher.rb +26 -0
  71. data/lib/datadog/ai_guard/contrib/rack/request_middleware.rb +97 -0
  72. data/lib/datadog/ai_guard/contrib/rails/integration.rb +41 -0
  73. data/lib/datadog/ai_guard/contrib/rails/patcher.rb +97 -0
  74. data/lib/datadog/ai_guard/contrib/ruby_llm/chat_instrumentation.rb +80 -0
  75. data/lib/datadog/ai_guard/contrib/ruby_llm/integration.rb +41 -0
  76. data/lib/datadog/ai_guard/contrib/ruby_llm/patcher.rb +30 -0
  77. data/lib/datadog/ai_guard/evaluation/content_builder.rb +31 -0
  78. data/lib/datadog/ai_guard/evaluation/content_part.rb +36 -0
  79. data/lib/datadog/ai_guard/evaluation/message.rb +25 -0
  80. data/lib/datadog/ai_guard/evaluation/no_op_result.rb +36 -0
  81. data/lib/datadog/ai_guard/evaluation/request.rb +86 -0
  82. data/lib/datadog/ai_guard/evaluation/result.rb +45 -0
  83. data/lib/datadog/ai_guard/evaluation/tool_call.rb +18 -0
  84. data/lib/datadog/ai_guard/evaluation.rb +108 -0
  85. data/lib/datadog/ai_guard/ext.rb +29 -0
  86. data/lib/datadog/ai_guard.rb +181 -0
  87. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  88. data/lib/datadog/appsec/actions_handler.rb +49 -0
  89. data/lib/datadog/appsec/anonymizer.rb +16 -0
  90. data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +26 -0
  91. data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +66 -0
  92. data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +36 -0
  93. data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +26 -0
  94. data/lib/datadog/appsec/api_security/endpoint_collection.rb +10 -0
  95. data/lib/datadog/appsec/api_security/route_extractor.rb +104 -0
  96. data/lib/datadog/appsec/api_security/sampler.rb +62 -0
  97. data/lib/datadog/appsec/api_security.rb +23 -0
  98. data/lib/datadog/appsec/assets/blocked.html +10 -1
  99. data/lib/datadog/appsec/assets/blocked.json +1 -1
  100. data/lib/datadog/appsec/assets/blocked.text +3 -1
  101. data/lib/datadog/appsec/assets/waf_rules/README.md +44 -5
  102. data/lib/datadog/appsec/assets/waf_rules/recommended.json +954 -229
  103. data/lib/datadog/appsec/assets/waf_rules/strict.json +109 -106
  104. data/lib/datadog/appsec/assets.rb +8 -8
  105. data/lib/datadog/appsec/autoload.rb +5 -5
  106. data/lib/datadog/appsec/component.rb +56 -68
  107. data/lib/datadog/appsec/compressed_json.rb +40 -0
  108. data/lib/datadog/appsec/configuration.rb +427 -1
  109. data/lib/datadog/appsec/context.rb +135 -0
  110. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +45 -24
  111. data/lib/datadog/appsec/contrib/active_record/integration.rb +6 -6
  112. data/lib/datadog/appsec/contrib/active_record/patcher.rb +67 -16
  113. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  114. data/lib/datadog/appsec/contrib/aws_lambda/gateway/watcher.rb +75 -0
  115. data/lib/datadog/appsec/contrib/aws_lambda/integration.rb +39 -0
  116. data/lib/datadog/appsec/contrib/aws_lambda/patcher.rb +30 -0
  117. data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +146 -0
  118. data/lib/datadog/appsec/contrib/devise/configuration.rb +52 -0
  119. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  120. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  121. data/lib/datadog/appsec/contrib/devise/integration.rb +5 -6
  122. data/lib/datadog/appsec/contrib/devise/patcher.rb +33 -25
  123. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +104 -0
  124. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +70 -0
  125. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +3 -3
  126. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +121 -0
  127. data/lib/datadog/appsec/contrib/excon/integration.rb +41 -0
  128. data/lib/datadog/appsec/contrib/excon/patcher.rb +30 -0
  129. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +181 -0
  130. data/lib/datadog/appsec/contrib/faraday/connection_patch.rb +22 -0
  131. data/lib/datadog/appsec/contrib/faraday/integration.rb +42 -0
  132. data/lib/datadog/appsec/contrib/faraday/patcher.rb +53 -0
  133. data/lib/datadog/appsec/contrib/faraday/rack_builder_patch.rb +22 -0
  134. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +166 -0
  135. data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +4 -10
  136. data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +76 -26
  137. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +22 -33
  138. data/lib/datadog/appsec/contrib/graphql/integration.rb +10 -9
  139. data/lib/datadog/appsec/contrib/graphql/patcher.rb +3 -6
  140. data/lib/datadog/appsec/contrib/rack/buffered_input.rb +83 -0
  141. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  142. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +56 -21
  143. data/lib/datadog/appsec/contrib/rack/gateway/response.rb +4 -4
  144. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +101 -100
  145. data/lib/datadog/appsec/contrib/rack/input_peeker.rb +79 -0
  146. data/lib/datadog/appsec/contrib/rack/integration.rb +7 -7
  147. data/lib/datadog/appsec/contrib/rack/patcher.rb +2 -5
  148. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +13 -14
  149. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +117 -115
  150. data/lib/datadog/appsec/contrib/rack/response_body.rb +36 -0
  151. data/lib/datadog/appsec/contrib/rails/gateway/request.rb +43 -4
  152. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +58 -33
  153. data/lib/datadog/appsec/contrib/rails/integration.rb +6 -6
  154. data/lib/datadog/appsec/contrib/rails/patcher.rb +82 -69
  155. data/lib/datadog/appsec/contrib/rails/patches/process_action_patch.rb +29 -0
  156. data/lib/datadog/appsec/contrib/rails/patches/render_to_body_patch.rb +33 -0
  157. data/lib/datadog/appsec/contrib/rails/request.rb +3 -3
  158. data/lib/datadog/appsec/contrib/rest_client/integration.rb +45 -0
  159. data/lib/datadog/appsec/contrib/rest_client/patcher.rb +30 -0
  160. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +193 -0
  161. data/lib/datadog/appsec/contrib/sinatra/gateway/request.rb +1 -1
  162. data/lib/datadog/appsec/contrib/sinatra/gateway/route_params.rb +1 -1
  163. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +83 -67
  164. data/lib/datadog/appsec/contrib/sinatra/integration.rb +6 -6
  165. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +25 -61
  166. data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +31 -0
  167. data/lib/datadog/appsec/counter_sampler.rb +25 -0
  168. data/lib/datadog/appsec/default_header_tags.rb +52 -0
  169. data/lib/datadog/appsec/event.rb +80 -152
  170. data/lib/datadog/appsec/ext.rb +16 -4
  171. data/lib/datadog/appsec/extensions.rb +2 -2
  172. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +23 -2
  173. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +23 -0
  174. data/lib/datadog/appsec/instrumentation/gateway.rb +6 -24
  175. data/lib/datadog/appsec/metrics/collector.rb +80 -0
  176. data/lib/datadog/appsec/metrics/exporter.rb +48 -0
  177. data/lib/datadog/appsec/metrics/telemetry.rb +40 -0
  178. data/lib/datadog/appsec/metrics/telemetry_exporter.rb +47 -0
  179. data/lib/datadog/appsec/metrics.rb +14 -0
  180. data/lib/datadog/appsec/monitor/gateway/watcher.rb +60 -34
  181. data/lib/datadog/appsec/monitor.rb +1 -1
  182. data/lib/datadog/appsec/processor/rule_loader.rb +48 -54
  183. data/lib/datadog/appsec/rate_limiter.rb +1 -1
  184. data/lib/datadog/appsec/remote.rb +59 -68
  185. data/lib/datadog/appsec/response.rb +42 -90
  186. data/lib/datadog/appsec/route_normalizer/rails_route_pattern.rb +176 -0
  187. data/lib/datadog/appsec/route_normalizer/route_pattern.rb +378 -0
  188. data/lib/datadog/appsec/route_normalizer/route_text.rb +57 -0
  189. data/lib/datadog/appsec/route_normalizer.rb +80 -0
  190. data/lib/datadog/appsec/security_engine/engine.rb +197 -0
  191. data/lib/datadog/appsec/security_engine/result.rb +103 -0
  192. data/lib/datadog/appsec/security_engine/runner.rb +111 -0
  193. data/lib/datadog/appsec/security_engine.rb +9 -0
  194. data/lib/datadog/appsec/security_event.rb +37 -0
  195. data/lib/datadog/appsec/thread_safe_ref.rb +61 -0
  196. data/lib/datadog/appsec/trace_keeper.rb +36 -0
  197. data/lib/datadog/appsec/utils/hash_coercion.rb +23 -0
  198. data/lib/datadog/appsec/utils/http/body.rb +41 -0
  199. data/lib/datadog/appsec/utils/http/body_reader.rb +61 -0
  200. data/lib/datadog/appsec/utils/http/media_range.rb +17 -16
  201. data/lib/datadog/appsec/utils/http/media_type.rb +33 -27
  202. data/lib/datadog/appsec/utils/http/url_encoded.rb +107 -0
  203. data/lib/datadog/appsec/utils.rb +0 -2
  204. data/lib/datadog/appsec.rb +35 -30
  205. data/lib/datadog/auto_instrument.rb +5 -2
  206. data/lib/datadog/auto_instrument_base.rb +2 -1
  207. data/lib/datadog/core/buffer/cruby.rb +1 -1
  208. data/lib/datadog/core/buffer/random.rb +18 -2
  209. data/lib/datadog/core/buffer/thread_safe.rb +1 -1
  210. data/lib/datadog/core/configuration/agent_settings.rb +52 -0
  211. data/lib/datadog/core/configuration/agent_settings_resolver.rb +22 -36
  212. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  213. data/lib/datadog/core/configuration/base.rb +19 -7
  214. data/lib/datadog/core/configuration/components.rb +261 -57
  215. data/lib/datadog/core/configuration/components_state.rb +28 -0
  216. data/lib/datadog/core/configuration/config_helper.rb +109 -0
  217. data/lib/datadog/core/configuration/deprecations.rb +36 -0
  218. data/lib/datadog/core/configuration/ext.rb +15 -12
  219. data/lib/datadog/core/configuration/option.rb +150 -84
  220. data/lib/datadog/core/configuration/option_definition.rb +50 -29
  221. data/lib/datadog/core/configuration/options.rb +58 -19
  222. data/lib/datadog/core/configuration/settings.rb +287 -103
  223. data/lib/datadog/core/configuration/stable_config.rb +32 -0
  224. data/lib/datadog/core/configuration/supported_configurations.rb +415 -0
  225. data/lib/datadog/core/configuration.rb +47 -23
  226. data/lib/datadog/core/contrib/rails/railtie.rb +32 -0
  227. data/lib/datadog/core/contrib/rails/utils.rb +28 -0
  228. data/lib/datadog/core/crashtracking/component.rb +81 -38
  229. data/lib/datadog/core/crashtracking/tag_builder.rb +11 -23
  230. data/lib/datadog/core/ddsketch.rb +19 -0
  231. data/lib/datadog/core/deprecations.rb +3 -3
  232. data/lib/datadog/core/diagnostics/environment_logger.rb +10 -8
  233. data/lib/datadog/core/diagnostics/health.rb +2 -2
  234. data/lib/datadog/core/encoding.rb +21 -5
  235. data/lib/datadog/core/environment/agent_info.rb +142 -0
  236. data/lib/datadog/core/environment/cgroup.rb +53 -28
  237. data/lib/datadog/core/environment/container.rb +143 -51
  238. data/lib/datadog/core/environment/execution.rb +3 -3
  239. data/lib/datadog/core/environment/ext.rb +32 -21
  240. data/lib/datadog/core/environment/git.rb +5 -4
  241. data/lib/datadog/core/environment/identity.rb +50 -14
  242. data/lib/datadog/core/environment/platform.rb +8 -8
  243. data/lib/datadog/core/environment/process.rb +122 -0
  244. data/lib/datadog/core/environment/socket.rb +15 -2
  245. data/lib/datadog/core/environment/variable_helpers.rb +4 -4
  246. data/lib/datadog/core/environment/yjit.rb +2 -1
  247. data/lib/datadog/core/error.rb +15 -13
  248. data/lib/datadog/core/evp.rb +11 -0
  249. data/lib/datadog/core/extensions.rb +1 -1
  250. data/lib/datadog/core/feature_flags.rb +61 -0
  251. data/lib/datadog/core/git/ext.rb +4 -4
  252. data/lib/datadog/core/knuth_sampler.rb +59 -0
  253. data/lib/datadog/core/logger.rb +5 -5
  254. data/lib/datadog/core/logging/ext.rb +1 -1
  255. data/lib/datadog/core/metrics/client.rb +49 -49
  256. data/lib/datadog/core/metrics/ext.rb +5 -5
  257. data/lib/datadog/core/metrics/logging.rb +8 -8
  258. data/lib/datadog/core/metrics/options.rb +3 -3
  259. data/lib/datadog/core/pin.rb +9 -9
  260. data/lib/datadog/core/process_discovery/tracer_memfd.rb +13 -0
  261. data/lib/datadog/core/process_discovery.rb +62 -0
  262. data/lib/datadog/core/rate_limiter.rb +16 -4
  263. data/lib/datadog/core/remote/client/capabilities.rb +72 -13
  264. data/lib/datadog/core/remote/client.rb +68 -51
  265. data/lib/datadog/core/remote/component.rb +90 -55
  266. data/lib/datadog/core/remote/configuration/content.rb +17 -4
  267. data/lib/datadog/core/remote/configuration/digest.rb +22 -15
  268. data/lib/datadog/core/remote/configuration/path.rb +9 -9
  269. data/lib/datadog/core/remote/configuration/repository.rb +17 -4
  270. data/lib/datadog/core/remote/configuration/target.rb +15 -8
  271. data/lib/datadog/core/remote/configuration.rb +4 -4
  272. data/lib/datadog/core/remote/ext.rb +3 -3
  273. data/lib/datadog/core/remote/negotiation.rb +10 -10
  274. data/lib/datadog/core/remote/tie/tracing.rb +7 -7
  275. data/lib/datadog/core/remote/transport/config.rb +11 -37
  276. data/lib/datadog/core/remote/transport/http/config.rb +39 -107
  277. data/lib/datadog/core/remote/transport/http/negotiation.rb +19 -92
  278. data/lib/datadog/core/remote/transport/http.rb +33 -111
  279. data/lib/datadog/core/remote/transport/negotiation.rb +9 -21
  280. data/lib/datadog/core/remote/worker.rb +33 -42
  281. data/lib/datadog/core/runtime/ext.rb +22 -23
  282. data/lib/datadog/core/runtime/metrics.rb +30 -14
  283. data/lib/datadog/core/semaphore.rb +1 -4
  284. data/lib/datadog/core/tag_builder.rb +52 -0
  285. data/lib/datadog/core/tag_normalizer.rb +84 -0
  286. data/lib/datadog/core/telemetry/component.rb +142 -65
  287. data/lib/datadog/core/telemetry/emitter.rb +26 -14
  288. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -0
  289. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  290. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  291. data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +30 -0
  292. data/lib/datadog/core/telemetry/event/app_extended_heartbeat.rb +32 -0
  293. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  294. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  295. data/lib/datadog/core/telemetry/event/app_started.rb +293 -0
  296. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  297. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  298. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  299. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  300. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  301. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +66 -0
  302. data/lib/datadog/core/telemetry/event.rb +21 -392
  303. data/lib/datadog/core/telemetry/ext.rb +11 -10
  304. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  305. data/lib/datadog/core/telemetry/logger.rb +6 -3
  306. data/lib/datadog/core/telemetry/logging.rb +27 -9
  307. data/lib/datadog/core/telemetry/metric.rb +35 -13
  308. data/lib/datadog/core/telemetry/metrics_collection.rb +2 -2
  309. data/lib/datadog/core/telemetry/metrics_manager.rb +10 -1
  310. data/lib/datadog/core/telemetry/request.rb +21 -9
  311. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +66 -0
  312. data/lib/datadog/core/telemetry/transport/http.rb +68 -0
  313. data/lib/datadog/core/telemetry/transport/telemetry.rb +42 -0
  314. data/lib/datadog/core/telemetry/worker.rb +214 -35
  315. data/lib/datadog/core/transport/ext.rb +14 -11
  316. data/lib/datadog/core/transport/http/adapters/net.rb +19 -4
  317. data/lib/datadog/core/transport/http/adapters/test.rb +3 -2
  318. data/lib/datadog/core/transport/http/adapters/unix_socket.rb +5 -5
  319. data/lib/datadog/core/transport/http/api/endpoint.rb +10 -5
  320. data/lib/datadog/{tracing → core}/transport/http/api/instance.rb +5 -5
  321. data/lib/datadog/core/transport/http/api/map.rb +1 -1
  322. data/lib/datadog/{tracing → core}/transport/http/builder.rb +62 -36
  323. data/lib/datadog/core/transport/http/client.rb +80 -0
  324. data/lib/datadog/core/transport/http/env.rb +8 -0
  325. data/lib/datadog/core/transport/http/response.rb +5 -1
  326. data/lib/datadog/core/transport/http.rb +80 -0
  327. data/lib/datadog/core/transport/parcel.rb +61 -9
  328. data/lib/datadog/core/transport/response.rb +19 -1
  329. data/lib/datadog/core/transport/transport.rb +90 -0
  330. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +9 -9
  331. data/lib/datadog/core/utils/base64_codec.rb +23 -0
  332. data/lib/datadog/core/utils/duration.rb +33 -33
  333. data/lib/datadog/core/utils/enumerable_compat.rb +29 -0
  334. data/lib/datadog/core/utils/fnv.rb +26 -0
  335. data/lib/datadog/core/utils/forking.rb +5 -3
  336. data/lib/datadog/core/utils/hash.rb +0 -23
  337. data/lib/datadog/core/utils/lru_cache.rb +45 -0
  338. data/lib/datadog/core/utils/network.rb +34 -13
  339. data/lib/datadog/core/utils/only_once.rb +1 -1
  340. data/lib/datadog/core/utils/only_once_successful.rb +25 -8
  341. data/lib/datadog/core/utils/safe_dup.rb +4 -3
  342. data/lib/datadog/core/utils/sequence.rb +2 -0
  343. data/lib/datadog/core/utils/spawn_monkey_patch.rb +68 -0
  344. data/lib/datadog/core/utils/time.rb +26 -2
  345. data/lib/datadog/core/utils/truncation.rb +21 -0
  346. data/lib/datadog/core/utils/url.rb +1 -1
  347. data/lib/datadog/core/utils.rb +14 -5
  348. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  349. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  350. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  351. data/lib/datadog/core/worker.rb +1 -1
  352. data/lib/datadog/core/workers/async.rb +40 -14
  353. data/lib/datadog/core/workers/interval_loop.rb +63 -4
  354. data/lib/datadog/core/workers/polling.rb +4 -2
  355. data/lib/datadog/core/workers/queue.rb +96 -1
  356. data/lib/datadog/core/workers/runtime_metrics.rb +14 -6
  357. data/lib/datadog/core.rb +20 -3
  358. data/lib/datadog/data_streams/configuration.rb +50 -0
  359. data/lib/datadog/data_streams/ext.rb +11 -0
  360. data/lib/datadog/data_streams/extensions.rb +16 -0
  361. data/lib/datadog/data_streams/pathway_context.rb +169 -0
  362. data/lib/datadog/data_streams/processor.rb +511 -0
  363. data/lib/datadog/data_streams/transport/http/stats.rb +58 -0
  364. data/lib/datadog/data_streams/transport/http.rb +36 -0
  365. data/lib/datadog/data_streams/transport/stats.rb +39 -0
  366. data/lib/datadog/data_streams.rb +100 -0
  367. data/lib/datadog/di/base.rb +123 -0
  368. data/lib/datadog/di/boot.rb +47 -0
  369. data/lib/datadog/di/capture_expression.rb +21 -0
  370. data/lib/datadog/di/capture_expression_evaluator.rb +71 -0
  371. data/lib/datadog/di/capture_limits.rb +41 -0
  372. data/lib/datadog/di/code_tracker.rb +224 -12
  373. data/lib/datadog/di/component.rb +157 -49
  374. data/lib/datadog/di/configuration.rb +241 -2
  375. data/lib/datadog/di/context.rb +82 -0
  376. data/lib/datadog/di/contrib/active_record.rb +34 -5
  377. data/lib/datadog/di/contrib/railtie.rb +15 -0
  378. data/lib/datadog/di/contrib.rb +28 -0
  379. data/lib/datadog/di/el/compiler.rb +168 -0
  380. data/lib/datadog/di/el/evaluator.rb +159 -0
  381. data/lib/datadog/di/el/expression.rb +42 -0
  382. data/lib/datadog/di/el.rb +5 -0
  383. data/lib/datadog/di/error.rb +49 -0
  384. data/lib/datadog/di/fatal_exceptions.rb +26 -0
  385. data/lib/datadog/di/instrumenter.rb +672 -122
  386. data/lib/datadog/di/logger.rb +30 -0
  387. data/lib/datadog/di/{init.rb → preload.rb} +2 -4
  388. data/lib/datadog/di/probe.rb +125 -20
  389. data/lib/datadog/di/probe_builder.rb +126 -5
  390. data/lib/datadog/di/probe_file_loader/railtie.rb +15 -0
  391. data/lib/datadog/di/probe_file_loader.rb +87 -0
  392. data/lib/datadog/di/probe_manager.rb +198 -100
  393. data/lib/datadog/di/probe_notification_builder.rb +349 -103
  394. data/lib/datadog/di/probe_notifier_worker.rb +161 -51
  395. data/lib/datadog/di/probe_repository.rb +198 -0
  396. data/lib/datadog/di/proc_responder.rb +36 -0
  397. data/lib/datadog/di/redactor.rb +24 -3
  398. data/lib/datadog/di/remote.rb +259 -73
  399. data/lib/datadog/di/serializer.rb +319 -30
  400. data/lib/datadog/di/transport/diagnostics.rb +32 -0
  401. data/lib/datadog/di/transport/http/diagnostics.rb +35 -0
  402. data/lib/datadog/di/transport/http/input.rb +45 -0
  403. data/lib/datadog/di/transport/http.rb +81 -0
  404. data/lib/datadog/di/transport/input.rb +144 -0
  405. data/lib/datadog/di/utils.rb +133 -9
  406. data/lib/datadog/di.rb +188 -121
  407. data/lib/datadog/error_tracking/collector.rb +88 -0
  408. data/lib/datadog/error_tracking/component.rb +167 -0
  409. data/lib/datadog/error_tracking/configuration.rb +64 -0
  410. data/lib/datadog/error_tracking/ext.rb +18 -0
  411. data/lib/datadog/error_tracking/extensions.rb +16 -0
  412. data/lib/datadog/error_tracking/filters.rb +77 -0
  413. data/lib/datadog/error_tracking.rb +18 -0
  414. data/lib/datadog/kit/appsec/events/v2.rb +253 -0
  415. data/lib/datadog/kit/appsec/events.rb +39 -26
  416. data/lib/datadog/kit/enable_core_dumps.rb +3 -3
  417. data/lib/datadog/kit/identity.rb +34 -24
  418. data/lib/datadog/kit/tracing/method_tracer.rb +135 -0
  419. data/lib/datadog/kit.rb +1 -1
  420. data/lib/datadog/open_feature/component.rb +109 -0
  421. data/lib/datadog/open_feature/configuration.rb +50 -0
  422. data/lib/datadog/open_feature/evaluation_engine.rb +70 -0
  423. data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
  424. data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
  425. data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
  426. data/lib/datadog/open_feature/exposures/event.rb +60 -0
  427. data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
  428. data/lib/datadog/open_feature/exposures/worker.rb +116 -0
  429. data/lib/datadog/open_feature/ext.rb +21 -0
  430. data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +286 -0
  431. data/lib/datadog/open_feature/flag_evaluation/writer.rb +433 -0
  432. data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +102 -0
  433. data/lib/datadog/open_feature/hooks/flag_eval_metrics_hook.rb +51 -0
  434. data/lib/datadog/open_feature/hooks/span_enrichment_hook/codec.rb +58 -0
  435. data/lib/datadog/open_feature/hooks/span_enrichment_hook/span_enrichment_state.rb +96 -0
  436. data/lib/datadog/open_feature/hooks/span_enrichment_hook/span_enrichment_state_store.rb +49 -0
  437. data/lib/datadog/open_feature/hooks/span_enrichment_hook.rb +184 -0
  438. data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +149 -0
  439. data/lib/datadog/open_feature/native_evaluator.rb +60 -0
  440. data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
  441. data/lib/datadog/open_feature/provider.rb +226 -0
  442. data/lib/datadog/open_feature/remote.rb +67 -0
  443. data/lib/datadog/open_feature/resolution_details.rb +37 -0
  444. data/lib/datadog/open_feature/transport.rb +121 -0
  445. data/lib/datadog/open_feature.rb +19 -0
  446. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  447. data/lib/datadog/opentelemetry/api/context.rb +25 -10
  448. data/lib/datadog/opentelemetry/configuration/settings.rb +226 -0
  449. data/lib/datadog/opentelemetry/ext.rb +9 -0
  450. data/lib/datadog/opentelemetry/logs.rb +98 -0
  451. data/lib/datadog/opentelemetry/metrics.rb +90 -0
  452. data/lib/datadog/opentelemetry/sdk/configurator.rb +69 -5
  453. data/lib/datadog/opentelemetry/sdk/id_generator.rb +16 -10
  454. data/lib/datadog/opentelemetry/sdk/logs_exporter.rb +30 -0
  455. data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +28 -0
  456. data/lib/datadog/opentelemetry/sdk/propagator.rb +20 -14
  457. data/lib/datadog/opentelemetry/sdk/span_processor.rb +24 -21
  458. data/lib/datadog/opentelemetry/sdk/trace/span.rb +43 -39
  459. data/lib/datadog/opentelemetry/sdk.rb +19 -0
  460. data/lib/datadog/opentelemetry/signal_configuration.rb +53 -0
  461. data/lib/datadog/opentelemetry/trace.rb +5 -5
  462. data/lib/datadog/opentelemetry.rb +11 -6
  463. data/lib/datadog/profiling/collectors/code_provenance.rb +84 -16
  464. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +57 -3
  465. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +13 -4
  466. data/lib/datadog/profiling/collectors/info.rb +62 -4
  467. data/lib/datadog/profiling/collectors/thread_context.rb +27 -7
  468. data/lib/datadog/profiling/component.rb +125 -88
  469. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  470. data/lib/datadog/profiling/exporter.rb +51 -17
  471. data/lib/datadog/profiling/ext/dir_monkey_patches.rb +24 -5
  472. data/lib/datadog/profiling/ext/exec_monkey_patch.rb +32 -0
  473. data/lib/datadog/profiling/ext.rb +2 -17
  474. data/lib/datadog/profiling/flush.rb +26 -17
  475. data/lib/datadog/profiling/http_transport.rb +30 -96
  476. data/lib/datadog/profiling/load_native_extension.rb +3 -35
  477. data/lib/datadog/profiling/profiler.rb +31 -12
  478. data/lib/datadog/profiling/scheduler.rb +19 -10
  479. data/lib/datadog/profiling/sequence_tracker.rb +44 -0
  480. data/lib/datadog/profiling/stack_recorder.rb +9 -17
  481. data/lib/datadog/profiling/tag_builder.rb +41 -41
  482. data/lib/datadog/profiling/tasks/exec.rb +10 -5
  483. data/lib/datadog/profiling/tasks/help.rb +1 -0
  484. data/lib/datadog/profiling/tasks/setup.rb +4 -2
  485. data/lib/datadog/profiling.rb +38 -37
  486. data/lib/datadog/ruby_version.rb +25 -0
  487. data/lib/datadog/single_step_instrument.rb +11 -2
  488. data/lib/datadog/symbol_database/component.rb +734 -0
  489. data/lib/datadog/symbol_database/configuration.rb +73 -0
  490. data/lib/datadog/symbol_database/extensions.rb +19 -0
  491. data/lib/datadog/symbol_database/extractor.rb +1110 -0
  492. data/lib/datadog/symbol_database/file_hash.rb +48 -0
  493. data/lib/datadog/symbol_database/logger.rb +43 -0
  494. data/lib/datadog/symbol_database/remote.rb +195 -0
  495. data/lib/datadog/symbol_database/scope.rb +102 -0
  496. data/lib/datadog/symbol_database/scope_batcher.rb +292 -0
  497. data/lib/datadog/symbol_database/service_version.rb +66 -0
  498. data/lib/datadog/symbol_database/symbol.rb +69 -0
  499. data/lib/datadog/symbol_database/transport/http/endpoint.rb +28 -0
  500. data/lib/datadog/symbol_database/transport/http.rb +45 -0
  501. data/lib/datadog/symbol_database/transport.rb +54 -0
  502. data/lib/datadog/symbol_database/uploader.rb +230 -0
  503. data/lib/datadog/symbol_database.rb +71 -0
  504. data/lib/datadog/tracing/analytics.rb +2 -2
  505. data/lib/datadog/tracing/buffer.rb +15 -15
  506. data/lib/datadog/tracing/client_ip.rb +4 -4
  507. data/lib/datadog/tracing/component.rb +39 -35
  508. data/lib/datadog/tracing/configuration/dynamic.rb +14 -16
  509. data/lib/datadog/tracing/configuration/ext.rb +60 -33
  510. data/lib/datadog/tracing/configuration/http.rb +2 -2
  511. data/lib/datadog/tracing/configuration/settings.rb +156 -26
  512. data/lib/datadog/tracing/context.rb +3 -3
  513. data/lib/datadog/tracing/context_provider.rb +3 -3
  514. data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +2 -2
  515. data/lib/datadog/tracing/contrib/action_cable/event.rb +5 -5
  516. data/lib/datadog/tracing/contrib/action_cable/events/broadcast.rb +9 -6
  517. data/lib/datadog/tracing/contrib/action_cable/events/perform_action.rb +8 -5
  518. data/lib/datadog/tracing/contrib/action_cable/events/transmit.rb +9 -6
  519. data/lib/datadog/tracing/contrib/action_cable/events.rb +4 -4
  520. data/lib/datadog/tracing/contrib/action_cable/ext.rb +18 -18
  521. data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +8 -5
  522. data/lib/datadog/tracing/contrib/action_cable/integration.rb +10 -7
  523. data/lib/datadog/tracing/contrib/action_cable/patcher.rb +4 -4
  524. data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +2 -2
  525. data/lib/datadog/tracing/contrib/action_mailer/event.rb +7 -4
  526. data/lib/datadog/tracing/contrib/action_mailer/events/deliver.rb +8 -8
  527. data/lib/datadog/tracing/contrib/action_mailer/events/process.rb +4 -4
  528. data/lib/datadog/tracing/contrib/action_mailer/events.rb +2 -2
  529. data/lib/datadog/tracing/contrib/action_mailer/ext.rb +18 -18
  530. data/lib/datadog/tracing/contrib/action_mailer/integration.rb +11 -7
  531. data/lib/datadog/tracing/contrib/action_mailer/patcher.rb +3 -3
  532. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +37 -19
  533. data/lib/datadog/tracing/contrib/action_pack/action_controller/patcher.rb +2 -2
  534. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +48 -13
  535. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +5 -3
  536. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +3 -3
  537. data/lib/datadog/tracing/contrib/action_pack/ext.rb +10 -8
  538. data/lib/datadog/tracing/contrib/action_pack/integration.rb +10 -7
  539. data/lib/datadog/tracing/contrib/action_pack/patcher.rb +3 -3
  540. data/lib/datadog/tracing/contrib/action_pack/utils.rb +2 -3
  541. data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +3 -3
  542. data/lib/datadog/tracing/contrib/action_view/event.rb +1 -1
  543. data/lib/datadog/tracing/contrib/action_view/events/render_partial.rb +10 -7
  544. data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +12 -9
  545. data/lib/datadog/tracing/contrib/action_view/events.rb +2 -2
  546. data/lib/datadog/tracing/contrib/action_view/ext.rb +10 -10
  547. data/lib/datadog/tracing/contrib/action_view/integration.rb +14 -11
  548. data/lib/datadog/tracing/contrib/action_view/patcher.rb +5 -5
  549. data/lib/datadog/tracing/contrib/action_view/utils.rb +2 -2
  550. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +2 -2
  551. data/lib/datadog/tracing/contrib/active_job/data_streams.rb +62 -0
  552. data/lib/datadog/tracing/contrib/active_job/event.rb +11 -11
  553. data/lib/datadog/tracing/contrib/active_job/events/discard.rb +11 -8
  554. data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +11 -8
  555. data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +11 -8
  556. data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +11 -8
  557. data/lib/datadog/tracing/contrib/active_job/events/perform.rb +11 -8
  558. data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +11 -8
  559. data/lib/datadog/tracing/contrib/active_job/events.rb +6 -6
  560. data/lib/datadog/tracing/contrib/active_job/ext.rb +23 -23
  561. data/lib/datadog/tracing/contrib/active_job/integration.rb +10 -7
  562. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +21 -7
  563. data/lib/datadog/tracing/contrib/active_job/patcher.rb +21 -5
  564. data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +2 -2
  565. data/lib/datadog/tracing/contrib/active_model_serializers/event.rb +4 -4
  566. data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +8 -8
  567. data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +9 -10
  568. data/lib/datadog/tracing/contrib/active_model_serializers/events.rb +2 -2
  569. data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +10 -10
  570. data/lib/datadog/tracing/contrib/active_model_serializers/integration.rb +5 -6
  571. data/lib/datadog/tracing/contrib/active_model_serializers/patcher.rb +3 -3
  572. data/lib/datadog/tracing/contrib/active_record/configuration/makara_resolver.rb +1 -1
  573. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +8 -8
  574. data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +4 -4
  575. data/lib/datadog/tracing/contrib/active_record/event.rb +1 -1
  576. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +10 -10
  577. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +16 -19
  578. data/lib/datadog/tracing/contrib/active_record/events.rb +2 -2
  579. data/lib/datadog/tracing/contrib/active_record/ext.rb +15 -15
  580. data/lib/datadog/tracing/contrib/active_record/integration.rb +16 -12
  581. data/lib/datadog/tracing/contrib/active_record/patcher.rb +2 -2
  582. data/lib/datadog/tracing/contrib/active_record/utils.rb +19 -19
  583. data/lib/datadog/tracing/contrib/active_support/cache/event.rb +1 -1
  584. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +28 -20
  585. data/lib/datadog/tracing/contrib/active_support/cache/events.rb +1 -1
  586. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +40 -8
  587. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +8 -4
  588. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +5 -7
  589. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +26 -3
  590. data/lib/datadog/tracing/contrib/active_support/ext.rb +16 -16
  591. data/lib/datadog/tracing/contrib/active_support/integration.rb +11 -8
  592. data/lib/datadog/tracing/contrib/active_support/notifications/event.rb +3 -2
  593. data/lib/datadog/tracing/contrib/active_support/notifications/subscriber.rb +2 -2
  594. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +9 -11
  595. data/lib/datadog/tracing/contrib/active_support/patcher.rb +2 -2
  596. data/lib/datadog/tracing/contrib/analytics.rb +1 -1
  597. data/lib/datadog/tracing/contrib/auto_instrument.rb +5 -5
  598. data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +3 -3
  599. data/lib/datadog/tracing/contrib/aws/ext.rb +26 -26
  600. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +21 -13
  601. data/lib/datadog/tracing/contrib/aws/integration.rb +11 -8
  602. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +9 -3
  603. data/lib/datadog/tracing/contrib/aws/patcher.rb +10 -6
  604. data/lib/datadog/tracing/contrib/aws/service/base.rb +2 -1
  605. data/lib/datadog/tracing/contrib/aws/service/dynamodb.rb +2 -2
  606. data/lib/datadog/tracing/contrib/aws/service/eventbridge.rb +2 -2
  607. data/lib/datadog/tracing/contrib/aws/service/kinesis.rb +4 -4
  608. data/lib/datadog/tracing/contrib/aws/service/s3.rb +2 -2
  609. data/lib/datadog/tracing/contrib/aws/service/sns.rb +3 -3
  610. data/lib/datadog/tracing/contrib/aws/service/sqs.rb +3 -3
  611. data/lib/datadog/tracing/contrib/aws/service/states.rb +5 -5
  612. data/lib/datadog/tracing/contrib/aws/services.rb +14 -14
  613. data/lib/datadog/tracing/contrib/component.rb +3 -3
  614. data/lib/datadog/tracing/contrib/concurrent_ruby/async_patch.rb +2 -2
  615. data/lib/datadog/tracing/contrib/concurrent_ruby/configuration/settings.rb +2 -2
  616. data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +2 -2
  617. data/lib/datadog/tracing/contrib/concurrent_ruby/ext.rb +2 -2
  618. data/lib/datadog/tracing/contrib/concurrent_ruby/future_patch.rb +2 -2
  619. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +8 -5
  620. data/lib/datadog/tracing/contrib/concurrent_ruby/patcher.rb +4 -4
  621. data/lib/datadog/tracing/contrib/concurrent_ruby/promises_future_patch.rb +2 -2
  622. data/lib/datadog/tracing/contrib/configurable.rb +24 -9
  623. data/lib/datadog/tracing/contrib/configuration/resolver.rb +14 -4
  624. data/lib/datadog/tracing/contrib/configuration/resolvers/pattern_resolver.rb +5 -5
  625. data/lib/datadog/tracing/contrib/configuration/settings.rb +3 -3
  626. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +2 -2
  627. data/lib/datadog/tracing/contrib/dalli/ext.rb +16 -15
  628. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +6 -10
  629. data/lib/datadog/tracing/contrib/dalli/integration.rb +10 -7
  630. data/lib/datadog/tracing/contrib/dalli/patcher.rb +3 -3
  631. data/lib/datadog/tracing/contrib/dalli/quantize.rb +3 -3
  632. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +2 -2
  633. data/lib/datadog/tracing/contrib/delayed_job/ext.rb +14 -14
  634. data/lib/datadog/tracing/contrib/delayed_job/integration.rb +5 -5
  635. data/lib/datadog/tracing/contrib/delayed_job/patcher.rb +3 -3
  636. data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +7 -5
  637. data/lib/datadog/tracing/contrib/delayed_job/server_internal_tracer/worker.rb +1 -0
  638. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +2 -2
  639. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +18 -17
  640. data/lib/datadog/tracing/contrib/elasticsearch/integration.rb +8 -8
  641. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +57 -63
  642. data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +8 -8
  643. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +7 -3
  644. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +19 -21
  645. data/lib/datadog/tracing/contrib/ethon/ext.rb +16 -14
  646. data/lib/datadog/tracing/contrib/ethon/integration.rb +6 -6
  647. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +4 -11
  648. data/lib/datadog/tracing/contrib/ethon/patcher.rb +3 -3
  649. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +21 -10
  650. data/lib/datadog/tracing/contrib/excon/ext.rb +14 -12
  651. data/lib/datadog/tracing/contrib/excon/integration.rb +6 -6
  652. data/lib/datadog/tracing/contrib/excon/middleware.rb +17 -19
  653. data/lib/datadog/tracing/contrib/excon/patcher.rb +2 -2
  654. data/lib/datadog/tracing/contrib/ext.rb +20 -17
  655. data/lib/datadog/tracing/contrib/extensions.rb +57 -14
  656. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +20 -13
  657. data/lib/datadog/tracing/contrib/faraday/ext.rb +14 -12
  658. data/lib/datadog/tracing/contrib/faraday/integration.rb +6 -6
  659. data/lib/datadog/tracing/contrib/faraday/middleware.rb +19 -19
  660. data/lib/datadog/tracing/contrib/faraday/patcher.rb +6 -6
  661. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +11 -7
  662. data/lib/datadog/tracing/contrib/grape/endpoint.rb +37 -34
  663. data/lib/datadog/tracing/contrib/grape/ext.rb +15 -15
  664. data/lib/datadog/tracing/contrib/grape/instrumentation.rb +15 -10
  665. data/lib/datadog/tracing/contrib/grape/integration.rb +5 -5
  666. data/lib/datadog/tracing/contrib/grape/patcher.rb +10 -5
  667. data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +21 -0
  668. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +20 -2
  669. data/lib/datadog/tracing/contrib/graphql/ext.rb +11 -5
  670. data/lib/datadog/tracing/contrib/graphql/integration.rb +9 -9
  671. data/lib/datadog/tracing/contrib/graphql/patcher.rb +8 -8
  672. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +174 -41
  673. data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +2 -2
  674. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +7 -4
  675. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +25 -23
  676. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +13 -17
  677. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor.rb +6 -6
  678. data/lib/datadog/tracing/contrib/grpc/distributed/fetcher.rb +2 -2
  679. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +12 -7
  680. data/lib/datadog/tracing/contrib/grpc/ext.rb +14 -13
  681. data/lib/datadog/tracing/contrib/grpc/formatting.rb +7 -7
  682. data/lib/datadog/tracing/contrib/grpc/integration.rb +5 -5
  683. data/lib/datadog/tracing/contrib/grpc/intercept_with_datadog.rb +1 -1
  684. data/lib/datadog/tracing/contrib/grpc/patcher.rb +3 -3
  685. data/lib/datadog/tracing/contrib/grpc.rb +7 -6
  686. data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +4 -3
  687. data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +2 -2
  688. data/lib/datadog/tracing/contrib/hanami/ext.rb +8 -8
  689. data/lib/datadog/tracing/contrib/hanami/integration.rb +6 -6
  690. data/lib/datadog/tracing/contrib/hanami/patcher.rb +5 -5
  691. data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +5 -4
  692. data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +12 -13
  693. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +1 -16
  694. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +20 -9
  695. data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +6 -6
  696. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +13 -8
  697. data/lib/datadog/tracing/contrib/http/ext.rb +14 -12
  698. data/lib/datadog/tracing/contrib/http/instrumentation.rb +20 -28
  699. data/lib/datadog/tracing/contrib/http/integration.rb +9 -8
  700. data/lib/datadog/tracing/contrib/http/patcher.rb +3 -3
  701. data/lib/datadog/tracing/contrib/http.rb +7 -6
  702. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +20 -9
  703. data/lib/datadog/tracing/contrib/httpclient/ext.rb +14 -12
  704. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +21 -31
  705. data/lib/datadog/tracing/contrib/httpclient/integration.rb +6 -6
  706. data/lib/datadog/tracing/contrib/httpclient/patcher.rb +3 -3
  707. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +20 -9
  708. data/lib/datadog/tracing/contrib/httprb/ext.rb +14 -12
  709. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +20 -32
  710. data/lib/datadog/tracing/contrib/httprb/integration.rb +9 -6
  711. data/lib/datadog/tracing/contrib/httprb/patcher.rb +3 -3
  712. data/lib/datadog/tracing/contrib/integration.rb +3 -3
  713. data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +2 -2
  714. data/lib/datadog/tracing/contrib/kafka/event.rb +5 -4
  715. data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +4 -4
  716. data/lib/datadog/tracing/contrib/kafka/events/consumer/process_batch.rb +5 -5
  717. data/lib/datadog/tracing/contrib/kafka/events/consumer/process_message.rb +5 -5
  718. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/heartbeat.rb +6 -6
  719. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/join_group.rb +6 -6
  720. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/leave_group.rb +6 -6
  721. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/sync_group.rb +6 -6
  722. data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +4 -4
  723. data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +4 -4
  724. data/lib/datadog/tracing/contrib/kafka/events.rb +9 -9
  725. data/lib/datadog/tracing/contrib/kafka/ext.rb +40 -40
  726. data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +66 -0
  727. data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +66 -0
  728. data/lib/datadog/tracing/contrib/kafka/integration.rb +8 -5
  729. data/lib/datadog/tracing/contrib/kafka/patcher.rb +17 -3
  730. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +31 -0
  731. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +50 -0
  732. data/lib/datadog/tracing/contrib/karafka/ext.rb +28 -0
  733. data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
  734. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  735. data/lib/datadog/tracing/contrib/karafka/monitor.rb +77 -0
  736. data/lib/datadog/tracing/contrib/karafka/patcher.rb +102 -0
  737. data/lib/datadog/tracing/contrib/karafka.rb +38 -0
  738. data/lib/datadog/tracing/contrib/lograge/configuration/settings.rb +2 -2
  739. data/lib/datadog/tracing/contrib/lograge/ext.rb +1 -1
  740. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +1 -1
  741. data/lib/datadog/tracing/contrib/lograge/integration.rb +5 -5
  742. data/lib/datadog/tracing/contrib/lograge/patcher.rb +13 -11
  743. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +11 -3
  744. data/lib/datadog/tracing/contrib/mongodb/ext.rb +19 -18
  745. data/lib/datadog/tracing/contrib/mongodb/instrumentation.rb +3 -3
  746. data/lib/datadog/tracing/contrib/mongodb/integration.rb +9 -6
  747. data/lib/datadog/tracing/contrib/mongodb/parsers.rb +10 -10
  748. data/lib/datadog/tracing/contrib/mongodb/patcher.rb +3 -3
  749. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +38 -24
  750. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +9 -3
  751. data/lib/datadog/tracing/contrib/mysql2/ext.rb +12 -12
  752. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +25 -18
  753. data/lib/datadog/tracing/contrib/mysql2/integration.rb +5 -5
  754. data/lib/datadog/tracing/contrib/mysql2/patcher.rb +2 -2
  755. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +19 -2
  756. data/lib/datadog/tracing/contrib/opensearch/ext.rb +31 -21
  757. data/lib/datadog/tracing/contrib/opensearch/integration.rb +8 -6
  758. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +75 -77
  759. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +9 -9
  760. data/lib/datadog/tracing/contrib/patcher.rb +14 -13
  761. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +9 -3
  762. data/lib/datadog/tracing/contrib/pg/ext.rb +19 -19
  763. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +21 -24
  764. data/lib/datadog/tracing/contrib/pg/integration.rb +5 -5
  765. data/lib/datadog/tracing/contrib/pg/patcher.rb +2 -2
  766. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +2 -2
  767. data/lib/datadog/tracing/contrib/presto/ext.rb +22 -22
  768. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +11 -13
  769. data/lib/datadog/tracing/contrib/presto/integration.rb +8 -5
  770. data/lib/datadog/tracing/contrib/presto/patcher.rb +4 -4
  771. data/lib/datadog/tracing/contrib/propagation/sql_comment/comment.rb +2 -2
  772. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +26 -13
  773. data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +7 -3
  774. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +29 -5
  775. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +7 -4
  776. data/lib/datadog/tracing/contrib/que/ext.rb +19 -18
  777. data/lib/datadog/tracing/contrib/que/integration.rb +6 -6
  778. data/lib/datadog/tracing/contrib/que/patcher.rb +1 -1
  779. data/lib/datadog/tracing/contrib/que/tracer.rb +2 -1
  780. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +3 -3
  781. data/lib/datadog/tracing/contrib/racecar/event.rb +6 -10
  782. data/lib/datadog/tracing/contrib/racecar/events/batch.rb +5 -5
  783. data/lib/datadog/tracing/contrib/racecar/events/consume.rb +4 -4
  784. data/lib/datadog/tracing/contrib/racecar/events/message.rb +5 -5
  785. data/lib/datadog/tracing/contrib/racecar/events.rb +3 -3
  786. data/lib/datadog/tracing/contrib/racecar/ext.rb +18 -18
  787. data/lib/datadog/tracing/contrib/racecar/integration.rb +5 -5
  788. data/lib/datadog/tracing/contrib/racecar/patcher.rb +3 -3
  789. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +13 -3
  790. data/lib/datadog/tracing/contrib/rack/ext.rb +43 -15
  791. data/lib/datadog/tracing/contrib/rack/header_collection.rb +13 -3
  792. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +55 -32
  793. data/lib/datadog/tracing/contrib/rack/integration.rb +7 -7
  794. data/lib/datadog/tracing/contrib/rack/middlewares.rb +102 -63
  795. data/lib/datadog/tracing/contrib/rack/patcher.rb +5 -5
  796. data/lib/datadog/tracing/contrib/rack/request_queue.rb +8 -7
  797. data/lib/datadog/tracing/contrib/rack/route_inference.rb +67 -0
  798. data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +130 -6
  799. data/lib/datadog/tracing/contrib/rails/auto_instrument_railtie.rb +1 -1
  800. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +9 -6
  801. data/lib/datadog/tracing/contrib/rails/ext.rb +16 -14
  802. data/lib/datadog/tracing/contrib/rails/framework.rb +12 -12
  803. data/lib/datadog/tracing/contrib/rails/integration.rb +6 -6
  804. data/lib/datadog/tracing/contrib/rails/log_injection.rb +2 -2
  805. data/lib/datadog/tracing/contrib/rails/middlewares.rb +4 -4
  806. data/lib/datadog/tracing/contrib/rails/patcher.rb +11 -9
  807. data/lib/datadog/tracing/contrib/rails/railtie.rb +4 -4
  808. data/lib/datadog/tracing/contrib/rails/runner.rb +64 -40
  809. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +3 -3
  810. data/lib/datadog/tracing/contrib/rake/ext.rb +12 -12
  811. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +13 -11
  812. data/lib/datadog/tracing/contrib/rake/integration.rb +5 -5
  813. data/lib/datadog/tracing/contrib/rake/patcher.rb +3 -3
  814. data/lib/datadog/tracing/contrib/redis/configuration/resolver.rb +4 -4
  815. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +2 -2
  816. data/lib/datadog/tracing/contrib/redis/ext.rb +19 -18
  817. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +6 -6
  818. data/lib/datadog/tracing/contrib/redis/integration.rb +7 -7
  819. data/lib/datadog/tracing/contrib/redis/patcher.rb +12 -12
  820. data/lib/datadog/tracing/contrib/redis/quantize.rb +6 -6
  821. data/lib/datadog/tracing/contrib/redis/tags.rb +7 -12
  822. data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +11 -9
  823. data/lib/datadog/tracing/contrib/registerable.rb +11 -0
  824. data/lib/datadog/tracing/contrib/registry.rb +1 -1
  825. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +2 -2
  826. data/lib/datadog/tracing/contrib/resque/ext.rb +7 -7
  827. data/lib/datadog/tracing/contrib/resque/integration.rb +5 -5
  828. data/lib/datadog/tracing/contrib/resque/patcher.rb +3 -3
  829. data/lib/datadog/tracing/contrib/resque/resque_job.rb +7 -6
  830. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +7 -4
  831. data/lib/datadog/tracing/contrib/rest_client/ext.rb +13 -11
  832. data/lib/datadog/tracing/contrib/rest_client/integration.rb +8 -5
  833. data/lib/datadog/tracing/contrib/rest_client/patcher.rb +2 -2
  834. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +18 -17
  835. data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +2 -2
  836. data/lib/datadog/tracing/contrib/roda/ext.rb +6 -5
  837. data/lib/datadog/tracing/contrib/roda/instrumentation.rb +12 -7
  838. data/lib/datadog/tracing/contrib/roda/integration.rb +6 -6
  839. data/lib/datadog/tracing/contrib/roda/patcher.rb +3 -3
  840. data/lib/datadog/tracing/contrib/semantic_logger/configuration/settings.rb +2 -2
  841. data/lib/datadog/tracing/contrib/semantic_logger/ext.rb +1 -1
  842. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +1 -1
  843. data/lib/datadog/tracing/contrib/semantic_logger/integration.rb +5 -5
  844. data/lib/datadog/tracing/contrib/semantic_logger/patcher.rb +2 -2
  845. data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +2 -2
  846. data/lib/datadog/tracing/contrib/sequel/database.rb +12 -11
  847. data/lib/datadog/tracing/contrib/sequel/dataset.rb +7 -6
  848. data/lib/datadog/tracing/contrib/sequel/ext.rb +12 -8
  849. data/lib/datadog/tracing/contrib/sequel/integration.rb +5 -5
  850. data/lib/datadog/tracing/contrib/sequel/patcher.rb +3 -3
  851. data/lib/datadog/tracing/contrib/sequel/utils.rb +115 -15
  852. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +2 -2
  853. data/lib/datadog/tracing/contrib/shoryuken/ext.rb +12 -12
  854. data/lib/datadog/tracing/contrib/shoryuken/integration.rb +6 -6
  855. data/lib/datadog/tracing/contrib/shoryuken/patcher.rb +1 -1
  856. data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +3 -2
  857. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +15 -9
  858. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +7 -3
  859. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +13 -8
  860. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +31 -29
  861. data/lib/datadog/tracing/contrib/sidekiq/integration.rb +7 -7
  862. data/lib/datadog/tracing/contrib/sidekiq/patcher.rb +8 -8
  863. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/heartbeat.rb +2 -0
  864. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/job_fetch.rb +1 -0
  865. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/redis_info.rb +1 -0
  866. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/scheduled_poller.rb +2 -0
  867. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/stop.rb +1 -0
  868. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +19 -15
  869. data/lib/datadog/tracing/contrib/sidekiq/utils.rb +10 -10
  870. data/lib/datadog/tracing/contrib/sidekiq.rb +7 -6
  871. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +7 -3
  872. data/lib/datadog/tracing/contrib/sinatra/env.rb +6 -6
  873. data/lib/datadog/tracing/contrib/sinatra/ext.rb +17 -16
  874. data/lib/datadog/tracing/contrib/sinatra/framework.rb +2 -2
  875. data/lib/datadog/tracing/contrib/sinatra/integration.rb +5 -5
  876. data/lib/datadog/tracing/contrib/sinatra/patcher.rb +5 -5
  877. data/lib/datadog/tracing/contrib/sinatra/tracer.rb +11 -10
  878. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +46 -45
  879. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +1 -1
  880. data/lib/datadog/tracing/contrib/sneakers/ext.rb +12 -12
  881. data/lib/datadog/tracing/contrib/sneakers/integration.rb +19 -8
  882. data/lib/datadog/tracing/contrib/sneakers/patcher.rb +2 -2
  883. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +4 -3
  884. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +9 -4
  885. data/lib/datadog/tracing/contrib/status_range_env_parser.rb +2 -2
  886. data/lib/datadog/tracing/contrib/status_range_matcher.rb +13 -1
  887. data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +2 -2
  888. data/lib/datadog/tracing/contrib/stripe/ext.rb +12 -12
  889. data/lib/datadog/tracing/contrib/stripe/integration.rb +5 -5
  890. data/lib/datadog/tracing/contrib/stripe/patcher.rb +2 -2
  891. data/lib/datadog/tracing/contrib/stripe/request.rb +5 -5
  892. data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +2 -2
  893. data/lib/datadog/tracing/contrib/sucker_punch/exception_handler.rb +1 -1
  894. data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +13 -13
  895. data/lib/datadog/tracing/contrib/sucker_punch/instrumentation.rb +5 -4
  896. data/lib/datadog/tracing/contrib/sucker_punch/integration.rb +5 -5
  897. data/lib/datadog/tracing/contrib/sucker_punch/patcher.rb +4 -4
  898. data/lib/datadog/tracing/contrib/support.rb +28 -0
  899. data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +9 -3
  900. data/lib/datadog/tracing/contrib/trilogy/ext.rb +12 -12
  901. data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +10 -12
  902. data/lib/datadog/tracing/contrib/trilogy/integration.rb +5 -5
  903. data/lib/datadog/tracing/contrib/trilogy/patcher.rb +2 -2
  904. data/lib/datadog/tracing/contrib/utils/database.rb +5 -5
  905. data/lib/datadog/tracing/contrib/utils/quantization/{hash.rb → hash_formatter.rb} +16 -14
  906. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +16 -16
  907. data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +31 -0
  908. data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +50 -0
  909. data/lib/datadog/tracing/contrib/waterdrop/ext.rb +18 -0
  910. data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
  911. data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
  912. data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +49 -0
  913. data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
  914. data/lib/datadog/tracing/contrib/waterdrop.rb +42 -0
  915. data/lib/datadog/tracing/contrib.rb +62 -52
  916. data/lib/datadog/tracing/correlation.rb +19 -12
  917. data/lib/datadog/tracing/diagnostics/environment_logger.rb +21 -13
  918. data/lib/datadog/tracing/diagnostics/ext.rb +19 -19
  919. data/lib/datadog/tracing/diagnostics/health.rb +1 -1
  920. data/lib/datadog/tracing/distributed/b3_multi.rb +9 -9
  921. data/lib/datadog/tracing/distributed/b3_single.rb +6 -6
  922. data/lib/datadog/tracing/distributed/baggage.rb +252 -0
  923. data/lib/datadog/tracing/distributed/datadog.rb +39 -36
  924. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +12 -27
  925. data/lib/datadog/tracing/distributed/fetcher.rb +1 -1
  926. data/lib/datadog/tracing/distributed/helpers.rb +4 -4
  927. data/lib/datadog/tracing/distributed/none.rb +4 -2
  928. data/lib/datadog/tracing/distributed/propagation.rb +70 -14
  929. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  930. data/lib/datadog/tracing/distributed/trace_context.rb +126 -97
  931. data/lib/datadog/tracing/event.rb +6 -8
  932. data/lib/datadog/tracing/ext.rb +9 -0
  933. data/lib/datadog/tracing/flush.rb +1 -1
  934. data/lib/datadog/tracing/metadata/analytics.rb +3 -3
  935. data/lib/datadog/tracing/metadata/errors.rb +8 -8
  936. data/lib/datadog/tracing/metadata/ext.rb +86 -59
  937. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  938. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  939. data/lib/datadog/tracing/metadata/tagging.rb +8 -8
  940. data/lib/datadog/tracing/metadata.rb +5 -3
  941. data/lib/datadog/tracing/pipeline/span_filter.rb +5 -3
  942. data/lib/datadog/tracing/pipeline/span_processor.rb +3 -1
  943. data/lib/datadog/tracing/pipeline.rb +4 -4
  944. data/lib/datadog/tracing/remote.rb +47 -17
  945. data/lib/datadog/tracing/sampling/all_sampler.rb +1 -1
  946. data/lib/datadog/tracing/sampling/ext.rb +9 -9
  947. data/lib/datadog/tracing/sampling/matcher.rb +4 -4
  948. data/lib/datadog/tracing/sampling/priority_sampler.rb +20 -5
  949. data/lib/datadog/tracing/sampling/rate_by_key_sampler.rb +3 -3
  950. data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +2 -2
  951. data/lib/datadog/tracing/sampling/rate_sampler.rb +9 -19
  952. data/lib/datadog/tracing/sampling/rule.rb +5 -5
  953. data/lib/datadog/tracing/sampling/rule_sampler.rb +88 -59
  954. data/lib/datadog/tracing/sampling/sampler.rb +2 -2
  955. data/lib/datadog/tracing/sampling/span/ext.rb +3 -3
  956. data/lib/datadog/tracing/sampling/span/matcher.rb +2 -2
  957. data/lib/datadog/tracing/sampling/span/rule.rb +1 -2
  958. data/lib/datadog/tracing/sampling/span/rule_parser.rb +11 -11
  959. data/lib/datadog/tracing/sampling/span/sampler.rb +0 -7
  960. data/lib/datadog/tracing/span.rb +28 -11
  961. data/lib/datadog/tracing/span_event.rb +125 -5
  962. data/lib/datadog/tracing/span_link.rb +12 -12
  963. data/lib/datadog/tracing/span_operation.rb +119 -39
  964. data/lib/datadog/tracing/sync_writer.rb +14 -11
  965. data/lib/datadog/tracing/trace_digest.rb +36 -24
  966. data/lib/datadog/tracing/trace_operation.rb +243 -112
  967. data/lib/datadog/tracing/trace_segment.rb +18 -16
  968. data/lib/datadog/tracing/tracer.rb +181 -72
  969. data/lib/datadog/tracing/transport/http/client.rb +17 -30
  970. data/lib/datadog/tracing/transport/http/statistics.rb +2 -2
  971. data/lib/datadog/tracing/transport/http/traces.rb +11 -90
  972. data/lib/datadog/tracing/transport/http.rb +26 -77
  973. data/lib/datadog/tracing/transport/io/client.rb +13 -16
  974. data/lib/datadog/tracing/transport/io/response.rb +1 -1
  975. data/lib/datadog/tracing/transport/io/traces.rb +32 -38
  976. data/lib/datadog/tracing/transport/io.rb +3 -3
  977. data/lib/datadog/tracing/transport/serializable_trace.rb +47 -23
  978. data/lib/datadog/tracing/transport/statistics.rb +3 -3
  979. data/lib/datadog/tracing/transport/trace_formatter.rb +36 -7
  980. data/lib/datadog/tracing/transport/traces.rb +56 -90
  981. data/lib/datadog/tracing/utils.rb +3 -3
  982. data/lib/datadog/tracing/workers.rb +11 -9
  983. data/lib/datadog/tracing/writer.rb +15 -11
  984. data/lib/datadog/tracing.rb +19 -6
  985. data/lib/datadog/version.rb +4 -4
  986. data/lib/datadog.rb +20 -7
  987. metadata +327 -69
  988. data/ext/datadog_profiling_loader/datadog_profiling_loader.c +0 -142
  989. data/ext/datadog_profiling_loader/extconf.rb +0 -60
  990. data/ext/datadog_profiling_native_extension/clock_id_noop.c +0 -21
  991. data/ext/libdatadog_api/macos_development.md +0 -26
  992. data/lib/datadog/appsec/assets/waf_rules/processors.json +0 -92
  993. data/lib/datadog/appsec/assets/waf_rules/scanners.json +0 -114
  994. data/lib/datadog/appsec/configuration/settings.rb +0 -215
  995. data/lib/datadog/appsec/contrib/devise/event.rb +0 -57
  996. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -77
  997. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -54
  998. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  999. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  1000. data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +0 -46
  1001. data/lib/datadog/appsec/contrib/patcher.rb +0 -12
  1002. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +0 -69
  1003. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +0 -47
  1004. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +0 -53
  1005. data/lib/datadog/appsec/contrib/rails/ext.rb +0 -13
  1006. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +0 -53
  1007. data/lib/datadog/appsec/contrib/sinatra/ext.rb +0 -14
  1008. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +0 -48
  1009. data/lib/datadog/appsec/monitor/reactive/set_user.rb +0 -45
  1010. data/lib/datadog/appsec/processor/context.rb +0 -107
  1011. data/lib/datadog/appsec/processor/rule_merger.rb +0 -170
  1012. data/lib/datadog/appsec/processor.rb +0 -106
  1013. data/lib/datadog/appsec/reactive/address_hash.rb +0 -22
  1014. data/lib/datadog/appsec/reactive/engine.rb +0 -47
  1015. data/lib/datadog/appsec/reactive/operation.rb +0 -68
  1016. data/lib/datadog/appsec/reactive/subscriber.rb +0 -19
  1017. data/lib/datadog/appsec/scope.rb +0 -58
  1018. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  1019. data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
  1020. data/lib/datadog/core/remote/transport/http/api/instance.rb +0 -39
  1021. data/lib/datadog/core/remote/transport/http/api/spec.rb +0 -21
  1022. data/lib/datadog/core/remote/transport/http/api.rb +0 -58
  1023. data/lib/datadog/core/remote/transport/http/builder.rb +0 -219
  1024. data/lib/datadog/core/remote/transport/http/client.rb +0 -48
  1025. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  1026. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  1027. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  1028. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
  1029. data/lib/datadog/core/utils/base64.rb +0 -22
  1030. data/lib/datadog/di/configuration/settings.rb +0 -188
  1031. data/lib/datadog/di/transport.rb +0 -81
  1032. data/lib/datadog/tracing/contrib/rails/utils.rb +0 -26
  1033. data/lib/datadog/tracing/transport/http/api/spec.rb +0 -19
  1034. data/lib/datadog/tracing/transport/http/api.rb +0 -43
  1035. data/lib/datadog/tracing/workers/trace_writer.rb +0 -196
@@ -1,8 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Lint/AssignmentInCondition
3
+ require_relative "../core/utils/time"
4
+ require_relative "../ruby_version"
5
+ require_relative "fatal_exceptions"
6
+ require_relative "capture_expression_evaluator"
4
7
 
5
- require 'benchmark'
8
+ # rubocop:disable Lint/AssignmentInCondition
9
+ # rubocop:disable Style/AndOr
6
10
 
7
11
  module Datadog
8
12
  module DI
@@ -52,6 +56,17 @@ module Datadog
52
56
  # (however, Probe instances can be replaced by OpenStruct instances
53
57
  # providing the same interface with not much effort).
54
58
  #
59
+ # Instrumenter (this class) is responsible for building snapshots.
60
+ # This is because to capture values on method entry, those values need to
61
+ # be duplicated or serialized into immutable values to prevent their
62
+ # modification by the instrumented method. Therefore this class must
63
+ # do at least some serialization/snapshot building and to keep the code
64
+ # well-encapsulated, all serialization/snapshot building should thus be
65
+ # initiated from this class rather than downstream code.
66
+ #
67
+ # As a consequence of Instrumenter building snapshots, it should not
68
+ # expose TracePoint objects to any downstream code.
69
+ #
55
70
  # @api private
56
71
  class Instrumenter
57
72
  def initialize(settings, serializer, logger, code_tracker: nil, telemetry: nil)
@@ -70,6 +85,18 @@ module Datadog
70
85
  attr_reader :telemetry
71
86
  attr_reader :code_tracker
72
87
 
88
+ # The code tracker is a global singleton created lazily by
89
+ # DI.activate_tracking. When DI is enabled after boot via remote
90
+ # configuration this instrumenter was already built with a nil tracker;
91
+ # Component#start! assigns the now-current tracker here.
92
+ attr_writer :code_tracker
93
+
94
+ def capture_expression_evaluator
95
+ @capture_expression_evaluator ||= CaptureExpressionEvaluator.new(
96
+ settings: settings, serializer: serializer, logger: logger, telemetry: telemetry,
97
+ )
98
+ end
99
+
73
100
  # This is a substitute for Thread::Backtrace::Location
74
101
  # which does not have a public constructor.
75
102
  # Used for the fabricated stack frame for the method itself
@@ -77,9 +104,22 @@ module Datadog
77
104
  # from the method but from outside of the method).
78
105
  Location = Struct.new(:path, :lineno, :label)
79
106
 
80
- def hook_method(probe, &block)
81
- unless block
82
- raise ArgumentError, 'block is required'
107
+ # Method probes can only target instance methods. The implementation uses
108
+ # Module#prepend with a module that defines an instance method matching the
109
+ # probe's target — class/singleton methods (def self.foo, module_function)
110
+ # are not reachable via prepend on the class itself. Line probes are
111
+ # unaffected since they install via TracePoint, not method dispatch.
112
+ def hook_method(probe, responder)
113
+ # Reject method probes targeting any class or module in the Datadog
114
+ # namespace. The tracer uses these classes internally while building
115
+ # and dispatching probe snapshots; allowing a method probe on them
116
+ # would let DI's own code paths re-enter the probe wrapper. Line
117
+ # probes are unaffected (TracePoint is self-disabling during its
118
+ # callback) and are not rejected here.
119
+ type_name = probe.type_name
120
+ if type_name && datadog_namespace_type_name?(type_name)
121
+ raise Error::ProbeTargetForbidden,
122
+ "Method probes on the Datadog namespace are not permitted: #{type_name}##{probe.method_name}"
83
123
  end
84
124
 
85
125
  lock.synchronize do
@@ -90,10 +130,9 @@ module Datadog
90
130
  end
91
131
 
92
132
  cls = symbolize_class_name(probe.type_name)
93
- serializer = self.serializer
94
- method_name = probe.method_name
95
- loc = begin
96
- cls.instance_method(method_name).source_location
133
+ method_name = probe.method_name!
134
+ target_method = begin
135
+ cls.instance_method(method_name)
97
136
  rescue NameError
98
137
  # The target method is not defined.
99
138
  # This could be because it will be explicitly defined later
@@ -101,81 +140,97 @@ module Datadog
101
140
  # or the method is virtual (provided by a method_missing handler).
102
141
  # In these cases we do not have a source location for the
103
142
  # target method here.
143
+ nil
104
144
  end
105
- rate_limiter = probe.rate_limiter
106
- settings = self.settings
145
+
146
+ # Reject method probes whose target method resolves to Kernel#lambda,
147
+ # including inherited targets. Every class inherits Kernel#lambda, so a
148
+ # probe naming any type that does not override lambda (Object#lambda,
149
+ # String#lambda, a plain user class, ...) prepends the wrapper ahead of
150
+ # Kernel#lambda and reaches the wrapper's super(&block) path. On
151
+ # Ruby 3.3+ that path raises ArgumentError for every lambda { ... }
152
+ # call site passing a captured block, breaking lambda creation
153
+ # process-wide. Resolving the method owner catches the inherited case
154
+ # that a textual "Kernel" name match misses; a type that defines its
155
+ # own lambda has a different owner and is left alone. Probing lambda
156
+ # creation has no legitimate customer use case. See #5560.
157
+ if method_name == "lambda" && target_method&.owner == ::Kernel
158
+ raise Error::ProbeTargetForbidden,
159
+ "Method probes on Kernel#lambda are not permitted: #{probe.type_name}##{method_name}"
160
+ end
161
+
162
+ loc = target_method&.source_location
163
+ instrumenter = self
107
164
 
108
165
  mod = Module.new do
109
- define_method(method_name) do |*args, **kwargs, &target_block| # steep:ignore
110
- if rate_limiter.nil? || rate_limiter.allow?
111
- # Arguments may be mutated by the method, therefore
112
- # they need to be serialized prior to method invocation.
113
- entry_args = if probe.capture_snapshot?
114
- serializer.serialize_args(args, kwargs,
115
- depth: probe.max_capture_depth || settings.dynamic_instrumentation.max_capture_depth,
116
- attribute_count: probe.max_capture_attribute_count || settings.dynamic_instrumentation.max_capture_attribute_count)
166
+ # Argument delegation follows docs/Delegation.md: on Ruby 3+
167
+ # positional and keyword arguments are captured and forwarded
168
+ # separately; on Ruby < 3 everything is captured into a single
169
+ # splat that ruby2_keywords flags, which is the only way to forward
170
+ # a trailing hash while preserving its positional-vs-keyword
171
+ # identity. The pre-3 branch is what lets an empty trailing hash
172
+ # (e.g. foo('x', {})) reach the original method intact.
173
+ #
174
+ # Re-entrancy guard: if we are already inside a DI method-probe
175
+ # callback, skip DI processing and call the original method
176
+ # directly. This prevents SystemStackError when a method probe is
177
+ # set on a stdlib method that DI itself calls during method-probe
178
+ # snapshot building (e.g., String#length, Hash#each). Line probes
179
+ # do not enter the guard — they rely on Ruby's TracePoint, which
180
+ # self-disables during its own callback. Nested invocations during
181
+ # DI processing also bypass the rate limiter: they are not
182
+ # user-observable probe firings, just internal calls that happen to
183
+ # land on a probed method. Guard storage is fiber-local;
184
+ # DI.in_probe?/enter_probe/leave_probe are implemented in C and
185
+ # access it directly, bypassing Thread#[]/Thread#[]= method dispatch
186
+ # so user probes on those cannot recurse.
187
+ #
188
+ # The original method is invoked via super. That super call lives
189
+ # in a block passed to #run_method_probe and captures its binding
190
+ # from inside this define_method block — the only place super
191
+ # resolves to the prepended-on class's method. #run_method_probe
192
+ # invokes it with yield, which does not dispatch Proc#call, so a
193
+ # user probe on Proc#call cannot intercept the trampoline, and no
194
+ # Proc is allocated for the block.
195
+ if RubyVersion.is?(">= 3")
196
+ define_method(method_name) do |*args, **kwargs, &target_block| # steep:ignore NoMethod
197
+ # steep:ignore FallbackAny below: Steep cannot narrow the
198
+ # **kwargs parameter inside this define_method block, so it
199
+ # falls back to untyped at the super and run_method_probe sites.
200
+ if DI.in_probe?
201
+ return super(*args, **kwargs, &target_block) # steep:ignore FallbackAny
117
202
  end
118
- rv = nil
119
- # Under Ruby 2.6 we cannot just call super(*args, **kwargs)
120
- # for methods defined via method_missing.
121
- duration = Benchmark.realtime do # steep:ignore
122
- rv = if args.any?
123
- if kwargs.any?
124
- super(*args, **kwargs, &target_block)
125
- else
126
- super(*args, &target_block)
127
- end
128
- elsif kwargs.any?
129
- super(**kwargs, &target_block)
130
- else
131
- super(&target_block)
132
- end
203
+
204
+ instrumenter.run_method_probe(
205
+ args, kwargs, target_block, # steep:ignore FallbackAny
206
+ self,
207
+ probe, responder,
208
+ loc, method_name,
209
+ ) do
210
+ super(*args, **kwargs, &target_block) # steep:ignore FallbackAny
133
211
  end
134
- # The method itself is not part of the stack trace because
135
- # we are getting the stack trace from outside of the method.
136
- # Add the method in manually as the top frame.
137
- method_frame = if loc
138
- [Location.new(loc.first, loc.last, method_name)]
139
- else
140
- # For virtual and lazily-defined methods, we do not have
141
- # the original source location here, and they won't be
142
- # included in the stack trace currently.
143
- # TODO when begin/end trace points are added for local
144
- # variable capture in method probes, we should be able
145
- # to obtain actual method execution location and use
146
- # that location here.
147
- []
212
+ end
213
+ else
214
+ define_method(method_name) do |*args, &target_block| # steep:ignore NoMethod
215
+ if DI.in_probe?
216
+ return super(*args, &target_block)
148
217
  end
149
- caller_locs = method_frame + caller_locations # steep:ignore
150
- # TODO capture arguments at exit
151
- # & is to stop steep complaints, block is always present here.
152
- block&.call(probe: probe, rv: rv, duration: duration, caller_locations: caller_locs,
153
- serialized_entry_args: entry_args)
154
- rv
155
- else
156
- # stop standard from trying to mess up my code
157
- _ = 42
158
-
159
- # The necessity to invoke super in each of these specific
160
- # ways is very difficult to test.
161
- # Existing tests, even though I wrote many, still don't
162
- # cause a failure if I replace all of the below with a
163
- # simple super(*args, **kwargs, &target_block).
164
- # But, let's be safe and go through the motions in case
165
- # there is actually a legitimate need for the breakdown.
166
- # TODO figure out how to test this properly.
167
- if args.any?
168
- if kwargs.any?
169
- super(*args, **kwargs, &target_block)
170
- else
171
- super(*args, &target_block)
172
- end
173
- elsif kwargs.any?
174
- super(**kwargs, &target_block)
175
- else
176
- super(&target_block)
218
+
219
+ # The super block replays the original *args (closed over here)
220
+ # so the ruby2_keywords-flagged trailing hash keeps its
221
+ # identity. run_method_probe receives the serialization-split
222
+ # arguments separately; forwarding does not use them.
223
+ pos_args, kwargs = instrumenter.kwargs_from_splat(args)
224
+ instrumenter.run_method_probe(
225
+ pos_args, kwargs, target_block,
226
+ self,
227
+ probe, responder,
228
+ loc, method_name,
229
+ ) do
230
+ super(*args, &target_block)
177
231
  end
178
232
  end
233
+ ruby2_keywords(method_name) if respond_to?(:ruby2_keywords, true) # steep:ignore NoMethod
179
234
  end
180
235
  end
181
236
 
@@ -187,6 +242,8 @@ module Datadog
187
242
 
188
243
  probe.instrumentation_module = mod
189
244
  cls.send(:prepend, mod)
245
+
246
+ DI.instrumented_count_inc(:method)
190
247
  end
191
248
  end
192
249
 
@@ -199,6 +256,8 @@ module Datadog
199
256
  if mod = probe.instrumentation_module
200
257
  mod.send(:remove_method, probe.method_name)
201
258
  probe.instrumentation_module = nil
259
+
260
+ DI.instrumented_count_dec(:method)
202
261
  end
203
262
  end
204
263
  end
@@ -208,11 +267,7 @@ module Datadog
208
267
  # not for eval'd code, unless the eval'd code is associated with
209
268
  # a file name and client invokes this method with the correct
210
269
  # file name for the eval'd code.
211
- def hook_line(probe, &block)
212
- unless block
213
- raise ArgumentError, 'No block given to hook_line'
214
- end
215
-
270
+ def hook_line(probe, responder)
216
271
  lock.synchronize do
217
272
  if probe.instrumentation_trace_point
218
273
  # Already instrumented, warn?
@@ -221,7 +276,6 @@ module Datadog
221
276
  end
222
277
 
223
278
  line_no = probe.line_no!
224
- rate_limiter = probe.rate_limiter
225
279
 
226
280
  # Memoize the value to ensure this method always uses the same
227
281
  # value for the setting.
@@ -233,7 +287,14 @@ module Datadog
233
287
 
234
288
  iseq = nil
235
289
  if code_tracker
236
- ret = code_tracker.iseqs_for_path_suffix(probe.file) # steep:ignore
290
+ # Steep: Complex type narrowing (before calling hook_line,
291
+ # we check that probe.line? is true which itself checks that probe.file is not nil)
292
+ # Annotation do not work here as `file` is a method on probe, not a local variable.
293
+ ret = if code_tracker.respond_to?(:iseq_for_line)
294
+ code_tracker.iseq_for_line(probe.file, line_no) # steep:ignore ArgumentTypeMismatch
295
+ else
296
+ code_tracker.iseqs_for_path_suffix(probe.file) # steep:ignore ArgumentTypeMismatch
297
+ end
237
298
  unless ret
238
299
  if permit_untargeted_trace_points
239
300
  # Continue withoout targeting the trace point.
@@ -246,19 +307,21 @@ module Datadog
246
307
  #
247
308
  # If the requested file is not in code tracker's registry,
248
309
  # or the code tracker does not exist at all,
249
- # do not attempt to instrumnet now.
310
+ # do not attempt to instrument now.
250
311
  # The caller should add the line to the list of pending lines
251
312
  # to instrument and install the hook when the file in
252
313
  # question is loaded (and hopefully, by then code tracking
253
314
  # is active, otherwise the line will never be instrumented.)
254
- raise Error::DITargetNotDefined, "File not in code tracker registry: #{probe.file}"
315
+ raise_if_probe_in_loaded_features(probe, line_no, code_tracker)
316
+ raise Error::DITargetNotDefined, "File not in code tracker registry: #{probe.file}:#{line_no}"
255
317
  end
256
318
  end
257
319
  elsif !permit_untargeted_trace_points
258
320
  # Same as previous comment, if untargeted trace points are not
259
321
  # explicitly defined, and we do not have code tracking, do not
260
322
  # instrument the method.
261
- raise Error::DITargetNotDefined, "File not in code tracker registry: #{probe.file}"
323
+ raise_if_probe_in_loaded_features(probe, line_no, nil)
324
+ raise Error::DITargetNotDefined, "File not in code tracker registry: #{probe.file}:#{line_no}"
262
325
  end
263
326
 
264
327
  if ret
@@ -287,36 +350,14 @@ module Datadog
287
350
  [:line]
288
351
  end
289
352
  tp = TracePoint.new(*types) do |tp|
290
- begin
291
- # If trace point is not targeted, we must verify that the invocation
292
- # is the file & line that we want, because untargeted trace points
293
- # are invoked for *each* line of Ruby executed.
294
- # TODO find out exactly when the path in trace point is relative.
295
- # Looks like this is the case when line trace point is not targeted?
296
- if iseq || tp.lineno == probe.line_no && (
297
- probe.file == tp.path || probe.file_matches?(tp.path)
298
- )
299
- if rate_limiter.nil? || rate_limiter.allow?
300
- # & is to stop steep complaints, block is always present here.
301
- block&.call(probe: probe, trace_point: tp, caller_locations: caller_locations)
302
- end
303
- end
304
- rescue => exc
305
- raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
306
- logger.warn("Unhandled exception in line trace point: #{exc.class}: #{exc}")
307
- telemetry&.report(exc, description: "Unhandled exception in line trace point")
308
- # TODO test this path
309
- end
310
- rescue => exc
311
- raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
312
- logger.warn("Unhandled exception in line trace point: #{exc.class}: #{exc}")
313
- telemetry&.report(exc, description: "Unhandled exception in line trace point")
314
- # TODO test this path
353
+ line_trace_point_callback(probe, iseq, responder, tp)
315
354
  end
316
355
 
317
- # TODO internal check - remove or use a proper exception
356
+ # Internal sanity check - untargeted trace points create a huge
357
+ # performance impact, and we absolutely do not want to set them
358
+ # accidentally.
318
359
  if !iseq && !permit_untargeted_trace_points
319
- raise "Trying to use an untargeted trace point when user did not permit it"
360
+ raise Error::InternalError, "Trying to use an untargeted trace point when user did not permit it"
320
361
  end
321
362
 
322
363
  lock.synchronize do
@@ -329,12 +370,16 @@ module Datadog
329
370
  # actual_path could be nil if we don't use targeted trace points.
330
371
  probe.instrumented_path = actual_path
331
372
 
332
- if iseq
373
+ # TracePoint#enable returns false when it succeeds.
374
+ rv = if iseq
333
375
  tp.enable(target: iseq, target_line: line_no)
334
376
  else
335
377
  tp.enable
336
378
  end
337
- # TracePoint#enable returns false when it succeeds.
379
+
380
+ DI.instrumented_count_inc(:line)
381
+
382
+ rv
338
383
  end
339
384
  true
340
385
  end
@@ -344,18 +389,20 @@ module Datadog
344
389
  if tp = probe.instrumentation_trace_point
345
390
  tp.disable
346
391
  probe.instrumentation_trace_point = nil
392
+
393
+ DI.instrumented_count_dec(:line)
347
394
  end
348
395
  end
349
396
  end
350
397
 
351
- def hook(probe, &block)
398
+ def hook(probe, responder)
352
399
  if probe.method?
353
- hook_method(probe, &block)
400
+ hook_method(probe, responder)
354
401
  elsif probe.line?
355
- hook_line(probe, &block)
402
+ hook_line(probe, responder)
356
403
  else
357
404
  # TODO add test coverage for this path
358
- logger.warn("Unknown probe type to hook: #{probe}")
405
+ logger.debug { "di: unknown probe type to hook: #{probe}" }
359
406
  end
360
407
  end
361
408
 
@@ -366,7 +413,24 @@ module Datadog
366
413
  unhook_line(probe)
367
414
  else
368
415
  # TODO add test coverage for this path
369
- logger.warn("Unknown probe type to unhook: #{probe}")
416
+ logger.debug { "di: unknown probe type to unhook: #{probe}" }
417
+ end
418
+ end
419
+
420
+ class << self
421
+ def get_local_variables(trace_point)
422
+ # binding appears to be constructed on access, therefore
423
+ # 1) we should attempt to cache it and
424
+ # 2) we should not call +binding+ until we actually need variable values.
425
+ binding = trace_point.binding
426
+
427
+ # steep hack - should never happen
428
+ return {} unless binding
429
+
430
+ binding.local_variables.each_with_object({}) do |name, map|
431
+ value = binding.local_variable_get(name)
432
+ map[name] = value
433
+ end
370
434
  end
371
435
  end
372
436
 
@@ -374,14 +438,500 @@ module Datadog
374
438
 
375
439
  attr_reader :lock
376
440
 
441
+ # Body of the method probe wrapper. Extracted from the define_method
442
+ # block in #hook_method so the begin/ensure structure can use normal
443
+ # indentation. The original method is invoked with yield, calling the
444
+ # block passed by #hook_method; that block captures super's binding
445
+ # from inside the define_method block, the only place super resolves
446
+ # to the prepended-on class's method.
447
+ #
448
+ # Performance: this method takes eight positional parameters, not
449
+ # keyword parameters, deliberately. Every probed method invocation
450
+ # passes through here on the firing/disabled/rate-limited paths.
451
+ # Keyword-argument calls in Ruby allocate a fresh Hash on every call
452
+ # to materialize the keyword bindings; with eight keyword arguments
453
+ # (~300-1000 ns of allocation per invocation), that hash dominated
454
+ # the wrapper's per-call overhead. Positional parameters skip the
455
+ # allocation entirely. The cost is a long unlabeled signature and
456
+ # an unlabeled call site in #hook_method — both small price for
457
+ # eliminating per-call allocation on the hot path. The argument
458
+ # order matches #hook_method's call site exactly; do not reorder
459
+ # without updating both sides.
460
+ #
461
+ # @param args [Array] positional arguments passed to the probed method
462
+ # @param kwargs [Hash{Symbol => Object}] keyword arguments passed to the probed method
463
+ # @param target_block [Proc, nil] block argument passed to the probed method
464
+ # @param target_self [Object] the receiver of the probed method invocation
465
+ # @param probe [Datadog::DI::Probe] the probe whose callback this invocation runs
466
+ # @param responder [#probe_executed_callback, #probe_condition_evaluation_failed_callback] callback target invoked with the built Context
467
+ # @param loc [Array(String, Integer), nil] source location of the probed method, or nil for virtual/lazily-defined methods
468
+ # @param method_name [String] name of the probed method, used as the synthetic top stack frame label
469
+ # @yield invokes the original method via super and returns its value
470
+ # @return [Object] the original method's return value, or re-raises its exception
471
+ def run_method_probe(args, kwargs, target_block, target_self,
472
+ probe, responder, loc, method_name)
473
+ # Disabled probe: skip DI processing entirely. enter_probe is not
474
+ # called on this path so the guard is never set — there is no DI
475
+ # work to guard, and any nested probed methods invoked by the
476
+ # original method should fire normally without short-circuit.
477
+ return yield unless probe.enabled?
478
+
479
+ DI.enter_probe
480
+ begin
481
+ di_start_time = Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID)
482
+
483
+ continue = true
484
+ if condition = probe.condition
485
+ begin
486
+ # This context will be recreated later, unlike for line probes.
487
+ #
488
+ # We do not need the stack for condition evaluation, therefore
489
+ # stack is not passed to Context here.
490
+ context = Context.new(
491
+ locals: serializer.combine_args(args, kwargs, target_self),
492
+ target_self: target_self,
493
+ probe: probe, settings: settings, serializer: serializer,
494
+ )
495
+ continue = condition.satisfied?(context)
496
+ rescue Exception => exc # standard:disable Lint/RescueException
497
+ Datadog::DI.reraise_if_fatal(exc)
498
+ # Evaluation error exception can be raised for "expected"
499
+ # errors, we probably need another setting to control whether
500
+ # these exceptions are propagated.
501
+ raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions &&
502
+ !exc.is_a?(DI::Error::ExpressionEvaluationError)
503
+
504
+ if context
505
+ # We want to report evaluation errors for conditions
506
+ # as probe snapshots. However, if we failed to create
507
+ # the context, we won't be able to report anything as
508
+ # the probe notifier builder requires a context.
509
+ begin
510
+ responder.probe_condition_evaluation_failed_callback(context, exc)
511
+ rescue Exception => nested_exc # standard:disable Lint/RescueException
512
+ Datadog::DI.reraise_if_fatal(nested_exc)
513
+ raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
514
+
515
+ logger.debug { "di: error in probe condition evaluation failed callback: #{nested_exc.class}: #{nested_exc.message}" }
516
+ telemetry&.report(nested_exc, description: "Error in probe condition evaluation failed callback")
517
+ end
518
+ else
519
+ raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
520
+
521
+ logger.debug { "di: error evaluating condition without context (tracer bug?): #{exc.class}: #{exc.message}" }
522
+ telemetry&.report(exc, description: "Error evaluating condition without context")
523
+ # If execution gets here, there is probably a bug in the tracer.
524
+ end
525
+
526
+ continue = false
527
+ end
528
+ end
529
+
530
+ rate_limiter = probe.rate_limiter
531
+ if continue and rate_limiter.nil? || rate_limiter.allow?
532
+ # Arguments may be mutated by the method, therefore
533
+ # they need to be serialized prior to method invocation.
534
+ serialized_entry_args = if probe.capture_snapshot?
535
+ serializer.serialize_args(args, kwargs, target_self,
536
+ **probe.snapshot_serializer_limits(settings))
537
+ end
538
+
539
+ entry_capture_expressions = nil
540
+ entry_capture_evaluation_errors = nil
541
+ if probe.capture_entry_expressions?
542
+ begin
543
+ entry_context = Context.new(
544
+ probe: probe, settings: settings, serializer: serializer,
545
+ target_self: target_self,
546
+ locals: serializer.combine_args(args, kwargs, target_self),
547
+ )
548
+ entry_capture_expressions, entry_capture_evaluation_errors =
549
+ capture_expression_evaluator.evaluate(probe, entry_context)
550
+ rescue Exception => exc # standard:disable Lint/RescueException
551
+ Datadog::DI.reraise_if_fatal(exc)
552
+ raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
553
+
554
+ logger.debug { "di: error evaluating entry-time capture expressions: #{exc.class}: #{exc.message}" }
555
+ telemetry&.report(exc, description: "Error evaluating entry-time capture expressions")
556
+ end
557
+ end
558
+ # We intentionally do not use Core::Utils::Time.get_time
559
+ # here because the time provider may be overridden by the
560
+ # customer, and DI is not allowed to invoke customer code.
561
+ start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
562
+
563
+ di_duration = Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID) - di_start_time
564
+
565
+ # Release re-entrancy guard for the original method so that
566
+ # probes on other methods (or recursive calls) fire normally
567
+ # during user code execution.
568
+ DI.leave_probe
569
+
570
+ rv = nil
571
+ begin
572
+ # yield invokes the super block without dispatching Proc#call,
573
+ # so a user probe on Proc#call cannot intercept the trampoline.
574
+ # The guard was just released above so nested probes on the
575
+ # customer method body fire normally — but Proc#call must
576
+ # remain bypassed regardless, because the disabled-probe early
577
+ # return at the top of this method also invokes the block.
578
+ rv = yield
579
+ rescue Exception => exc # standard:disable Lint/RescueException
580
+ Datadog::DI.reraise_if_fatal(exc)
581
+ # We will raise the (non-fatal) exception captured here later,
582
+ # after the instrumentation callback runs.
583
+ end
584
+
585
+ # Re-acquire re-entrancy guard for DI post-processing
586
+ # (building context, notification callback).
587
+ DI.enter_probe
588
+
589
+ end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
590
+ duration = end_time - start_time
591
+
592
+ # Restart DI timer.
593
+ # The DI execution duration covers time spent in DI code before
594
+ # the customer method is invoked and time spent in DI code
595
+ # after the customer method finishes.
596
+ di_start_time = Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID)
597
+
598
+ # The method itself is not part of the stack trace because
599
+ # we are getting the stack trace from outside of the method.
600
+ # Add the method in manually as the top frame.
601
+ method_frame = if loc
602
+ [Location.new(loc.first, loc.last, method_name)]
603
+ else
604
+ # For virtual and lazily-defined methods, we do not have
605
+ # the original source location here, and they won't be
606
+ # included in the stack trace currently.
607
+ # TODO when begin/end trace points are added for local
608
+ # variable capture in method probes, we should be able
609
+ # to obtain actual method execution location and use
610
+ # that location here.
611
+ []
612
+ end
613
+ # depth 2 skips run_method_probe and the wrapper define_method
614
+ # block, leaving the user's call site as the first returned frame.
615
+ # caller_locations is RBS-nilable but never nil at this depth.
616
+ caller_locs = method_frame + (caller_locations(2) || [])
617
+ # TODO capture arguments at exit
618
+
619
+ capture_expression_locals = if probe.capture_expressions_only?
620
+ serializer.combine_args(args, kwargs, target_self)
621
+ end
622
+ context = Context.new(locals: capture_expression_locals, target_self: target_self,
623
+ probe: probe, settings: settings, serializer: serializer,
624
+ serialized_entry_args: serialized_entry_args,
625
+ entry_capture_expressions: entry_capture_expressions,
626
+ entry_capture_evaluation_errors: entry_capture_evaluation_errors,
627
+ caller_locations: caller_locs,
628
+ return_value: rv, duration: duration, exception: exc,)
629
+
630
+ begin
631
+ responder.probe_executed_callback(context)
632
+
633
+ check_and_disable_if_exceeded(probe, responder, di_start_time, di_duration)
634
+ rescue Exception => di_exc # standard:disable Lint/RescueException
635
+ Datadog::DI.reraise_if_fatal(di_exc)
636
+ raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
637
+
638
+ logger.debug { "di: unhandled exception in method probe: #{di_exc.class}: #{di_exc.message}" }
639
+ telemetry&.report(di_exc, description: "Unhandled exception in method probe")
640
+ end
641
+
642
+ if exc
643
+ raise exc
644
+ else
645
+ rv
646
+ end
647
+ else
648
+ # Condition not satisfied or rate-limited: skip DI processing
649
+ # and call super. (The disabled-probe case is handled by the
650
+ # early return at the top of this method, so it never reaches
651
+ # this branch.)
652
+ #
653
+ # The guard must be released here (not relied on the ensure)
654
+ # because the super block invokes the customer's method, which
655
+ # may call other probed methods. Those nested probes should fire
656
+ # normally — they would not if the guard were still set,
657
+ # because the wrapper's early-return short-circuits when
658
+ # DI.in_probe? is true.
659
+ #
660
+ # No post-processing in this branch, so we don't re-acquire
661
+ # the guard after super. The ensure's leave_probe below is
662
+ # a no-op here (guard already cleared) and serves the
663
+ # firing branch above, where post-processing re-enters.
664
+ DI.leave_probe
665
+ # yield bypasses Proc#call dispatch — see the firing branch
666
+ # above for the same rationale.
667
+ yield
668
+ end
669
+ ensure
670
+ DI.leave_probe
671
+ end
672
+ end
673
+ # `run_method_probe` is documentation-private (`# @api private`) but must
674
+ # be lexically public so that the prepended wrapper can call it without
675
+ # `.send`. The wrapper hot path is reached when a probed customer method
676
+ # is invoked, and a customer probe on `Object#send` / `Kernel#send`
677
+ # would intercept any `.send` call before the wrapper had a chance to
678
+ # set the re-entrancy guard, causing infinite recursion. Calling the
679
+ # method directly avoids `Object#send` dispatch entirely.
680
+ public :run_method_probe
681
+
682
+ # Splits a Ruby < 3 splat-captured argument list into positional
683
+ # arguments and the trailing keyword-argument hash, for argument
684
+ # serialization only. Returns `[positional_args, kwargs]`. Forwarding
685
+ # does not use this — the wrapper's do_super replays the original
686
+ # splat so the trailing hash keeps its keyword identity.
687
+ #
688
+ # A trailing hash is treated as keyword arguments regardless of how it
689
+ # was passed at the call site, matching the previous `**kwargs`
690
+ # capture (which, on Ruby 2.x, absorbed a trailing hash into kwargs).
691
+ # The ruby2_keywords flag is intentionally not consulted here: callers
692
+ # that pass a hash positionally (e.g. `m(opts)`) still expect it shown
693
+ # as a keyword argument, consistent with Ruby 2.x serialization.
694
+ #
695
+ # The trailing-element test goes through DI.hash? (a C type check)
696
+ # rather than `last.is_a?(Hash)`: kwargs_from_splat runs before the
697
+ # re-entrancy guard is set, so a customer method probe on Kernel#is_a?
698
+ # would otherwise re-enter the wrapper and recurse. DI.hash? is a
699
+ # singleton method and cannot be targeted by a method probe.
700
+ #
701
+ # Defined only on Ruby < 3; the Ruby 3+ wrapper captures keyword
702
+ # arguments directly and never calls this.
703
+ if RubyVersion.is?("< 3")
704
+ def kwargs_from_splat(args)
705
+ last = args.last
706
+ if DI.hash?(last)
707
+ [args[0...-1] || [], last]
708
+ else
709
+ [args, {}]
710
+ end
711
+ end
712
+ # Lexically public for the same reason as #run_method_probe: the
713
+ # prepended wrapper must call it without `.send`, which a customer
714
+ # probe on Object#send could intercept.
715
+ public :kwargs_from_splat
716
+ end
717
+
718
+ def line_trace_point_callback(probe, iseq, responder, tp)
719
+ di_start_time = Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID)
720
+
721
+ # Check if probe is enabled before doing any processing
722
+ return unless probe.enabled?
723
+
724
+ # If trace point is not targeted, we must verify that the invocation
725
+ # is the file & line that we want, because untargeted trace points
726
+ # are invoked for *each* line of Ruby executed.
727
+ # TODO find out exactly when the path in trace point is relative.
728
+ # Looks like this is the case when line trace point is not targeted?
729
+ unless iseq
730
+ return unless tp.lineno == probe.line_no && ( # standard:disable Style/UnlessLogicalOperators
731
+ probe.file == tp.path || probe.file_matches?(tp.path)
732
+ )
733
+ end
734
+
735
+ # We set the trace point on :return to be able to instrument
736
+ # 'end' lines. This also causes the trace point to be invoked on
737
+ # non-'end' lines when a line raises an exception, since the
738
+ # exception causes the method to stop executing and stack unwends.
739
+ # We do not want two invocations of the trace point.
740
+ # Therefore, if a trace point is invoked with a :line event,
741
+ # mark it as such and ignore subsequent :return events.
742
+ if probe.executed_on_line?
743
+ return unless tp.event == :line
744
+ else
745
+ _ = 42 # stop standard from changing this code
746
+
747
+ if tp.event == :line
748
+ probe.executed_on_line!
749
+ end
750
+ end
751
+
752
+ if condition = probe.condition
753
+ begin
754
+ context = build_trace_point_context(probe, tp)
755
+ return unless condition.satisfied?(context)
756
+ rescue Exception => exc # standard:disable Lint/RescueException
757
+ Datadog::DI.reraise_if_fatal(exc)
758
+ # Evaluation error exception can be raised for "expected"
759
+ # errors, we probably need another setting to control whether
760
+ # these exceptions are propagated.
761
+ raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions &&
762
+ !exc.is_a?(DI::Error::ExpressionEvaluationError)
763
+
764
+ if context
765
+ # We want to report evaluation errors for conditions
766
+ # as probe snapshots. However, if we failed to create
767
+ # the context, we won't be able to report anything as
768
+ # the probe notifier builder requires a context.
769
+ begin
770
+ responder.probe_condition_evaluation_failed_callback(context, condition, exc)
771
+ rescue Exception => nested_exc # standard:disable Lint/RescueException
772
+ Datadog::DI.reraise_if_fatal(nested_exc)
773
+ raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
774
+
775
+ logger.debug { "di: error in probe condition evaluation failed callback: #{nested_exc.class}: #{nested_exc.message}" }
776
+ telemetry&.report(nested_exc, description: "Error in probe condition evaluation failed callback")
777
+ end
778
+
779
+ return
780
+ else
781
+ _ = 42 # stop standard from wrecking this code
782
+
783
+ raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
784
+
785
+ logger.debug { "di: error evaluating condition without context (tracer bug?): #{exc.class}: #{exc.message}" }
786
+ telemetry&.report(exc, description: "Error evaluating condition without context")
787
+ # If execution gets here, there is probably a bug in the tracer.
788
+ end
789
+ end
790
+ end
791
+
792
+ # In practice we should always have a rate limiter, but be safe
793
+ # and check that it is in fact set.
794
+ return if probe.rate_limiter && !probe.rate_limiter.allow?
795
+
796
+ # The context creation is relatively expensive and we don't
797
+ # want to run it if the callback won't be executed due to the
798
+ # rate limit.
799
+ # Thus the copy-paste of the creation call here.
800
+ context ||= build_trace_point_context(probe, tp)
801
+
802
+ responder.probe_executed_callback(context)
803
+
804
+ check_and_disable_if_exceeded(probe, responder, di_start_time)
805
+ rescue Exception => exc # standard:disable Lint/RescueException
806
+ Datadog::DI.reraise_if_fatal(exc)
807
+ raise if settings.dynamic_instrumentation.internal.propagate_all_exceptions
808
+ logger.debug { "di: unhandled exception in line trace point: #{exc.class}: #{exc.message}" }
809
+ telemetry&.report(exc, description: "Unhandled exception in line trace point")
810
+ # TODO test this path
811
+ end
812
+
813
+ def build_trace_point_context(probe, tp)
814
+ stack = caller_locations
815
+ # We have two helper methods being invoked from the trace point
816
+ # handler block, remove them from the stack.
817
+ #
818
+ # According to steep stack may be nil.
819
+ stack&.shift(2)
820
+ Context.new(
821
+ locals: Instrumenter.get_local_variables(tp),
822
+ target_self: tp.self,
823
+ probe: probe,
824
+ settings: settings,
825
+ serializer: serializer,
826
+ path: tp.path,
827
+ caller_locations: stack,
828
+ )
829
+ end
830
+
831
+ # Circuit breaker: disables the probe if total CPU time consumed by
832
+ # DI processing exceeds the configured threshold.
833
+ def check_and_disable_if_exceeded(probe, responder, di_start_time, accumulated_duration = 0.0)
834
+ return unless max_processing_time = settings.dynamic_instrumentation.internal.max_processing_time
835
+
836
+ di_duration = accumulated_duration + Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID) - di_start_time
837
+ if di_duration > max_processing_time
838
+ logger.debug { "di: disabling probe: consumed #{di_duration}: #{probe}" }
839
+ # We disable the probe here rather than remove it to
840
+ # avoid a dependency on ProbeManager from Instrumenter.
841
+ probe.disable!
842
+ responder.probe_disabled_callback(probe, di_duration)
843
+ end
844
+ end
845
+
846
+ def raise_if_probe_in_loaded_features(probe, line_no, code_tracker)
847
+ return unless probe.file
848
+
849
+ # Find the loaded path matching the probe file. Case-sensitive
850
+ # matching is attempted first, with case-insensitive matching as a
851
+ # fallback (see the design comment in utils.rb, steps 5-8). Leading
852
+ # directory components are stripped so probes whose sourceFile carries
853
+ # a source-repo prefix that does not exist on disk still resolve to
854
+ # the loaded file — matching the behavior of
855
+ # CodeTracker#iseqs_for_path_suffix.
856
+ loaded_path = if $LOADED_FEATURES.include?(probe.file)
857
+ probe.file
858
+ else
859
+ # Expensive suffix check.
860
+ suffix = Utils.normalize_windows_separators(probe.file)
861
+ found = nil #: ::String?
862
+ [false, true].each do |case_insensitive|
863
+ working_suffix = suffix.dup
864
+ loop do
865
+ found = $LOADED_FEATURES.find do |path|
866
+ Utils.path_matches_suffix?(path, working_suffix, case_insensitive: case_insensitive)
867
+ end
868
+ break if found
869
+ break unless working_suffix.include?("/")
870
+ working_suffix.sub!(%r{.*/+}, "")
871
+ end
872
+ break if found
873
+ end
874
+ found
875
+ end
876
+
877
+ return unless loaded_path
878
+
879
+ # Distinguish between "no iseqs at all" and "has per-method iseqs
880
+ # but none cover this line".
881
+ has_per_method = code_tracker&.send(:instance_variable_defined?, :@per_method_registry) &&
882
+ code_tracker.send(:per_method_registry).key?(loaded_path)
883
+
884
+ if code_tracker.nil?
885
+ raise Error::DITargetNotInRegistry,
886
+ "File #{loaded_path} is loaded but code tracking is not active; " \
887
+ "line probes cannot be targeted."
888
+ elsif has_per_method
889
+ raise Error::DITargetNotInRegistry,
890
+ "File #{loaded_path} is loaded and has per-method iseqs, " \
891
+ "but none cover line #{line_no}. " \
892
+ "The line may be in file-level setup code outside any method."
893
+ else
894
+ raise Error::DITargetNotInRegistry,
895
+ "File #{loaded_path} is loaded but has no surviving iseqs " \
896
+ "(whole-file iseq was garbage collected and no per-method iseqs remain). " \
897
+ "Line probes cannot target this file."
898
+ end
899
+ end
900
+
377
901
  # TODO test that this resolves qualified names e.g. A::B
378
902
  def symbolize_class_name(cls_name)
379
- Object.const_get(cls_name)
903
+ Object.const_get(cls_name) # steep:ignore ArgumentTypeMismatch
380
904
  rescue NameError => exc
381
- raise Error::DITargetNotDefined, "Class not defined: #{cls_name}: #{exc.class}: #{exc}"
905
+ raise Error::DITargetNotDefined, "Class not defined: #{cls_name}: #{exc.class}: #{exc.message}"
906
+ end
907
+
908
+ # Matches a class name in the Datadog namespace, tolerating the alias
909
+ # forms that Object.const_get resolves to the same top-level constants.
910
+ # Two such forms exist: an optional leading "::" (Ruby's root-namespace
911
+ # prefix), and any number of leading "Object::" segments. Top-level
912
+ # constants are constants of Object, so "Object::Datadog::DI::Instrumenter"
913
+ # resolves to Datadog::DI::Instrumenter; without stripping "Object::" a
914
+ # probe could name a tracer-internal class through an Object:: alias and
915
+ # bypass the rejection, then get prepended onto tracer internals. These
916
+ # are the only alias paths to the top-level Datadog: "Foo::Datadog" does
917
+ # not resolve through const_get for an arbitrary Foo. Anchored at \A so
918
+ # the match decides in O(prefix length) without scanning.
919
+ DATADOG_NAMESPACE_TYPE_NAME = /\A(?:::)?(?:Object::)*Datadog(?:::|\z)/
920
+ private_constant :DATADOG_NAMESPACE_TYPE_NAME
921
+
922
+ # Returns true when +cls_name+ names the +Datadog+ module itself or
923
+ # any class/module under it (e.g. +Datadog::Tracing::SpanOperation+).
924
+ # The check is purely textual on the probe's declared type name; it
925
+ # does not require the class to be loaded. A leading +::+ and any
926
+ # number of leading +Object::+ segments are treated the same as the
927
+ # bare form, since Object.const_get resolves those aliases to the same
928
+ # top-level constants.
929
+ def datadog_namespace_type_name?(cls_name)
930
+ DATADOG_NAMESPACE_TYPE_NAME.match?(cls_name)
382
931
  end
383
932
  end
384
933
  end
385
934
  end
386
935
 
387
936
  # rubocop:enable Lint/AssignmentInCondition
937
+ # rubocop:enable Style/AndOr