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