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