datadog 2.38.0 → 2.47.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 (922) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +279 -35
  3. data/README.md +3 -0
  4. data/bin/ddprofrb +4 -4
  5. data/ext/datadog_profiling_native_extension/NativeExtensionDesign.md +12 -24
  6. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +256 -117
  7. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -5
  8. data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.c +0 -2
  9. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +19 -20
  10. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.h +5 -1
  11. data/ext/datadog_profiling_native_extension/collectors_stack.c +267 -171
  12. data/ext/datadog_profiling_native_extension/collectors_stack.h +17 -3
  13. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +307 -217
  14. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +10 -5
  15. data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +5 -4
  16. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +19 -11
  17. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +7 -10
  18. data/ext/datadog_profiling_native_extension/extconf.rb +68 -100
  19. data/ext/datadog_profiling_native_extension/heap_recorder.c +353 -257
  20. data/ext/datadog_profiling_native_extension/heap_recorder.h +50 -31
  21. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +3 -27
  22. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +853 -496
  23. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +42 -15
  24. data/ext/datadog_profiling_native_extension/profiling.c +30 -23
  25. data/ext/datadog_profiling_native_extension/ruby_helpers.c +4 -80
  26. data/ext/datadog_profiling_native_extension/ruby_helpers.h +4 -7
  27. data/ext/datadog_profiling_native_extension/stack_recorder.c +116 -89
  28. data/ext/datadog_profiling_native_extension/stack_recorder.h +12 -5
  29. data/ext/datadog_profiling_native_extension/time_helpers.c +2 -4
  30. data/ext/datadog_profiling_native_extension/time_helpers.h +15 -15
  31. data/ext/libdatadog_api/datadog_ruby_common.c +19 -11
  32. data/ext/libdatadog_api/datadog_ruby_common.h +7 -10
  33. data/ext/libdatadog_api/di.c +43 -3
  34. data/ext/libdatadog_api/extconf.rb +29 -24
  35. data/ext/libdatadog_api/feature_flags.c +34 -0
  36. data/ext/libdatadog_api/init.c +9 -1
  37. data/ext/libdatadog_api/otel_thread_context.c +274 -0
  38. data/ext/libdatadog_api/otel_thread_context.h +5 -0
  39. data/ext/libdatadog_api/process_discovery.c +15 -1
  40. data/ext/libdatadog_api/trace_exporter.c +2078 -0
  41. data/ext/libdatadog_api/trace_exporter.h +5 -0
  42. data/ext/libdatadog_extconf_helpers.rb +22 -17
  43. data/lib/datadog/ai_guard/component.rb +24 -15
  44. data/lib/datadog/ai_guard/configuration/ext.rb +2 -0
  45. data/lib/datadog/ai_guard/configuration.rb +13 -0
  46. data/lib/datadog/ai_guard/contrib/ruby_llm/chat_instrumentation.rb +48 -55
  47. data/lib/datadog/ai_guard/contrib/ruby_llm/integration.rb +1 -1
  48. data/lib/datadog/ai_guard/contrib/ruby_llm/message_adapter.rb +76 -0
  49. data/lib/datadog/ai_guard/contrib/ruby_llm/patcher.rb +1 -0
  50. data/lib/datadog/ai_guard/contrib/ruby_llm/redaction_change_set.rb +135 -0
  51. data/lib/datadog/ai_guard/evaluation/client.rb +50 -0
  52. data/lib/datadog/ai_guard/evaluation/content_part.rb +12 -0
  53. data/lib/datadog/ai_guard/evaluation/message.rb +25 -7
  54. data/lib/datadog/ai_guard/evaluation/message_builder.rb +31 -0
  55. data/lib/datadog/ai_guard/evaluation/no_op_result.rb +6 -6
  56. data/lib/datadog/ai_guard/evaluation/outcome.rb +24 -0
  57. data/lib/datadog/ai_guard/evaluation/request.rb +8 -64
  58. data/lib/datadog/ai_guard/evaluation/response.rb +33 -0
  59. data/lib/datadog/ai_guard/evaluation/result.rb +11 -18
  60. data/lib/datadog/ai_guard/evaluation/tool_call.rb +15 -2
  61. data/lib/datadog/ai_guard/evaluation.rb +36 -14
  62. data/lib/datadog/ai_guard/ext.rb +4 -1
  63. data/lib/datadog/ai_guard/{api_client.rb → http_client.rb} +9 -7
  64. data/lib/datadog/ai_guard/metrics/telemetry.rb +43 -0
  65. data/lib/datadog/ai_guard/redaction/replacements.rb +97 -0
  66. data/lib/datadog/ai_guard/redaction/result.rb +29 -0
  67. data/lib/datadog/ai_guard/redaction.rb +80 -0
  68. data/lib/datadog/ai_guard.rb +58 -57
  69. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +22 -43
  70. data/lib/datadog/appsec/actions_handler.rb +6 -6
  71. data/lib/datadog/appsec/anonymizer.rb +1 -1
  72. data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +2 -2
  73. data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +6 -6
  74. data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +1 -1
  75. data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +2 -2
  76. data/lib/datadog/appsec/api_security/route_extractor.rb +11 -11
  77. data/lib/datadog/appsec/api_security/sampler.rb +5 -5
  78. data/lib/datadog/appsec/api_security.rb +1 -1
  79. data/lib/datadog/appsec/assets/blocked.html +1 -108
  80. data/lib/datadog/appsec/assets.rb +7 -7
  81. data/lib/datadog/appsec/autoload.rb +3 -3
  82. data/lib/datadog/appsec/component.rb +15 -15
  83. data/lib/datadog/appsec/compressed_json.rb +6 -6
  84. data/lib/datadog/appsec/configuration.rb +70 -61
  85. data/lib/datadog/appsec/context.rb +7 -7
  86. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +6 -6
  87. data/lib/datadog/appsec/contrib/active_record/integration.rb +4 -4
  88. data/lib/datadog/appsec/contrib/active_record/patcher.rb +4 -4
  89. data/lib/datadog/appsec/contrib/aws_lambda/gateway/watcher.rb +7 -7
  90. data/lib/datadog/appsec/contrib/aws_lambda/integration.rb +2 -2
  91. data/lib/datadog/appsec/contrib/aws_lambda/patcher.rb +2 -2
  92. data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +36 -34
  93. data/lib/datadog/appsec/contrib/devise/configuration.rb +1 -1
  94. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +3 -3
  95. data/lib/datadog/appsec/contrib/devise/ext.rb +20 -20
  96. data/lib/datadog/appsec/contrib/devise/integration.rb +4 -4
  97. data/lib/datadog/appsec/contrib/devise/patcher.rb +8 -8
  98. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +12 -12
  99. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +8 -8
  100. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +24 -9
  101. data/lib/datadog/appsec/contrib/excon/integration.rb +4 -4
  102. data/lib/datadog/appsec/contrib/excon/patcher.rb +1 -1
  103. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +26 -26
  104. data/lib/datadog/appsec/contrib/faraday/integration.rb +4 -4
  105. data/lib/datadog/appsec/contrib/faraday/patcher.rb +4 -4
  106. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +22 -22
  107. data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +4 -4
  108. data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +2 -2
  109. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +7 -7
  110. data/lib/datadog/appsec/contrib/graphql/integration.rb +9 -9
  111. data/lib/datadog/appsec/contrib/graphql/patcher.rb +3 -3
  112. data/lib/datadog/appsec/contrib/rack/buffered_input.rb +1 -1
  113. data/lib/datadog/appsec/contrib/rack/ext.rb +29 -29
  114. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +14 -18
  115. data/lib/datadog/appsec/contrib/rack/gateway/response.rb +1 -1
  116. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +24 -24
  117. data/lib/datadog/appsec/contrib/rack/input_peeker.rb +6 -6
  118. data/lib/datadog/appsec/contrib/rack/integration.rb +6 -6
  119. data/lib/datadog/appsec/contrib/rack/patcher.rb +3 -3
  120. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +11 -8
  121. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +26 -26
  122. data/lib/datadog/appsec/contrib/rack/response_body.rb +1 -1
  123. data/lib/datadog/appsec/contrib/rails/gateway/request.rb +10 -10
  124. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +38 -11
  125. data/lib/datadog/appsec/contrib/rails/integration.rb +5 -5
  126. data/lib/datadog/appsec/contrib/rails/patcher.rb +17 -17
  127. data/lib/datadog/appsec/contrib/rails/patches/process_action_patch.rb +2 -2
  128. data/lib/datadog/appsec/contrib/rails/patches/render_to_body_patch.rb +10 -9
  129. data/lib/datadog/appsec/contrib/rails/request.rb +3 -3
  130. data/lib/datadog/appsec/contrib/rails/request_middleware.rb +2 -1
  131. data/lib/datadog/appsec/contrib/rest_client/integration.rb +5 -5
  132. data/lib/datadog/appsec/contrib/rest_client/patcher.rb +1 -1
  133. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +23 -23
  134. data/lib/datadog/appsec/contrib/sinatra/gateway/request.rb +1 -1
  135. data/lib/datadog/appsec/contrib/sinatra/gateway/route_params.rb +1 -1
  136. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +28 -16
  137. data/lib/datadog/appsec/contrib/sinatra/integration.rb +5 -5
  138. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +11 -11
  139. data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +10 -9
  140. data/lib/datadog/appsec/contrib/sinatra/request_middleware.rb +2 -1
  141. data/lib/datadog/appsec/counter_sampler.rb +1 -1
  142. data/lib/datadog/appsec/event.rb +14 -14
  143. data/lib/datadog/appsec/ext.rb +11 -11
  144. data/lib/datadog/appsec/extensions.rb +2 -2
  145. data/lib/datadog/appsec/instrumentation/gateway.rb +1 -1
  146. data/lib/datadog/appsec/metrics/exporter.rb +8 -8
  147. data/lib/datadog/appsec/metrics/telemetry.rb +7 -7
  148. data/lib/datadog/appsec/metrics/telemetry_exporter.rb +4 -4
  149. data/lib/datadog/appsec/metrics.rb +4 -4
  150. data/lib/datadog/appsec/monitor/gateway/watcher.rb +16 -12
  151. data/lib/datadog/appsec/monitor.rb +1 -1
  152. data/lib/datadog/appsec/processor/rule_loader.rb +32 -32
  153. data/lib/datadog/appsec/rate_limiter.rb +1 -1
  154. data/lib/datadog/appsec/remote.rb +6 -6
  155. data/lib/datadog/appsec/response.rb +22 -22
  156. data/lib/datadog/appsec/route_normalizer/rails_route_pattern.rb +11 -11
  157. data/lib/datadog/appsec/route_normalizer/route_pattern.rb +18 -18
  158. data/lib/datadog/appsec/route_normalizer/route_text.rb +3 -3
  159. data/lib/datadog/appsec/route_normalizer.rb +15 -15
  160. data/lib/datadog/appsec/security_engine/engine.rb +41 -40
  161. data/lib/datadog/appsec/security_engine/runner.rb +2 -2
  162. data/lib/datadog/appsec/security_event.rb +2 -2
  163. data/lib/datadog/appsec/utils/http/body.rb +11 -8
  164. data/lib/datadog/appsec/utils/http/body_reader.rb +1 -1
  165. data/lib/datadog/appsec/utils/http/media_range.rb +15 -15
  166. data/lib/datadog/appsec/utils/http/media_type.rb +4 -4
  167. data/lib/datadog/appsec/utils/http/url_encoded.rb +80 -25
  168. data/lib/datadog/appsec.rb +16 -16
  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/base.rb +2 -2
  175. data/lib/datadog/core/configuration/components.rb +82 -47
  176. data/lib/datadog/core/configuration/components_state.rb +8 -1
  177. data/lib/datadog/core/configuration/config_helper.rb +3 -3
  178. data/lib/datadog/core/configuration/deprecations.rb +6 -6
  179. data/lib/datadog/core/configuration/ext.rb +11 -11
  180. data/lib/datadog/core/configuration/option.rb +16 -16
  181. data/lib/datadog/core/configuration/option_definition.rb +5 -5
  182. data/lib/datadog/core/configuration/options.rb +2 -2
  183. data/lib/datadog/core/configuration/settings.rb +95 -100
  184. data/lib/datadog/core/configuration/stable_config.rb +1 -1
  185. data/lib/datadog/core/configuration/supported_configurations.rb +20 -3
  186. data/lib/datadog/core/configuration.rb +8 -8
  187. data/lib/datadog/core/contrib/rails/railtie.rb +3 -3
  188. data/lib/datadog/core/crashtracking/component.rb +14 -10
  189. data/lib/datadog/core/crashtracking/tag_builder.rb +5 -5
  190. data/lib/datadog/core/deprecations.rb +1 -1
  191. data/lib/datadog/core/diagnostics/environment_logger.rb +42 -7
  192. data/lib/datadog/core/diagnostics/health.rb +2 -2
  193. data/lib/datadog/core/encoding.rb +4 -4
  194. data/lib/datadog/core/environment/agent_info.rb +2 -2
  195. data/lib/datadog/core/environment/cgroup.rb +4 -4
  196. data/lib/datadog/core/environment/container.rb +9 -9
  197. data/lib/datadog/core/environment/execution.rb +3 -3
  198. data/lib/datadog/core/environment/ext.rb +18 -18
  199. data/lib/datadog/core/environment/gc.rb +1 -1
  200. data/lib/datadog/core/environment/git.rb +2 -2
  201. data/lib/datadog/core/environment/identity.rb +10 -10
  202. data/lib/datadog/core/environment/platform.rb +8 -8
  203. data/lib/datadog/core/environment/process.rb +3 -3
  204. data/lib/datadog/core/environment/socket.rb +2 -2
  205. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  206. data/lib/datadog/core/environment/vm_cache.rb +1 -1
  207. data/lib/datadog/core/environment/yjit.rb +2 -2
  208. data/lib/datadog/core/error.rb +5 -5
  209. data/lib/datadog/core/evp.rb +2 -2
  210. data/lib/datadog/core/extensions.rb +1 -1
  211. data/lib/datadog/core/feature_flags.rb +2 -2
  212. data/lib/datadog/core/git/ext.rb +4 -4
  213. data/lib/datadog/core/logger.rb +3 -3
  214. data/lib/datadog/core/logging/ext.rb +1 -1
  215. data/lib/datadog/core/metrics/client.rb +20 -20
  216. data/lib/datadog/core/metrics/ext.rb +5 -5
  217. data/lib/datadog/core/metrics/helpers.rb +1 -1
  218. data/lib/datadog/core/metrics/logging.rb +2 -2
  219. data/lib/datadog/core/metrics/options.rb +5 -5
  220. data/lib/datadog/core/pin.rb +1 -1
  221. data/lib/datadog/core/process_discovery.rb +13 -9
  222. data/lib/datadog/core/rate_limiter.rb +1 -1
  223. data/lib/datadog/core/remote/client/capabilities.rb +60 -33
  224. data/lib/datadog/core/remote/client.rb +61 -20
  225. data/lib/datadog/core/remote/component.rb +48 -17
  226. data/lib/datadog/core/remote/configuration/content.rb +3 -3
  227. data/lib/datadog/core/remote/configuration/digest.rb +1 -1
  228. data/lib/datadog/core/remote/configuration/path.rb +9 -9
  229. data/lib/datadog/core/remote/configuration/repository.rb +4 -4
  230. data/lib/datadog/core/remote/configuration/target.rb +9 -9
  231. data/lib/datadog/core/remote/configuration.rb +4 -4
  232. data/lib/datadog/core/remote/dispatcher.rb +47 -6
  233. data/lib/datadog/core/remote/ext.rb +3 -3
  234. data/lib/datadog/core/remote/negotiation.rb +1 -1
  235. data/lib/datadog/core/remote/tie/tracing.rb +7 -7
  236. data/lib/datadog/core/remote/transport/config.rb +4 -4
  237. data/lib/datadog/core/remote/transport/http/config.rb +7 -7
  238. data/lib/datadog/core/remote/transport/http/negotiation.rb +4 -4
  239. data/lib/datadog/core/remote/transport/http.rb +10 -10
  240. data/lib/datadog/core/remote/transport/negotiation.rb +3 -3
  241. data/lib/datadog/core/remote/worker.rb +13 -5
  242. data/lib/datadog/core/runtime/ext.rb +22 -22
  243. data/lib/datadog/core/runtime/metrics.rb +9 -9
  244. data/lib/datadog/core/tag_builder.rb +18 -18
  245. data/lib/datadog/core/tag_normalizer.rb +7 -7
  246. data/lib/datadog/core/telemetry/component.rb +13 -13
  247. data/lib/datadog/core/telemetry/configuration_value.rb +38 -0
  248. data/lib/datadog/core/telemetry/emitter.rb +4 -4
  249. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +8 -6
  250. data/lib/datadog/core/telemetry/event/app_closing.rb +2 -2
  251. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +2 -2
  252. data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +3 -3
  253. data/lib/datadog/core/telemetry/event/app_extended_heartbeat.rb +2 -2
  254. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +2 -2
  255. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +2 -2
  256. data/lib/datadog/core/telemetry/event/app_started.rb +36 -55
  257. data/lib/datadog/core/telemetry/event/base.rb +1 -1
  258. data/lib/datadog/core/telemetry/event/distributions.rb +2 -2
  259. data/lib/datadog/core/telemetry/event/generate_metrics.rb +3 -3
  260. data/lib/datadog/core/telemetry/event/log.rb +6 -6
  261. data/lib/datadog/core/telemetry/event/message_batch.rb +1 -1
  262. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +3 -3
  263. data/lib/datadog/core/telemetry/event.rb +16 -16
  264. data/lib/datadog/core/telemetry/ext.rb +11 -11
  265. data/lib/datadog/core/telemetry/logger.rb +1 -1
  266. data/lib/datadog/core/telemetry/logging.rb +5 -5
  267. data/lib/datadog/core/telemetry/metric.rb +9 -9
  268. data/lib/datadog/core/telemetry/metrics_collection.rb +2 -2
  269. data/lib/datadog/core/telemetry/metrics_manager.rb +1 -1
  270. data/lib/datadog/core/telemetry/request.rb +6 -6
  271. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +14 -14
  272. data/lib/datadog/core/telemetry/transport/http.rb +7 -7
  273. data/lib/datadog/core/telemetry/transport/telemetry.rb +3 -3
  274. data/lib/datadog/core/telemetry/worker.rb +6 -6
  275. data/lib/datadog/core/transport/ext.rb +14 -14
  276. data/lib/datadog/core/transport/http/adapters/net.rb +4 -4
  277. data/lib/datadog/core/transport/http/adapters/test.rb +1 -1
  278. data/lib/datadog/core/transport/http/adapters/unix_socket.rb +4 -4
  279. data/lib/datadog/core/transport/http/api/endpoint.rb +1 -1
  280. data/lib/datadog/core/transport/http/api/map.rb +1 -1
  281. data/lib/datadog/core/transport/http/builder.rb +5 -5
  282. data/lib/datadog/core/transport/http/client.rb +2 -2
  283. data/lib/datadog/core/transport/http/response.rb +1 -1
  284. data/lib/datadog/core/transport/http.rb +9 -9
  285. data/lib/datadog/core/transport/transport.rb +2 -2
  286. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +172 -20
  287. data/lib/datadog/core/utils/base64_codec.rb +3 -3
  288. data/lib/datadog/core/utils/duration.rb +1 -1
  289. data/lib/datadog/core/utils/forking.rb +2 -2
  290. data/lib/datadog/core/utils/lru_cache.rb +3 -3
  291. data/lib/datadog/core/utils/network.rb +11 -11
  292. data/lib/datadog/core/utils/only_once_successful.rb +1 -1
  293. data/lib/datadog/core/utils/safe_dup.rb +2 -1
  294. data/lib/datadog/core/utils/sequence.rb +3 -6
  295. data/lib/datadog/core/utils/spawn_monkey_patch.rb +2 -2
  296. data/lib/datadog/core/utils/time.rb +16 -54
  297. data/lib/datadog/core/utils/url.rb +1 -1
  298. data/lib/datadog/core/utils.rb +4 -4
  299. data/lib/datadog/core/workers/async.rb +1 -1
  300. data/lib/datadog/core/workers/polling.rb +2 -2
  301. data/lib/datadog/core/workers/runtime_metrics.rb +5 -5
  302. data/lib/datadog/core.rb +4 -4
  303. data/lib/datadog/data_streams/configuration.rb +3 -3
  304. data/lib/datadog/data_streams/ext.rb +1 -1
  305. data/lib/datadog/data_streams/extensions.rb +2 -2
  306. data/lib/datadog/data_streams/pathway_context.rb +25 -27
  307. data/lib/datadog/data_streams/processor.rb +92 -61
  308. data/lib/datadog/data_streams/transport/http/stats.rb +5 -5
  309. data/lib/datadog/data_streams/transport/http.rb +5 -5
  310. data/lib/datadog/data_streams/transport/stats.rb +7 -7
  311. data/lib/datadog/data_streams.rb +5 -5
  312. data/lib/datadog/di/base.rb +4 -4
  313. data/lib/datadog/di/boot.rb +26 -25
  314. data/lib/datadog/di/capture_expression_evaluator/result.rb +30 -0
  315. data/lib/datadog/di/capture_expression_evaluator.rb +39 -9
  316. data/lib/datadog/di/code_tracker.rb +6 -6
  317. data/lib/datadog/di/component.rb +119 -6
  318. data/lib/datadog/di/configuration.rb +54 -3
  319. data/lib/datadog/di/context.rb +7 -2
  320. data/lib/datadog/di/contrib/active_record.rb +8 -2
  321. data/lib/datadog/di/contrib/railtie.rb +1 -1
  322. data/lib/datadog/di/contrib.rb +5 -5
  323. data/lib/datadog/di/el/compiler.rb +113 -37
  324. data/lib/datadog/di/el/evaluator.rb +82 -2
  325. data/lib/datadog/di/el/expression.rb +13 -2
  326. data/lib/datadog/di/el.rb +3 -3
  327. data/lib/datadog/di/evaluation_failure.rb +28 -0
  328. data/lib/datadog/di/guardrails_telemetry/reason.rb +87 -0
  329. data/lib/datadog/di/guardrails_telemetry.rb +203 -0
  330. data/lib/datadog/di/instrumenter.rb +124 -23
  331. data/lib/datadog/di/logger.rb +32 -10
  332. data/lib/datadog/di/preload.rb +1 -1
  333. data/lib/datadog/di/probe.rb +9 -1
  334. data/lib/datadog/di/probe_builder.rb +25 -24
  335. data/lib/datadog/di/probe_file_loader/railtie.rb +1 -1
  336. data/lib/datadog/di/probe_file_loader.rb +5 -5
  337. data/lib/datadog/di/probe_manager.rb +57 -9
  338. data/lib/datadog/di/probe_notification_builder.rb +46 -43
  339. data/lib/datadog/di/probe_notifier_worker.rb +62 -12
  340. data/lib/datadog/di/probe_repository.rb +1 -1
  341. data/lib/datadog/di/proc_responder.rb +1 -1
  342. data/lib/datadog/di/remote.rb +52 -8
  343. data/lib/datadog/di/serializer.rb +185 -68
  344. data/lib/datadog/di/snapshot_event.rb +38 -0
  345. data/lib/datadog/di/transport/diagnostics.rb +5 -5
  346. data/lib/datadog/di/transport/http/diagnostics.rb +3 -3
  347. data/lib/datadog/di/transport/http/input.rb +2 -2
  348. data/lib/datadog/di/transport/http.rb +23 -13
  349. data/lib/datadog/di/transport/input.rb +41 -16
  350. data/lib/datadog/di/utils.rb +4 -4
  351. data/lib/datadog/di.rb +5 -5
  352. data/lib/datadog/error_tracking/collector.rb +2 -2
  353. data/lib/datadog/error_tracking/component.rb +12 -12
  354. data/lib/datadog/error_tracking/configuration.rb +2 -2
  355. data/lib/datadog/error_tracking/ext.rb +7 -7
  356. data/lib/datadog/error_tracking/extensions.rb +2 -2
  357. data/lib/datadog/error_tracking/filters.rb +4 -4
  358. data/lib/datadog/error_tracking.rb +6 -6
  359. data/lib/datadog/kit/appsec/events/v2.rb +40 -40
  360. data/lib/datadog/kit/appsec/events.rb +25 -25
  361. data/lib/datadog/kit/enable_core_dumps.rb +2 -2
  362. data/lib/datadog/kit/identity.rb +18 -18
  363. data/lib/datadog/kit/tracing/method_tracer.rb +7 -7
  364. data/lib/datadog/kit.rb +1 -1
  365. data/lib/datadog/open_feature/activation.rb +268 -0
  366. data/lib/datadog/open_feature/agentless/configuration_source.rb +246 -0
  367. data/lib/datadog/open_feature/agentless/parser.rb +43 -0
  368. data/lib/datadog/open_feature/agentless/response.rb +19 -0
  369. data/lib/datadog/open_feature/agentless/transport.rb +103 -0
  370. data/lib/datadog/open_feature/component.rb +112 -31
  371. data/lib/datadog/open_feature/configuration/agentless_endpoint.rb +90 -0
  372. data/lib/datadog/open_feature/configuration/source/resolution.rb +22 -0
  373. data/lib/datadog/open_feature/configuration/source.rb +43 -0
  374. data/lib/datadog/open_feature/configuration.rb +139 -2
  375. data/lib/datadog/open_feature/evaluation_engine.rb +36 -10
  376. data/lib/datadog/open_feature/exposures/batch_builder.rb +1 -1
  377. data/lib/datadog/open_feature/exposures/buffer.rb +1 -1
  378. data/lib/datadog/open_feature/exposures/deduplicator.rb +1 -1
  379. data/lib/datadog/open_feature/exposures/event.rb +17 -10
  380. data/lib/datadog/open_feature/exposures/reporter.rb +3 -3
  381. data/lib/datadog/open_feature/exposures/worker.rb +6 -6
  382. data/lib/datadog/open_feature/ext.rb +32 -8
  383. data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +242 -86
  384. data/lib/datadog/open_feature/flag_evaluation/writer.rb +211 -100
  385. data/lib/datadog/open_feature/hooks/evaluation_telemetry_opt_out_hook.rb +25 -0
  386. data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +28 -24
  387. data/lib/datadog/open_feature/hooks/flag_eval_metrics_hook.rb +3 -1
  388. data/lib/datadog/open_feature/hooks/span_enrichment_hook/codec.rb +58 -0
  389. data/lib/datadog/open_feature/hooks/span_enrichment_hook/span_enrichment_state.rb +96 -0
  390. data/lib/datadog/open_feature/hooks/span_enrichment_hook/span_enrichment_state_store.rb +49 -0
  391. data/lib/datadog/open_feature/hooks/span_enrichment_hook.rb +184 -0
  392. data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +24 -24
  393. data/lib/datadog/open_feature/native_evaluator.rb +24 -10
  394. data/lib/datadog/open_feature/noop_evaluator.rb +8 -3
  395. data/lib/datadog/open_feature/provider.rb +357 -17
  396. data/lib/datadog/open_feature/remote.rb +7 -7
  397. data/lib/datadog/open_feature/resolution_details.rb +4 -2
  398. data/lib/datadog/open_feature/transport.rb +19 -14
  399. data/lib/datadog/open_feature.rb +33 -3
  400. data/lib/datadog/opentelemetry/api/baggage.rb +3 -3
  401. data/lib/datadog/opentelemetry/api/context.rb +4 -4
  402. data/lib/datadog/opentelemetry/configuration/settings.rb +41 -41
  403. data/lib/datadog/opentelemetry/ext.rb +1 -1
  404. data/lib/datadog/opentelemetry/logs.rb +5 -5
  405. data/lib/datadog/opentelemetry/metrics.rb +7 -7
  406. data/lib/datadog/opentelemetry/sdk/configurator.rb +8 -8
  407. data/lib/datadog/opentelemetry/sdk/id_generator.rb +2 -2
  408. data/lib/datadog/opentelemetry/sdk/logs_exporter.rb +6 -6
  409. data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +5 -5
  410. data/lib/datadog/opentelemetry/sdk/propagator.rb +8 -8
  411. data/lib/datadog/opentelemetry/sdk/span_processor.rb +15 -15
  412. data/lib/datadog/opentelemetry/sdk/trace/span.rb +32 -32
  413. data/lib/datadog/opentelemetry/sdk.rb +2 -2
  414. data/lib/datadog/opentelemetry/signal_configuration.rb +20 -16
  415. data/lib/datadog/opentelemetry/trace.rb +4 -1
  416. data/lib/datadog/opentelemetry.rb +8 -8
  417. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +10 -2
  418. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +5 -7
  419. data/lib/datadog/profiling/collectors/info.rb +40 -13
  420. data/lib/datadog/profiling/collectors/thread_context.rb +6 -17
  421. data/lib/datadog/profiling/component.rb +33 -39
  422. data/lib/datadog/profiling/exporter.rb +11 -11
  423. data/lib/datadog/profiling/http_transport.rb +1 -1
  424. data/lib/datadog/profiling/sequence_tracker.rb +1 -1
  425. data/lib/datadog/profiling/tag_builder.rb +19 -19
  426. data/lib/datadog/profiling/tasks/exec.rb +1 -1
  427. data/lib/datadog/profiling.rb +31 -27
  428. data/lib/datadog/single_step_instrument.rb +1 -1
  429. data/lib/datadog/symbol_database/component.rb +15 -15
  430. data/lib/datadog/symbol_database/configuration.rb +3 -3
  431. data/lib/datadog/symbol_database/extensions.rb +2 -2
  432. data/lib/datadog/symbol_database/extractor.rb +141 -159
  433. data/lib/datadog/symbol_database/file_hash.rb +3 -3
  434. data/lib/datadog/symbol_database/logger.rb +1 -1
  435. data/lib/datadog/symbol_database/remote.rb +21 -6
  436. data/lib/datadog/symbol_database/scope.rb +2 -2
  437. data/lib/datadog/symbol_database/scope_batcher.rb +2 -2
  438. data/lib/datadog/symbol_database/service_version.rb +4 -4
  439. data/lib/datadog/symbol_database/symbol.rb +1 -1
  440. data/lib/datadog/symbol_database/transport/http/endpoint.rb +1 -1
  441. data/lib/datadog/symbol_database/transport/http.rb +6 -6
  442. data/lib/datadog/symbol_database/transport.rb +4 -4
  443. data/lib/datadog/symbol_database/uploader.rb +22 -22
  444. data/lib/datadog/symbol_database.rb +2 -2
  445. data/lib/datadog/tracing/analytics.rb +1 -1
  446. data/lib/datadog/tracing/buffer.rb +5 -5
  447. data/lib/datadog/tracing/client_ip.rb +4 -4
  448. data/lib/datadog/tracing/component.rb +51 -9
  449. data/lib/datadog/tracing/configuration/dynamic/option.rb +4 -0
  450. data/lib/datadog/tracing/configuration/dynamic.rb +13 -11
  451. data/lib/datadog/tracing/configuration/ext.rb +46 -42
  452. data/lib/datadog/tracing/configuration/http.rb +2 -2
  453. data/lib/datadog/tracing/configuration/settings.rb +52 -16
  454. data/lib/datadog/tracing/context.rb +25 -3
  455. data/lib/datadog/tracing/context_provider.rb +19 -7
  456. data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +2 -2
  457. data/lib/datadog/tracing/contrib/action_cable/event.rb +4 -4
  458. data/lib/datadog/tracing/contrib/action_cable/events/broadcast.rb +5 -5
  459. data/lib/datadog/tracing/contrib/action_cable/events/perform_action.rb +4 -4
  460. data/lib/datadog/tracing/contrib/action_cable/events/transmit.rb +5 -5
  461. data/lib/datadog/tracing/contrib/action_cable/events.rb +5 -5
  462. data/lib/datadog/tracing/contrib/action_cable/ext.rb +18 -18
  463. data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +4 -4
  464. data/lib/datadog/tracing/contrib/action_cable/integration.rb +7 -7
  465. data/lib/datadog/tracing/contrib/action_cable/patcher.rb +4 -4
  466. data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +2 -2
  467. data/lib/datadog/tracing/contrib/action_mailer/event.rb +3 -3
  468. data/lib/datadog/tracing/contrib/action_mailer/events/deliver.rb +8 -8
  469. data/lib/datadog/tracing/contrib/action_mailer/events/process.rb +4 -4
  470. data/lib/datadog/tracing/contrib/action_mailer/events.rb +3 -3
  471. data/lib/datadog/tracing/contrib/action_mailer/ext.rb +18 -18
  472. data/lib/datadog/tracing/contrib/action_mailer/integration.rb +7 -7
  473. data/lib/datadog/tracing/contrib/action_mailer/patcher.rb +3 -3
  474. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +9 -9
  475. data/lib/datadog/tracing/contrib/action_pack/action_controller/patcher.rb +2 -2
  476. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +4 -4
  477. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +4 -4
  478. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +3 -3
  479. data/lib/datadog/tracing/contrib/action_pack/ext.rb +10 -10
  480. data/lib/datadog/tracing/contrib/action_pack/integration.rb +7 -7
  481. data/lib/datadog/tracing/contrib/action_pack/patcher.rb +3 -3
  482. data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -1
  483. data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +3 -3
  484. data/lib/datadog/tracing/contrib/action_view/event.rb +1 -1
  485. data/lib/datadog/tracing/contrib/action_view/events/render_partial.rb +6 -6
  486. data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +6 -6
  487. data/lib/datadog/tracing/contrib/action_view/events.rb +3 -3
  488. data/lib/datadog/tracing/contrib/action_view/ext.rb +10 -10
  489. data/lib/datadog/tracing/contrib/action_view/integration.rb +11 -11
  490. data/lib/datadog/tracing/contrib/action_view/patcher.rb +5 -5
  491. data/lib/datadog/tracing/contrib/action_view/utils.rb +2 -2
  492. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +2 -2
  493. data/lib/datadog/tracing/contrib/active_job/data_streams.rb +2 -2
  494. data/lib/datadog/tracing/contrib/active_job/event.rb +3 -3
  495. data/lib/datadog/tracing/contrib/active_job/events/discard.rb +5 -5
  496. data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +5 -5
  497. data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +5 -5
  498. data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +5 -5
  499. data/lib/datadog/tracing/contrib/active_job/events/perform.rb +5 -5
  500. data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +5 -5
  501. data/lib/datadog/tracing/contrib/active_job/events.rb +6 -6
  502. data/lib/datadog/tracing/contrib/active_job/ext.rb +23 -23
  503. data/lib/datadog/tracing/contrib/active_job/integration.rb +7 -7
  504. data/lib/datadog/tracing/contrib/active_job/patcher.rb +7 -7
  505. data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +2 -2
  506. data/lib/datadog/tracing/contrib/active_model_serializers/event.rb +4 -4
  507. data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +6 -6
  508. data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +6 -6
  509. data/lib/datadog/tracing/contrib/active_model_serializers/events.rb +3 -3
  510. data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +10 -10
  511. data/lib/datadog/tracing/contrib/active_model_serializers/integration.rb +5 -5
  512. data/lib/datadog/tracing/contrib/active_model_serializers/patcher.rb +3 -3
  513. data/lib/datadog/tracing/contrib/active_record/configuration/makara_resolver.rb +1 -1
  514. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +7 -7
  515. data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +4 -4
  516. data/lib/datadog/tracing/contrib/active_record/event.rb +1 -1
  517. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +8 -8
  518. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +10 -9
  519. data/lib/datadog/tracing/contrib/active_record/events.rb +3 -3
  520. data/lib/datadog/tracing/contrib/active_record/ext.rb +15 -15
  521. data/lib/datadog/tracing/contrib/active_record/integration.rb +11 -11
  522. data/lib/datadog/tracing/contrib/active_record/patcher.rb +2 -2
  523. data/lib/datadog/tracing/contrib/active_record/utils.rb +3 -3
  524. data/lib/datadog/tracing/contrib/active_support/cache/event.rb +1 -1
  525. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +12 -12
  526. data/lib/datadog/tracing/contrib/active_support/cache/events.rb +1 -1
  527. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +4 -4
  528. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +5 -5
  529. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +4 -4
  530. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +3 -3
  531. data/lib/datadog/tracing/contrib/active_support/ext.rb +16 -16
  532. data/lib/datadog/tracing/contrib/active_support/integration.rb +8 -8
  533. data/lib/datadog/tracing/contrib/active_support/notifications/event.rb +1 -1
  534. data/lib/datadog/tracing/contrib/active_support/notifications/subscriber.rb +2 -2
  535. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +1 -1
  536. data/lib/datadog/tracing/contrib/active_support/patcher.rb +2 -2
  537. data/lib/datadog/tracing/contrib/analytics.rb +1 -1
  538. data/lib/datadog/tracing/contrib/auto_instrument.rb +4 -4
  539. data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +3 -3
  540. data/lib/datadog/tracing/contrib/aws/ext.rb +26 -26
  541. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +5 -5
  542. data/lib/datadog/tracing/contrib/aws/integration.rb +9 -9
  543. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +1 -1
  544. data/lib/datadog/tracing/contrib/aws/patcher.rb +5 -5
  545. data/lib/datadog/tracing/contrib/aws/service/dynamodb.rb +2 -2
  546. data/lib/datadog/tracing/contrib/aws/service/eventbridge.rb +2 -2
  547. data/lib/datadog/tracing/contrib/aws/service/kinesis.rb +4 -4
  548. data/lib/datadog/tracing/contrib/aws/service/s3.rb +2 -2
  549. data/lib/datadog/tracing/contrib/aws/service/sns.rb +3 -3
  550. data/lib/datadog/tracing/contrib/aws/service/sqs.rb +3 -3
  551. data/lib/datadog/tracing/contrib/aws/service/states.rb +5 -5
  552. data/lib/datadog/tracing/contrib/aws/services.rb +14 -14
  553. data/lib/datadog/tracing/contrib/concurrent_ruby/async_patch.rb +1 -1
  554. data/lib/datadog/tracing/contrib/concurrent_ruby/configuration/settings.rb +2 -2
  555. data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +1 -1
  556. data/lib/datadog/tracing/contrib/concurrent_ruby/ext.rb +2 -2
  557. data/lib/datadog/tracing/contrib/concurrent_ruby/future_patch.rb +1 -1
  558. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +6 -6
  559. data/lib/datadog/tracing/contrib/concurrent_ruby/patcher.rb +4 -4
  560. data/lib/datadog/tracing/contrib/concurrent_ruby/promises_future_patch.rb +1 -1
  561. data/lib/datadog/tracing/contrib/configurable.rb +2 -2
  562. data/lib/datadog/tracing/contrib/configuration/resolvers/pattern_resolver.rb +1 -1
  563. data/lib/datadog/tracing/contrib/configuration/settings.rb +2 -2
  564. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +2 -2
  565. data/lib/datadog/tracing/contrib/dalli/ext.rb +13 -13
  566. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +5 -5
  567. data/lib/datadog/tracing/contrib/dalli/integration.rb +7 -7
  568. data/lib/datadog/tracing/contrib/dalli/patcher.rb +3 -3
  569. data/lib/datadog/tracing/contrib/dalli/quantize.rb +2 -2
  570. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +2 -2
  571. data/lib/datadog/tracing/contrib/delayed_job/ext.rb +14 -14
  572. data/lib/datadog/tracing/contrib/delayed_job/integration.rb +5 -5
  573. data/lib/datadog/tracing/contrib/delayed_job/patcher.rb +3 -3
  574. data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +5 -5
  575. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +2 -2
  576. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +15 -15
  577. data/lib/datadog/tracing/contrib/elasticsearch/integration.rb +6 -6
  578. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +10 -10
  579. data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +3 -3
  580. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +2 -2
  581. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +18 -13
  582. data/lib/datadog/tracing/contrib/ethon/ext.rb +13 -13
  583. data/lib/datadog/tracing/contrib/ethon/integration.rb +6 -6
  584. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +3 -3
  585. data/lib/datadog/tracing/contrib/ethon/patcher.rb +3 -3
  586. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +5 -5
  587. data/lib/datadog/tracing/contrib/excon/ext.rb +11 -11
  588. data/lib/datadog/tracing/contrib/excon/integration.rb +6 -6
  589. data/lib/datadog/tracing/contrib/excon/middleware.rb +17 -10
  590. data/lib/datadog/tracing/contrib/excon/patcher.rb +2 -2
  591. data/lib/datadog/tracing/contrib/ext.rb +18 -18
  592. data/lib/datadog/tracing/contrib/extensions.rb +2 -2
  593. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +4 -4
  594. data/lib/datadog/tracing/contrib/faraday/ext.rb +11 -11
  595. data/lib/datadog/tracing/contrib/faraday/integration.rb +6 -6
  596. data/lib/datadog/tracing/contrib/faraday/middleware.rb +17 -11
  597. data/lib/datadog/tracing/contrib/faraday/patcher.rb +6 -6
  598. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +4 -4
  599. data/lib/datadog/tracing/contrib/grape/endpoint.rb +51 -24
  600. data/lib/datadog/tracing/contrib/grape/ext.rb +15 -15
  601. data/lib/datadog/tracing/contrib/grape/instrumentation.rb +3 -3
  602. data/lib/datadog/tracing/contrib/grape/integration.rb +5 -5
  603. data/lib/datadog/tracing/contrib/grape/patcher.rb +5 -5
  604. data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +1 -1
  605. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +3 -3
  606. data/lib/datadog/tracing/contrib/graphql/ext.rb +9 -9
  607. data/lib/datadog/tracing/contrib/graphql/integration.rb +9 -9
  608. data/lib/datadog/tracing/contrib/graphql/patcher.rb +7 -7
  609. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +37 -37
  610. data/lib/datadog/tracing/contrib/graphql/unified_trace_patcher.rb +2 -2
  611. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +2 -2
  612. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +8 -8
  613. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +8 -8
  614. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor.rb +6 -6
  615. data/lib/datadog/tracing/contrib/grpc/distributed/fetcher.rb +1 -1
  616. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +9 -9
  617. data/lib/datadog/tracing/contrib/grpc/ext.rb +14 -14
  618. data/lib/datadog/tracing/contrib/grpc/formatting.rb +7 -7
  619. data/lib/datadog/tracing/contrib/grpc/integration.rb +5 -5
  620. data/lib/datadog/tracing/contrib/grpc/intercept_with_datadog.rb +1 -1
  621. data/lib/datadog/tracing/contrib/grpc/patcher.rb +3 -3
  622. data/lib/datadog/tracing/contrib/grpc.rb +6 -6
  623. data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +3 -3
  624. data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +2 -2
  625. data/lib/datadog/tracing/contrib/hanami/ext.rb +8 -8
  626. data/lib/datadog/tracing/contrib/hanami/integration.rb +6 -6
  627. data/lib/datadog/tracing/contrib/hanami/patcher.rb +5 -5
  628. data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +3 -3
  629. data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +5 -4
  630. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +1 -1
  631. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +4 -4
  632. data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +3 -3
  633. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +8 -8
  634. data/lib/datadog/tracing/contrib/http/ext.rb +11 -11
  635. data/lib/datadog/tracing/contrib/http/instrumentation.rb +22 -7
  636. data/lib/datadog/tracing/contrib/http/integration.rb +7 -7
  637. data/lib/datadog/tracing/contrib/http/patcher.rb +3 -3
  638. data/lib/datadog/tracing/contrib/http.rb +6 -6
  639. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +4 -4
  640. data/lib/datadog/tracing/contrib/httpclient/ext.rb +11 -11
  641. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +13 -7
  642. data/lib/datadog/tracing/contrib/httpclient/integration.rb +6 -6
  643. data/lib/datadog/tracing/contrib/httpclient/patcher.rb +3 -3
  644. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +4 -4
  645. data/lib/datadog/tracing/contrib/httprb/ext.rb +11 -11
  646. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +16 -10
  647. data/lib/datadog/tracing/contrib/httprb/integration.rb +7 -7
  648. data/lib/datadog/tracing/contrib/httprb/patcher.rb +3 -3
  649. data/lib/datadog/tracing/contrib/integration.rb +3 -3
  650. data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +2 -2
  651. data/lib/datadog/tracing/contrib/kafka/event.rb +3 -3
  652. data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +7 -3
  653. data/lib/datadog/tracing/contrib/kafka/events/consumer/process_batch.rb +4 -4
  654. data/lib/datadog/tracing/contrib/kafka/events/consumer/process_message.rb +4 -4
  655. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/heartbeat.rb +5 -5
  656. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/join_group.rb +5 -5
  657. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/leave_group.rb +5 -5
  658. data/lib/datadog/tracing/contrib/kafka/events/consumer_group/sync_group.rb +5 -5
  659. data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +10 -5
  660. data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +10 -5
  661. data/lib/datadog/tracing/contrib/kafka/events.rb +10 -10
  662. data/lib/datadog/tracing/contrib/kafka/ext.rb +40 -40
  663. data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +2 -2
  664. data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +4 -4
  665. data/lib/datadog/tracing/contrib/kafka/integration.rb +6 -6
  666. data/lib/datadog/tracing/contrib/kafka/patcher.rb +5 -5
  667. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +2 -2
  668. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +9 -9
  669. data/lib/datadog/tracing/contrib/karafka/ext.rb +13 -13
  670. data/lib/datadog/tracing/contrib/karafka/integration.rb +5 -5
  671. data/lib/datadog/tracing/contrib/karafka/monitor.rb +14 -14
  672. data/lib/datadog/tracing/contrib/karafka/patcher.rb +8 -8
  673. data/lib/datadog/tracing/contrib/karafka.rb +6 -6
  674. data/lib/datadog/tracing/contrib/lograge/configuration/settings.rb +2 -2
  675. data/lib/datadog/tracing/contrib/lograge/ext.rb +1 -1
  676. data/lib/datadog/tracing/contrib/lograge/integration.rb +5 -5
  677. data/lib/datadog/tracing/contrib/lograge/patcher.rb +9 -9
  678. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +2 -2
  679. data/lib/datadog/tracing/contrib/mongodb/ext.rb +18 -18
  680. data/lib/datadog/tracing/contrib/mongodb/instrumentation.rb +3 -3
  681. data/lib/datadog/tracing/contrib/mongodb/integration.rb +7 -7
  682. data/lib/datadog/tracing/contrib/mongodb/parsers.rb +5 -5
  683. data/lib/datadog/tracing/contrib/mongodb/patcher.rb +3 -3
  684. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +13 -13
  685. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +3 -3
  686. data/lib/datadog/tracing/contrib/mysql2/ext.rb +11 -11
  687. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +6 -6
  688. data/lib/datadog/tracing/contrib/mysql2/integration.rb +5 -5
  689. data/lib/datadog/tracing/contrib/mysql2/patcher.rb +2 -2
  690. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +2 -2
  691. data/lib/datadog/tracing/contrib/opensearch/ext.rb +23 -23
  692. data/lib/datadog/tracing/contrib/opensearch/integration.rb +6 -6
  693. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +13 -13
  694. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +4 -4
  695. data/lib/datadog/tracing/contrib/patchable.rb +1 -1
  696. data/lib/datadog/tracing/contrib/patcher.rb +3 -3
  697. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +3 -3
  698. data/lib/datadog/tracing/contrib/pg/ext.rb +19 -19
  699. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +6 -6
  700. data/lib/datadog/tracing/contrib/pg/integration.rb +5 -5
  701. data/lib/datadog/tracing/contrib/pg/patcher.rb +2 -2
  702. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +2 -2
  703. data/lib/datadog/tracing/contrib/presto/ext.rb +21 -21
  704. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +2 -2
  705. data/lib/datadog/tracing/contrib/presto/integration.rb +6 -6
  706. data/lib/datadog/tracing/contrib/presto/patcher.rb +4 -4
  707. data/lib/datadog/tracing/contrib/propagation/sql_comment/comment.rb +2 -2
  708. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +17 -17
  709. data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +1 -1
  710. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +5 -5
  711. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +2 -2
  712. data/lib/datadog/tracing/contrib/que/ext.rb +19 -19
  713. data/lib/datadog/tracing/contrib/que/integration.rb +6 -6
  714. data/lib/datadog/tracing/contrib/que/patcher.rb +1 -1
  715. data/lib/datadog/tracing/contrib/que/tracer.rb +2 -2
  716. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +3 -3
  717. data/lib/datadog/tracing/contrib/racecar/event.rb +4 -4
  718. data/lib/datadog/tracing/contrib/racecar/events/batch.rb +3 -3
  719. data/lib/datadog/tracing/contrib/racecar/events/consume.rb +3 -3
  720. data/lib/datadog/tracing/contrib/racecar/events/message.rb +3 -3
  721. data/lib/datadog/tracing/contrib/racecar/events.rb +4 -4
  722. data/lib/datadog/tracing/contrib/racecar/ext.rb +18 -18
  723. data/lib/datadog/tracing/contrib/racecar/integration.rb +5 -5
  724. data/lib/datadog/tracing/contrib/racecar/patcher.rb +3 -3
  725. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +3 -3
  726. data/lib/datadog/tracing/contrib/rack/ext.rb +33 -33
  727. data/lib/datadog/tracing/contrib/rack/header_collection.rb +3 -3
  728. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +4 -4
  729. data/lib/datadog/tracing/contrib/rack/integration.rb +6 -6
  730. data/lib/datadog/tracing/contrib/rack/middlewares.rb +24 -24
  731. data/lib/datadog/tracing/contrib/rack/patcher.rb +3 -3
  732. data/lib/datadog/tracing/contrib/rack/request_queue.rb +3 -3
  733. data/lib/datadog/tracing/contrib/rack/route_inference.rb +11 -11
  734. data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +16 -16
  735. data/lib/datadog/tracing/contrib/rails/auto_instrument_railtie.rb +1 -1
  736. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +3 -3
  737. data/lib/datadog/tracing/contrib/rails/ext.rb +15 -15
  738. data/lib/datadog/tracing/contrib/rails/framework.rb +11 -11
  739. data/lib/datadog/tracing/contrib/rails/integration.rb +5 -5
  740. data/lib/datadog/tracing/contrib/rails/middlewares.rb +1 -1
  741. data/lib/datadog/tracing/contrib/rails/patcher.rb +8 -8
  742. data/lib/datadog/tracing/contrib/rails/railtie.rb +4 -4
  743. data/lib/datadog/tracing/contrib/rails/runner.rb +1 -1
  744. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +3 -3
  745. data/lib/datadog/tracing/contrib/rake/ext.rb +12 -12
  746. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +4 -4
  747. data/lib/datadog/tracing/contrib/rake/integration.rb +5 -5
  748. data/lib/datadog/tracing/contrib/rake/patcher.rb +3 -3
  749. data/lib/datadog/tracing/contrib/redis/configuration/resolver.rb +3 -3
  750. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +2 -2
  751. data/lib/datadog/tracing/contrib/redis/ext.rb +16 -16
  752. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +6 -6
  753. data/lib/datadog/tracing/contrib/redis/integration.rb +7 -7
  754. data/lib/datadog/tracing/contrib/redis/patcher.rb +10 -10
  755. data/lib/datadog/tracing/contrib/redis/quantize.rb +39 -5
  756. data/lib/datadog/tracing/contrib/redis/tags.rb +5 -5
  757. data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +14 -8
  758. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +2 -2
  759. data/lib/datadog/tracing/contrib/resque/ext.rb +7 -7
  760. data/lib/datadog/tracing/contrib/resque/integration.rb +5 -5
  761. data/lib/datadog/tracing/contrib/resque/patcher.rb +3 -3
  762. data/lib/datadog/tracing/contrib/resque/resque_job.rb +5 -5
  763. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +2 -2
  764. data/lib/datadog/tracing/contrib/rest_client/ext.rb +10 -10
  765. data/lib/datadog/tracing/contrib/rest_client/integration.rb +6 -6
  766. data/lib/datadog/tracing/contrib/rest_client/patcher.rb +2 -2
  767. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +15 -8
  768. data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +2 -2
  769. data/lib/datadog/tracing/contrib/roda/ext.rb +6 -6
  770. data/lib/datadog/tracing/contrib/roda/instrumentation.rb +4 -4
  771. data/lib/datadog/tracing/contrib/roda/integration.rb +6 -6
  772. data/lib/datadog/tracing/contrib/roda/patcher.rb +3 -3
  773. data/lib/datadog/tracing/contrib/semantic_logger/configuration/settings.rb +2 -2
  774. data/lib/datadog/tracing/contrib/semantic_logger/ext.rb +1 -1
  775. data/lib/datadog/tracing/contrib/semantic_logger/integration.rb +5 -5
  776. data/lib/datadog/tracing/contrib/semantic_logger/patcher.rb +2 -2
  777. data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +2 -2
  778. data/lib/datadog/tracing/contrib/sequel/database.rb +6 -10
  779. data/lib/datadog/tracing/contrib/sequel/dataset.rb +5 -5
  780. data/lib/datadog/tracing/contrib/sequel/ext.rb +12 -8
  781. data/lib/datadog/tracing/contrib/sequel/integration.rb +5 -5
  782. data/lib/datadog/tracing/contrib/sequel/jdbc_connection_string.rb +140 -0
  783. data/lib/datadog/tracing/contrib/sequel/patcher.rb +3 -3
  784. data/lib/datadog/tracing/contrib/sequel/utils.rb +101 -9
  785. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +2 -2
  786. data/lib/datadog/tracing/contrib/shoryuken/ext.rb +12 -12
  787. data/lib/datadog/tracing/contrib/shoryuken/integration.rb +6 -6
  788. data/lib/datadog/tracing/contrib/shoryuken/patcher.rb +1 -1
  789. data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +2 -2
  790. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +8 -8
  791. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +2 -2
  792. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +10 -10
  793. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +30 -30
  794. data/lib/datadog/tracing/contrib/sidekiq/integration.rb +7 -7
  795. data/lib/datadog/tracing/contrib/sidekiq/patcher.rb +8 -8
  796. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +13 -13
  797. data/lib/datadog/tracing/contrib/sidekiq/utils.rb +9 -9
  798. data/lib/datadog/tracing/contrib/sidekiq.rb +6 -6
  799. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +3 -3
  800. data/lib/datadog/tracing/contrib/sinatra/env.rb +6 -6
  801. data/lib/datadog/tracing/contrib/sinatra/ext.rb +17 -17
  802. data/lib/datadog/tracing/contrib/sinatra/framework.rb +1 -1
  803. data/lib/datadog/tracing/contrib/sinatra/integration.rb +5 -5
  804. data/lib/datadog/tracing/contrib/sinatra/patcher.rb +5 -5
  805. data/lib/datadog/tracing/contrib/sinatra/tracer.rb +10 -10
  806. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +8 -8
  807. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +1 -1
  808. data/lib/datadog/tracing/contrib/sneakers/ext.rb +12 -12
  809. data/lib/datadog/tracing/contrib/sneakers/integration.rb +7 -7
  810. data/lib/datadog/tracing/contrib/sneakers/patcher.rb +2 -2
  811. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +4 -4
  812. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +2 -2
  813. data/lib/datadog/tracing/contrib/status_range_env_parser.rb +2 -2
  814. data/lib/datadog/tracing/contrib/status_range_matcher.rb +1 -1
  815. data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +2 -2
  816. data/lib/datadog/tracing/contrib/stripe/ext.rb +12 -12
  817. data/lib/datadog/tracing/contrib/stripe/integration.rb +5 -5
  818. data/lib/datadog/tracing/contrib/stripe/patcher.rb +2 -2
  819. data/lib/datadog/tracing/contrib/stripe/request.rb +3 -3
  820. data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +2 -2
  821. data/lib/datadog/tracing/contrib/sucker_punch/exception_handler.rb +1 -1
  822. data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +13 -13
  823. data/lib/datadog/tracing/contrib/sucker_punch/instrumentation.rb +4 -4
  824. data/lib/datadog/tracing/contrib/sucker_punch/integration.rb +5 -5
  825. data/lib/datadog/tracing/contrib/sucker_punch/patcher.rb +4 -4
  826. data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +3 -3
  827. data/lib/datadog/tracing/contrib/trilogy/ext.rb +11 -11
  828. data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +6 -6
  829. data/lib/datadog/tracing/contrib/trilogy/integration.rb +5 -5
  830. data/lib/datadog/tracing/contrib/trilogy/patcher.rb +2 -2
  831. data/lib/datadog/tracing/contrib/utils/database.rb +5 -5
  832. data/lib/datadog/tracing/contrib/utils/quantization/hash_formatter.rb +2 -2
  833. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +118 -13
  834. data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +2 -2
  835. data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +9 -9
  836. data/lib/datadog/tracing/contrib/waterdrop/ext.rb +4 -4
  837. data/lib/datadog/tracing/contrib/waterdrop/integration.rb +5 -5
  838. data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +2 -2
  839. data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +7 -7
  840. data/lib/datadog/tracing/contrib/waterdrop/producer.rb +3 -3
  841. data/lib/datadog/tracing/contrib/waterdrop.rb +6 -6
  842. data/lib/datadog/tracing/contrib.rb +54 -54
  843. data/lib/datadog/tracing/correlation.rb +12 -12
  844. data/lib/datadog/tracing/diagnostics/environment_logger.rb +12 -11
  845. data/lib/datadog/tracing/diagnostics/ext.rb +19 -19
  846. data/lib/datadog/tracing/diagnostics/health.rb +1 -1
  847. data/lib/datadog/tracing/distributed/b3_multi.rb +8 -8
  848. data/lib/datadog/tracing/distributed/b3_single.rb +4 -4
  849. data/lib/datadog/tracing/distributed/baggage.rb +27 -29
  850. data/lib/datadog/tracing/distributed/datadog.rb +23 -23
  851. data/lib/datadog/tracing/distributed/fetcher.rb +1 -1
  852. data/lib/datadog/tracing/distributed/helpers.rb +3 -3
  853. data/lib/datadog/tracing/distributed/propagation.rb +15 -12
  854. data/lib/datadog/tracing/distributed/propagation_policy.rb +5 -0
  855. data/lib/datadog/tracing/distributed/trace_context.rb +21 -278
  856. data/lib/datadog/tracing/distributed/trace_state/datadog.rb +233 -0
  857. data/lib/datadog/tracing/distributed/trace_state/ext.rb +44 -0
  858. data/lib/datadog/tracing/distributed/trace_state/open_telemetry.rb +156 -0
  859. data/lib/datadog/tracing/distributed/trace_state.rb +121 -0
  860. data/lib/datadog/tracing/event.rb +1 -1
  861. data/lib/datadog/tracing/ext.rb +1 -1
  862. data/lib/datadog/tracing/metadata/analytics.rb +2 -2
  863. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  864. data/lib/datadog/tracing/metadata/ext.rb +72 -69
  865. data/lib/datadog/tracing/metadata/metastruct.rb +1 -1
  866. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +1 -1
  867. data/lib/datadog/tracing/metadata/tagging.rb +3 -3
  868. data/lib/datadog/tracing/metadata.rb +4 -4
  869. data/lib/datadog/tracing/otel_thread_context.rb +97 -0
  870. data/lib/datadog/tracing/pipeline/span_filter.rb +2 -2
  871. data/lib/datadog/tracing/pipeline.rb +2 -2
  872. data/lib/datadog/tracing/remote.rb +250 -44
  873. data/lib/datadog/tracing/sampling/all_sampler.rb +1 -1
  874. data/lib/datadog/tracing/sampling/ext.rb +8 -8
  875. data/lib/datadog/tracing/sampling/matcher.rb +4 -4
  876. data/lib/datadog/tracing/sampling/priority_sampler.rb +4 -4
  877. data/lib/datadog/tracing/sampling/rate_by_key_sampler.rb +3 -3
  878. data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +2 -2
  879. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -2
  880. data/lib/datadog/tracing/sampling/rule.rb +4 -4
  881. data/lib/datadog/tracing/sampling/rule_sampler.rb +14 -12
  882. data/lib/datadog/tracing/sampling/sampler.rb +2 -2
  883. data/lib/datadog/tracing/sampling/span/ext.rb +3 -3
  884. data/lib/datadog/tracing/sampling/span/matcher.rb +2 -2
  885. data/lib/datadog/tracing/sampling/span/rule.rb +1 -1
  886. data/lib/datadog/tracing/sampling/span/rule_parser.rb +8 -8
  887. data/lib/datadog/tracing/span.rb +9 -9
  888. data/lib/datadog/tracing/span_event.rb +5 -5
  889. data/lib/datadog/tracing/span_operation.rb +22 -22
  890. data/lib/datadog/tracing/sync_writer.rb +12 -7
  891. data/lib/datadog/tracing/trace_digest.rb +22 -4
  892. data/lib/datadog/tracing/trace_operation.rb +33 -21
  893. data/lib/datadog/tracing/trace_segment.rb +10 -10
  894. data/lib/datadog/tracing/tracer.rb +43 -22
  895. data/lib/datadog/tracing/transport/http/client.rb +4 -4
  896. data/lib/datadog/tracing/transport/http/statistics.rb +2 -2
  897. data/lib/datadog/tracing/transport/http/telemetry.rb +94 -0
  898. data/lib/datadog/tracing/transport/http/traces.rb +10 -8
  899. data/lib/datadog/tracing/transport/http.rb +10 -10
  900. data/lib/datadog/tracing/transport/io/client.rb +2 -2
  901. data/lib/datadog/tracing/transport/io/response.rb +1 -1
  902. data/lib/datadog/tracing/transport/io/traces.rb +5 -5
  903. data/lib/datadog/tracing/transport/io.rb +3 -3
  904. data/lib/datadog/tracing/transport/native/response.rb +71 -0
  905. data/lib/datadog/tracing/transport/native/telemetry.rb +17 -0
  906. data/lib/datadog/tracing/transport/native.rb +395 -0
  907. data/lib/datadog/tracing/transport/serializable_trace.rb +19 -19
  908. data/lib/datadog/tracing/transport/span_events_negotiation.rb +41 -0
  909. data/lib/datadog/tracing/transport/statistics.rb +2 -2
  910. data/lib/datadog/tracing/transport/telemetry.rb +62 -0
  911. data/lib/datadog/tracing/transport/trace_formatter.rb +23 -13
  912. data/lib/datadog/tracing/transport/traces.rb +93 -46
  913. data/lib/datadog/tracing/utils.rb +2 -2
  914. data/lib/datadog/tracing/workers.rb +2 -2
  915. data/lib/datadog/tracing/writer.rb +22 -9
  916. data/lib/datadog/tracing.rb +3 -3
  917. data/lib/datadog/version.rb +4 -4
  918. data/lib/datadog.rb +13 -13
  919. metadata +55 -13
  920. data/lib/datadog/ai_guard/evaluation/content_builder.rb +0 -31
  921. data/lib/datadog/appsec/utils/hash_coercion.rb +0 -23
  922. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +0 -69
@@ -3,17 +3,10 @@
3
3
  #include <ruby/st.h>
4
4
  #include <stdatomic.h>
5
5
 
6
- #include "extconf.h" // This is needed for the HAVE_DLADDR and friends below
7
-
8
- #if (defined(HAVE_DLADDR1) && HAVE_DLADDR1) || (defined(HAVE_DLADDR) && HAVE_DLADDR)
9
- #ifndef _GNU_SOURCE
10
- #define _GNU_SOURCE
11
- #endif
12
- #include <dlfcn.h>
13
- #if defined(HAVE_DLADDR1) && HAVE_DLADDR1
14
- #include <link.h>
15
- #endif
6
+ #ifndef _GNU_SOURCE
7
+ #define _GNU_SOURCE // Needed for dlfcn.h/dladdr
16
8
  #endif
9
+ #include <dlfcn.h>
17
10
 
18
11
  #include "datadog_ruby_common.h"
19
12
  #include "private_vm_api_access.h"
@@ -21,11 +14,16 @@
21
14
  #include "stack_recorder.h"
22
15
  #include "collectors_stack.h"
23
16
 
17
+ // An estimation of how much bytes we need on average for qualified method names.
18
+ // This is an "average" and not a "max" because frames can use more than that,
19
+ // we just fall back to unqualified method names if the buffer is full.
20
+ #define QUALIFIED_NAME_AVG_SIZE 64
21
+
24
22
  // Gathers stack traces from running threads, storing them in a StackRecorder instance
25
23
  // This file implements the native bits of the Datadog::Profiling::Collectors::Stack class
26
24
 
27
- static VALUE _native_filenames_available(DDTRACE_UNUSED VALUE self);
28
25
  static VALUE _native_ruby_native_filename(DDTRACE_UNUSED VALUE self);
26
+ static VALUE _native_set_file_info_for_cfunc(DDTRACE_UNUSED VALUE self, VALUE new_static_ruby_actual_filename);
29
27
  static VALUE _native_sample(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self);
30
28
  static VALUE native_sample_do(VALUE args);
31
29
  static VALUE native_sample_ensure(VALUE args);
@@ -40,56 +38,51 @@ static void set_file_info_for_cfunc(
40
38
  st_table *native_filenames_cache
41
39
  );
42
40
  static const char *get_or_compute_native_filename(void *function, st_table *native_filenames_cache);
41
+ static void initialize_static_ruby_actual_filename(VALUE profiling_module);
43
42
  static void add_truncated_frames_placeholder(ddog_prof_Location *locations);
44
43
  static void record_placeholder_stack_in_native_code(VALUE recorder_instance, sample_values values, sample_labels labels);
45
- static void maybe_trim_template_random_ids(ddog_CharSlice *name_slice, ddog_CharSlice *filename_slice);
46
-
47
- // These two functions are exposed as symbols by the VM but are not in any header.
48
- // Their signatures actually take a `const rb_iseq_t *iseq` but it gets casted back and forth between VALUE.
49
- extern VALUE rb_iseq_path(const VALUE);
50
- extern VALUE rb_iseq_base_label(const VALUE);
44
+ static void maybe_trim_template_random_ids(ddog_CharSlice *frame_name, ddog_CharSlice method_name, ddog_CharSlice filename);
51
45
 
52
- // NULL if dladdr is not available or we weren't able to get the native filename for the Ruby VM
46
+ // NULL if we weren't able to get the native filename for the Ruby VM.
47
+ // On a static Ruby without libruby.so, `get_or_compute_native_filename` returns `ruby_native_filename` but
48
+ // `static_ruby_actual_filename` (below) is what we want to show instead.
53
49
  static const char *ruby_native_filename = NULL;
50
+ // Qnil unless we're running on a static Ruby
51
+ static VALUE static_ruby_actual_filename = Qnil;
54
52
 
55
53
  void collectors_stack_init(VALUE profiling_module) {
56
54
  VALUE collectors_module = rb_define_module_under(profiling_module, "Collectors");
57
55
  VALUE collectors_stack_class = rb_define_class_under(collectors_module, "Stack", rb_cObject);
58
56
 
59
- rb_define_singleton_method(collectors_stack_class, "_native_filenames_available?", _native_filenames_available, 0);
60
57
  rb_define_singleton_method(collectors_stack_class, "_native_ruby_native_filename", _native_ruby_native_filename, 0);
61
58
 
62
59
  // Hosts methods used for testing the native code using RSpec
63
60
  VALUE testing_module = rb_define_module_under(collectors_stack_class, "Testing");
64
61
 
65
62
  rb_define_singleton_method(testing_module, "_native_sample", _native_sample, -1);
63
+ rb_define_singleton_method(testing_module, "_native_set_file_info_for_cfunc", _native_set_file_info_for_cfunc, 1);
66
64
 
67
- #if (defined(HAVE_DLADDR1) && HAVE_DLADDR1) || (defined(HAVE_DLADDR) && HAVE_DLADDR)
68
- // To be able to detect when a frame is coming from Ruby, we record here its filename as returned by dladdr.
69
- // We expect this same pointer to be returned by dladdr for all frames coming from Ruby.
70
- //
71
- // Small note: Creating/deleting the cache is a bit awkward here, but it seems like a bigger footgun to allow
72
- // `get_or_compute_native_filename` to run without a cache, since we never expect that to happen during sampling. So it seems
73
- // like a reasonable trade-off to force callers to always figure that out.
74
- st_table *temporary_cache = st_init_numtable();
75
- const char *native_filename = get_or_compute_native_filename(rb_ary_new, temporary_cache);
76
- if (native_filename != NULL && native_filename[0] != '\0') {
77
- ruby_native_filename = native_filename;
78
- }
79
- st_free_table(temporary_cache);
80
- #endif
81
- }
82
-
83
- static VALUE _native_filenames_available(DDTRACE_UNUSED VALUE self) {
84
- #if (defined(HAVE_DLADDR1) && HAVE_DLADDR1) || (defined(HAVE_DLADDR) && HAVE_DLADDR)
85
- return ruby_native_filename != NULL ? Qtrue : Qfalse;
86
- #else
87
- return Qfalse;
88
- #endif
65
+ // To be able to detect when a frame is coming from Ruby, we record here its filename as returned by dladdr.
66
+ // We expect this same pointer to be returned by dladdr for all frames coming from Ruby.
67
+ //
68
+ // Small note: Creating/deleting the cache is a bit awkward here, but it seems like a bigger footgun to allow
69
+ // `get_or_compute_native_filename` to run without a cache, since we never expect that to happen during sampling. So it seems
70
+ // like a reasonable trade-off to force callers to always figure that out.
71
+ st_table *temporary_cache = st_init_numtable();
72
+ const char *native_filename = get_or_compute_native_filename(rb_ary_new, temporary_cache);
73
+ if (native_filename[0] != '\0') {
74
+ ruby_native_filename = native_filename;
75
+ initialize_static_ruby_actual_filename(profiling_module);
76
+ }
77
+ st_free_table(temporary_cache);
89
78
  }
90
79
 
91
80
  static VALUE _native_ruby_native_filename(DDTRACE_UNUSED VALUE self) {
92
- return ruby_native_filename != NULL ? rb_utf8_str_new_cstr(ruby_native_filename) : Qnil;
81
+ if (static_ruby_actual_filename != Qnil) {
82
+ return static_ruby_actual_filename;
83
+ } else {
84
+ return ruby_native_filename != NULL ? rb_utf8_str_new_cstr(ruby_native_filename) : Qnil;
85
+ }
93
86
  }
94
87
 
95
88
  typedef struct {
@@ -102,6 +95,7 @@ typedef struct {
102
95
  sampling_buffer *buffer;
103
96
  bool native_filenames_enabled;
104
97
  st_table *native_filenames_cache;
98
+ bool show_classes;
105
99
  } native_sample_args;
106
100
 
107
101
  // This method exists only to enable testing Datadog::Profiling::Collectors::Stack behavior using RSpec.
@@ -124,6 +118,7 @@ static VALUE _native_sample(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self) {
124
118
  VALUE in_gc = rb_hash_lookup2(options, ID2SYM(rb_intern("in_gc")), Qfalse);
125
119
  VALUE is_gvl_waiting_state = rb_hash_lookup2(options, ID2SYM(rb_intern("is_gvl_waiting_state")), Qfalse);
126
120
  VALUE native_filenames_enabled = rb_hash_lookup2(options, ID2SYM(rb_intern("native_filenames_enabled")), Qfalse);
121
+ VALUE show_classes = rb_hash_lookup2(options, ID2SYM(rb_intern("show_classes")), Qtrue);
127
122
 
128
123
  ENFORCE_TYPE(metric_values_hash, T_HASH);
129
124
  ENFORCE_TYPE(labels_array, T_ARRAY);
@@ -132,10 +127,19 @@ static VALUE _native_sample(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self) {
132
127
  ENFORCE_BOOLEAN(in_gc);
133
128
  ENFORCE_BOOLEAN(is_gvl_waiting_state);
134
129
  ENFORCE_BOOLEAN(native_filenames_enabled);
130
+ ENFORCE_BOOLEAN(show_classes);
135
131
 
136
132
  VALUE zero = INT2NUM(0);
137
- VALUE heap_sample = rb_hash_lookup2(metric_values_hash, rb_str_new_cstr("heap_sample"), Qfalse);
138
- ENFORCE_BOOLEAN(heap_sample);
133
+ // Pass `heap_sample: {new_object: ..., alloc_class: ...}` to also record this sample for heap profiling
134
+ VALUE heap_sample_options = rb_hash_lookup2(options, ID2SYM(rb_intern("heap_sample")), Qnil);
135
+ heap_sample_values heap_sample = {};
136
+ if (heap_sample_options != Qnil) {
137
+ ENFORCE_TYPE(heap_sample_options, T_HASH);
138
+ heap_sample.new_object = rb_hash_fetch(heap_sample_options, ID2SYM(rb_intern("new_object")));
139
+ heap_sample.alloc_class =
140
+ char_slice_from_ruby_string(rb_hash_fetch(heap_sample_options, ID2SYM(rb_intern("alloc_class"))));
141
+ }
142
+
139
143
  sample_values values = {
140
144
  .cpu_time_ns = NUM2UINT(rb_hash_lookup2(metric_values_hash, rb_str_new_cstr("cpu-time"), zero)),
141
145
  .cpu_or_wall_samples = NUM2UINT(rb_hash_lookup2(metric_values_hash, rb_str_new_cstr("cpu-samples"), zero)),
@@ -143,7 +147,7 @@ static VALUE _native_sample(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self) {
143
147
  .alloc_samples = NUM2UINT(rb_hash_lookup2(metric_values_hash, rb_str_new_cstr("alloc-samples"), zero)),
144
148
  .alloc_samples_unscaled = NUM2UINT(rb_hash_lookup2(metric_values_hash, rb_str_new_cstr("alloc-samples-unscaled"), zero)),
145
149
  .timeline_wall_time_ns = NUM2UINT(rb_hash_lookup2(metric_values_hash, rb_str_new_cstr("timeline"), zero)),
146
- .heap_sample = heap_sample == Qtrue,
150
+ .heap_sample = heap_sample_options != Qnil ? &heap_sample : NULL,
147
151
  };
148
152
 
149
153
  long labels_count = RARRAY_LEN(labels_array) + RARRAY_LEN(numeric_labels_array);
@@ -173,7 +177,8 @@ static VALUE _native_sample(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self) {
173
177
 
174
178
  int max_frames_requested = sampling_buffer_check_max_frames(NUM2INT(max_frames));
175
179
 
176
- ddog_prof_Location *locations = ruby_xcalloc(max_frames_requested, sizeof(ddog_prof_Location));
180
+ sample_locations locations;
181
+ sample_locations_initialize(&locations, max_frames_requested, show_classes == Qtrue);
177
182
  sampling_buffer buffer;
178
183
  sampling_buffer_initialize(&buffer, max_frames_requested);
179
184
 
@@ -185,10 +190,11 @@ static VALUE _native_sample(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self) {
185
190
  .values = values,
186
191
  .labels = (sample_labels) {.labels = slice_labels, .state_label = state_label, .is_gvl_waiting_state = is_gvl_waiting_state == Qtrue},
187
192
  .thread = thread,
188
- .locations = (sample_locations) {.ptr = locations, .len = max_frames_requested},
193
+ .locations = locations,
189
194
  .buffer = &buffer,
190
195
  .native_filenames_enabled = native_filenames_enabled == Qtrue,
191
196
  .native_filenames_cache = st_init_numtable(),
197
+ .show_classes = show_classes == Qtrue,
192
198
  };
193
199
 
194
200
  return rb_ensure(native_sample_do, (VALUE) &args_struct, native_sample_ensure, (VALUE) &args_struct);
@@ -213,7 +219,8 @@ static VALUE native_sample_do(VALUE args) {
213
219
  args_struct->values,
214
220
  args_struct->labels,
215
221
  args_struct->native_filenames_enabled,
216
- args_struct->native_filenames_cache
222
+ args_struct->native_filenames_cache,
223
+ args_struct->show_classes
217
224
  );
218
225
  }
219
226
 
@@ -223,7 +230,7 @@ static VALUE native_sample_do(VALUE args) {
223
230
  static VALUE native_sample_ensure(VALUE args) {
224
231
  native_sample_args *args_struct = (native_sample_args *) args;
225
232
 
226
- ruby_xfree(args_struct->locations.ptr);
233
+ sample_locations_free(&args_struct->locations);
227
234
  sampling_buffer_free(args_struct->buffer);
228
235
  st_free_table(args_struct->native_filenames_cache);
229
236
 
@@ -249,7 +256,8 @@ void sample_thread(
249
256
  sample_values values,
250
257
  sample_labels labels,
251
258
  bool native_filenames_enabled,
252
- st_table *native_filenames_cache
259
+ st_table *native_filenames_cache,
260
+ bool show_classes
253
261
  ) {
254
262
  if (buffer->max_frames != locations.len) {
255
263
  // This shouldn't happen as thread_context_collector_reset_all_per_thread_contexts (which resizes every
@@ -268,11 +276,13 @@ void sample_thread(
268
276
  prepare_sample_thread(thread, buffer);
269
277
  }
270
278
 
271
- buffer->pending_sample = false;
272
279
  int captured_frames = buffer->pending_sample_result;
273
280
 
274
281
  if (captured_frames == PLACEHOLDER_STACK_IN_NATIVE_CODE) {
275
282
  record_placeholder_stack_in_native_code(recorder_instance, values, labels);
283
+
284
+ // Done reading from the buffer -- allow GC to stop marking it.
285
+ buffer->pending_sample = false;
276
286
  return;
277
287
  }
278
288
 
@@ -309,45 +319,58 @@ void sample_thread(
309
319
  }
310
320
 
311
321
  int top_of_stack_position = captured_frames - 1;
322
+ char *qualified_name_buf = locations.qualified_name_buf;
323
+ size_t qualified_name_buf_size = locations.qualified_name_buf_size;
312
324
 
313
325
  for (int i = 0; i <= top_of_stack_position; i++) {
314
- ddog_CharSlice name_slice, filename_slice;
326
+ ddog_CharSlice filename_slice;
315
327
  int line;
316
328
  bool top_of_the_stack = i == top_of_stack_position;
317
329
 
318
- if (buffer->stack_buffer[i].is_ruby_frame) {
319
- VALUE iseq = buffer->stack_buffer[i].as.ruby_frame.iseq;
320
- VALUE name = rb_iseq_base_label(iseq);
321
- VALUE filename =
322
- // Note: We saw crash reports from a customer from dereferencing a null pointer inside `rb_iseq_path`.
323
- // It's not clear in what situation would the pathobj ever be NULL, yet it seems harmless from our side to
324
- // skip this information if we're ever in such a situation.
325
- pathobj_is_null(iseq) ? Qnil : rb_iseq_path(iseq);
326
-
327
- name_slice = NIL_P(name) ? DDOG_CHARSLICE_C("") : char_slice_from_ruby_string(name);
328
- filename_slice = NIL_P(filename) ? DDOG_CHARSLICE_C("") : char_slice_from_ruby_string(filename);
329
- line = buffer->stack_buffer[i].as.ruby_frame.line;
330
+ frame_info frame = buffer->stack_buffer[i];
331
+ const rb_callable_method_entry_t *cme = frame.cme;
332
+ const rb_iseq_t* iseq;
333
+ if (frame.is_ruby_frame) {
334
+ iseq = frame.as.ruby_frame.iseq;
335
+
336
+ VALUE filename = ddtrace_iseq_path(iseq);
337
+ filename_slice = char_slice_from_ruby_string(filename);
338
+ line = frame.as.ruby_frame.line;
330
339
 
331
340
  last_ruby_frame_filename = filename_slice;
332
341
  last_ruby_line = line;
333
342
  } else {
334
- VALUE name = rb_id2str(buffer->stack_buffer[i].as.native_frame.method_id);
335
-
336
- name_slice = NIL_P(name) ? DDOG_CHARSLICE_C("") : char_slice_from_ruby_string(name);
343
+ iseq = NULL;
337
344
 
338
345
  set_file_info_for_cfunc(
339
346
  &filename_slice,
340
347
  &line,
341
348
  last_ruby_frame_filename,
342
349
  last_ruby_line,
343
- buffer->stack_buffer[i].as.native_frame.function,
350
+ ddtrace_cme_cfunc_func(cme),
344
351
  top_of_the_stack,
345
352
  native_filenames_enabled,
346
353
  native_filenames_cache
347
354
  );
348
355
  }
349
356
 
350
- maybe_trim_template_random_ids(&name_slice, &filename_slice);
357
+ VALUE name = ddtrace_location_base_label(cme, iseq);
358
+ // TODO: name_slice is currently the unqualified method name
359
+ // because we don't always use qualified method names yet, so we don't always compute it,
360
+ // and checks below need to compare to something stable until we always qualified method names.
361
+ ddog_CharSlice name_slice = (name == Qfalse) ? DDOG_CHARSLICE_C("") : char_slice_from_ruby_string(name);
362
+
363
+ ddog_CharSlice qualified_name = DDOG_CHARSLICE_C("");
364
+ if (show_classes) {
365
+ ssize_t written = ddtrace_location_label(cme, iseq, qualified_name_buf, qualified_name_buf_size);
366
+ if (written > 0) {
367
+ qualified_name = (ddog_CharSlice) {.ptr = qualified_name_buf, .len = written};
368
+ qualified_name_buf += written;
369
+ qualified_name_buf_size -= written;
370
+ } else {
371
+ qualified_name = name_slice; // just the method name
372
+ }
373
+ }
351
374
 
352
375
  // When there's only wall-time in a sample, this means that the thread was not active in the sampled period.
353
376
  if (top_of_the_stack && only_wall_time) {
@@ -358,7 +381,7 @@ void sample_thread(
358
381
  // Otherwise, we try to categorize what the thread was doing based on what we observe at the top of the stack. This is a very rough
359
382
  // approximation, and in the future we hope to replace this with a more accurate approach (such as using the
360
383
  // GVL instrumentation API.)
361
- } else if (!buffer->stack_buffer[i].is_ruby_frame) {
384
+ } else if (!frame.is_ruby_frame) {
362
385
  // We know that known versions of Ruby implement these using native code; thus if we find a method with the
363
386
  // same name that is not native code, we ignore it, as it's probably a user method that coincidentally
364
387
  // has the same name. Thus, even though "matching just by method name" is kinda weak,
@@ -408,11 +431,20 @@ void sample_thread(
408
431
  }
409
432
  }
410
433
 
434
+ ddog_CharSlice frame_name;
435
+ if (show_classes) {
436
+ frame_name = qualified_name;
437
+ } else {
438
+ frame_name = name_slice;
439
+ }
440
+
441
+ maybe_trim_template_random_ids(&frame_name, name_slice, filename_slice);
442
+
411
443
  int libdatadog_stores_stacks_flipped_from_rb_profile_frames_index = top_of_stack_position - i;
412
444
 
413
445
  locations.ptr[libdatadog_stores_stacks_flipped_from_rb_profile_frames_index] = (ddog_prof_Location) {
414
446
  .mapping = {.filename = DDOG_CHARSLICE_C(""), .build_id = DDOG_CHARSLICE_C(""), .build_id_id = {}},
415
- .function = (ddog_prof_Function) {.name = name_slice, .filename = filename_slice},
447
+ .function = (ddog_prof_Function) {.name = frame_name, .filename = filename_slice},
416
448
  .line = line,
417
449
  };
418
450
  }
@@ -429,95 +461,81 @@ void sample_thread(
429
461
  values,
430
462
  labels
431
463
  );
464
+
465
+ // Done reading from the buffer -- allow GC to stop marking it.
466
+ // This needs to be done last in this function in case anything above triggers a GC
467
+ // (remember that `ruby_xmalloc` for instance can do that too...)
468
+ buffer->pending_sample = false;
432
469
  }
433
470
 
434
- #if (defined(HAVE_DLADDR1) && HAVE_DLADDR1) || (defined(HAVE_DLADDR) && HAVE_DLADDR)
435
- static void set_file_info_for_cfunc(
436
- ddog_CharSlice *filename_slice,
437
- int *line,
438
- ddog_CharSlice last_ruby_frame_filename,
439
- int last_ruby_line,
440
- void *function,
441
- bool top_of_the_stack,
442
- bool native_filenames_enabled,
443
- st_table *native_filenames_cache
444
- ) {
445
- if (native_filenames_enabled) {
446
- const char *native_filename = get_or_compute_native_filename(function, native_filenames_cache);
447
- if (native_filename && native_filename[0] != '\0' &&
448
- // Using the ruby_native_filename at the top of the stack has a weird effect on the "top methods" table because
449
- // e.g. we don't have classnames for methods. This is especially visible in the allocations profile, e.g.
450
- // what a surprise, you're telling me "libruby.so:new" is the top method always?
451
- //
452
- // Until we have a better way of dealing with that, we don't do this replacement for the top frame.
453
- //
454
- // Also, dladdr is expected to always return the same pointer to the ruby_native_filename, so that's why we're
455
- // comparing only pointer values and not the string contents.
456
- (native_filename != ruby_native_filename || !top_of_the_stack)
457
- ) {
471
+ static void set_file_info_for_cfunc(
472
+ ddog_CharSlice *filename_slice,
473
+ int *line,
474
+ ddog_CharSlice last_ruby_frame_filename,
475
+ int last_ruby_line,
476
+ void *function,
477
+ bool top_of_the_stack,
478
+ bool native_filenames_enabled,
479
+ st_table *native_filenames_cache
480
+ ) {
481
+ if (native_filenames_enabled) {
482
+ const char *native_filename = get_or_compute_native_filename(function, native_filenames_cache);
483
+ if (native_filename[0] != '\0' &&
484
+ // TODO: Using the ruby_native_filename at the top of the stack has a weird effect on the "top methods" table because
485
+ // e.g. we don't have classnames for methods. This is especially visible in the allocations profile, e.g.
486
+ // what a surprise, you're telling me "libruby.so:new" is the top method always?
487
+ // Until we have a better way of dealing with that, we don't do this replacement for the top frame.
488
+ // (Bonus TODO note: This might be fixed by using full class/module names in frames?)
489
+ //
490
+ // dladdr is expected to always return the same pointer to the ruby_native_filename, so that's why we're
491
+ // comparing only pointer values and not the string contents.
492
+ (native_filename != ruby_native_filename || !top_of_the_stack)
493
+ ) {
494
+ // On a static Ruby without libruby.so, we show `static_ruby_actual_filename` instead of `ruby_native_filename`
495
+ if (native_filename == ruby_native_filename && static_ruby_actual_filename != Qnil) {
496
+ *filename_slice = char_slice_from_ruby_string(static_ruby_actual_filename);
497
+ } else {
458
498
  *filename_slice = (ddog_CharSlice) {.ptr = native_filename, .len = strlen(native_filename)};
459
- // Explicitly set the line to 0 as it has no meaning on a native library (e.g. an .so is built of many source files)
460
- // and anyway often that debug info is not available.
461
- *line = 0;
462
- return;
463
499
  }
500
+ // Explicitly set the line to 0 as it has no meaning on a native library (e.g. an .so is built of many source files)
501
+ // and anyway often that debug info is not available.
502
+ *line = 0;
503
+ return;
464
504
  }
465
-
466
- *filename_slice = last_ruby_frame_filename;
467
- *line = last_ruby_line;
468
505
  }
469
506
 
470
- // `native_filenames_cache` is used to cache native filename lookup results (Map[void *function_pointer, char *filename])
471
- //
472
- // Caching this information is safe because there's no API in Ruby to "unrequire" a native extension. Thus, if we see a
473
- // frame on the **Ruby** stack with a given `function`, then that `function` was registered with the Ruby VM and
474
- // belongs to a Ruby extension, so a lot of other bad things would happen if it was dlclosed.
475
- static const char *get_or_compute_native_filename(void *function, st_table *native_filenames_cache) {
476
- const char *cached_filename = NULL;
477
- st_lookup(native_filenames_cache, (st_data_t) function, (st_data_t *) &cached_filename);
478
- if (cached_filename != NULL) return cached_filename;
479
-
480
- Dl_info info;
481
- const char *native_filename = NULL;
482
- #if defined(HAVE_DLADDR1) && HAVE_DLADDR1
483
- struct link_map *extra_info = NULL;
484
- if (dladdr1(function, &info, (void **) &extra_info, RTLD_DL_LINKMAP) != 0 && extra_info != NULL) {
485
- native_filename = extra_info->l_name != NULL ? extra_info->l_name : info.dli_fname;
486
- }
487
- #elif defined(HAVE_DLADDR) && HAVE_DLADDR
488
- if (dladdr(function, &info) != 0) {
489
- native_filename = info.dli_fname;
490
- }
491
- #endif
492
-
493
- // We explicitly use an empty string here so as to cache lookups that somehow "failed". Otherwise we would keep trying them every time.
494
- if (native_filename == NULL) native_filename = "";
495
-
496
- // An st_table is what Ruby uses for its own hashtables. This allows us to get an easy estimate of the size of the cache:
497
- // `ObjectSpace.memsize_of((0..100000).map { |it| [it, nil] }.to_h)` => 4194400 bytes as of Ruby 3.2 so that seems reasonable?
498
- // Note: `st_table_size()` is available from Ruby 3.2+ but not before
499
- if (native_filenames_cache->num_entries >= 100000) {
500
- st_clear(native_filenames_cache);
501
- }
507
+ *filename_slice = last_ruby_frame_filename;
508
+ *line = last_ruby_line;
509
+ }
502
510
 
503
- st_insert(native_filenames_cache, (st_data_t) function, (st_data_t) native_filename);
504
- return native_filename;
505
- }
506
- #else
507
- static void set_file_info_for_cfunc(
508
- ddog_CharSlice *filename_slice,
509
- int *line,
510
- ddog_CharSlice last_ruby_frame_filename,
511
- int last_ruby_line,
512
- DDTRACE_UNUSED void *function,
513
- DDTRACE_UNUSED bool top_of_the_stack,
514
- DDTRACE_UNUSED bool native_filenames_enabled,
515
- DDTRACE_UNUSED st_table *native_filenames_cache
516
- ) {
517
- *filename_slice = last_ruby_frame_filename;
518
- *line = last_ruby_line;
511
+ // `native_filenames_cache` is used to cache native filename lookup results (Map[void *function_pointer, char *filename])
512
+ //
513
+ // Caching this information is safe because there's no API in Ruby to "unrequire" a native extension. Thus, if we see a
514
+ // frame on the **Ruby** stack with a given `function`, then that `function` was registered with the Ruby VM and
515
+ // belongs to a Ruby extension, so a lot of other bad things would happen if it was dlclosed.
516
+ //
517
+ // Returns "" if not found. Never returns NULL.
518
+ static const char *get_or_compute_native_filename(void *function, st_table *native_filenames_cache) {
519
+ const char *cached_filename = NULL;
520
+ st_lookup(native_filenames_cache, (st_data_t) function, (st_data_t *) &cached_filename);
521
+ if (cached_filename != NULL) return cached_filename;
522
+
523
+ Dl_info info;
524
+ const char *native_filename = dladdr(function, &info) != 0 ? info.dli_fname : NULL;
525
+
526
+ // We explicitly use an empty string here so as to cache lookups that somehow "failed". Otherwise we would keep trying them every time.
527
+ if (native_filename == NULL) native_filename = "";
528
+
529
+ // An st_table is what Ruby uses for its own hashtables. This allows us to get an easy estimate of the size of the cache:
530
+ // `ObjectSpace.memsize_of((0..100000).map { |it| [it, nil] }.to_h)` => 4194400 bytes as of Ruby 3.2 so that seems reasonable?
531
+ // Note: `st_table_size()` is available from Ruby 3.2+ but not before
532
+ if (native_filenames_cache->num_entries >= 100000) {
533
+ st_clear(native_filenames_cache);
519
534
  }
520
- #endif
535
+
536
+ st_insert(native_filenames_cache, (st_data_t) function, (st_data_t) native_filename);
537
+ return native_filename;
538
+ }
521
539
 
522
540
  // Rails's ActionView likes to dynamically generate method names with suffixed hashes/ids, resulting in methods with
523
541
  // names such as:
@@ -530,33 +548,50 @@ void sample_thread(
530
548
  // the extra "_".)
531
549
  //
532
550
  // This method trims these suffixes, so that we keep less data + the names correctly aggregate together.
533
- static void maybe_trim_template_random_ids(ddog_CharSlice *name_slice, ddog_CharSlice *filename_slice) {
551
+ //
552
+ // We match on `method_name` because it always ends with the ids, while `frame_name` can have DDTRACE_BLOCK_SUFFIX
553
+ // after them ("Foo#_app_views_articles_index_html_erb__123_456 (block)"); in that case we move the suffix left over
554
+ // the ids. A `frame_name` that is a Ruby String ends with the ids we just matched, so that write only ever lands on
555
+ // a name we composed in the sample's own buffer.
556
+ static void maybe_trim_template_random_ids(ddog_CharSlice *frame_name, ddog_CharSlice method_name, ddog_CharSlice filename) {
534
557
  // Check filename doesn't end with ".rb"; templates are usually along the lines of .html.erb/.html.haml/...
535
- if (filename_slice->len < 3 || memcmp(filename_slice->ptr + filename_slice->len - 3, ".rb", 3) == 0) return;
558
+ if (filename.len < 3 || memcmp(filename.ptr + filename.len - 3, ".rb", 3) == 0) return;
536
559
 
537
- if (name_slice->len > 1024) return;
538
- if (name_slice->len == 0) return;
560
+ if (method_name.len > 1024) return;
561
+ if (method_name.len == 0) return;
539
562
 
540
- int pos = ((int) name_slice->len) - 1;
563
+ int pos = ((int) method_name.len) - 1;
541
564
 
542
565
  // Let's match on something__number_number:
543
566
  // Find start of id suffix from the end...
544
- if (name_slice->ptr[pos] < '0' || name_slice->ptr[pos] > '9') return;
567
+ if (method_name.ptr[pos] < '0' || method_name.ptr[pos] > '9') return;
545
568
 
546
569
  // ...now match a bunch of numbers and interspersed underscores
547
570
  for (int underscores = 0; pos >= 0 && underscores < 2; pos--) {
548
- if (name_slice->ptr[pos] == '_') underscores++;
549
- else if (name_slice->ptr[pos] < '0' || name_slice->ptr[pos] > '9') return;
571
+ if (method_name.ptr[pos] == '_') underscores++;
572
+ else if (method_name.ptr[pos] < '0' || method_name.ptr[pos] > '9') return;
550
573
  }
551
574
 
552
575
  // Make sure there's something left before the underscores (hence the <= instead of <) + match the last underscore
553
- if (pos <= 0 || name_slice->ptr[pos] != '_') return;
576
+ if (pos <= 0 || method_name.ptr[pos] != '_') return;
554
577
 
555
578
  // Does it have the optional third underscore? If so, remove it as well
556
- if (pos > 1 && name_slice->ptr[pos-1] == '_') pos--;
579
+ if (pos > 1 && method_name.ptr[pos-1] == '_') pos--;
580
+
581
+ // If we got here, we matched on our pattern. Let's remove the ids from the end of the frame name.
582
+ size_t random_ids_len = method_name.len - pos;
583
+
584
+ static const char block_suffix[] = DDTRACE_BLOCK_SUFFIX;
585
+ size_t block_suffix_len = sizeof(block_suffix) - 1;
586
+
587
+ if (
588
+ frame_name->len >= random_ids_len + block_suffix_len &&
589
+ memcmp(frame_name->ptr + frame_name->len - block_suffix_len, block_suffix, block_suffix_len) == 0
590
+ ) {
591
+ memcpy((char *) frame_name->ptr + frame_name->len - block_suffix_len - random_ids_len, block_suffix, block_suffix_len);
592
+ }
557
593
 
558
- // If we got here, we matched on our pattern. Let's slice the length of the string to exclude it.
559
- name_slice->len = pos;
594
+ frame_name->len -= random_ids_len;
560
595
  }
561
596
 
562
597
  static void add_truncated_frames_placeholder(ddog_prof_Location *locations) {
@@ -623,9 +658,10 @@ void record_placeholder_stack(
623
658
  );
624
659
  }
625
660
 
661
+ // Also called from a signal handler or during GC; check callers' safety requirements before changing this function.
626
662
  bool prepare_sample_thread(VALUE thread, sampling_buffer *buffer) {
627
- // Since this can get called from inside a signal handler, we don't want to touch the buffer if
628
- // the thread was actually in the middle of marking it.
663
+ // While the signal handler checks if there's GC going on, it's actually possible for `sampling_buffer_mark` to
664
+ // still run outside of GC (see comments on that function) and thus we guard for it here.
629
665
  if (buffer->is_marking) return false;
630
666
 
631
667
  buffer->pending_sample = true;
@@ -633,6 +669,28 @@ bool prepare_sample_thread(VALUE thread, sampling_buffer *buffer) {
633
669
  return true;
634
670
  }
635
671
 
672
+ void sample_locations_initialize(sample_locations *locations, uint16_t max_frames, bool show_classes) {
673
+ locations->len = max_frames;
674
+ locations->ptr = ruby_xcalloc(max_frames, sizeof(ddog_prof_Location));
675
+ if (show_classes) {
676
+ locations->qualified_name_buf_size = QUALIFIED_NAME_AVG_SIZE * max_frames;
677
+ locations->qualified_name_buf = ruby_xmalloc(locations->qualified_name_buf_size);
678
+ } else {
679
+ locations->qualified_name_buf_size = 0;
680
+ locations->qualified_name_buf = NULL;
681
+ }
682
+ }
683
+
684
+ void sample_locations_free(sample_locations *locations) {
685
+ ruby_xfree(locations->ptr);
686
+ ruby_xfree(locations->qualified_name_buf);
687
+
688
+ locations->ptr = NULL;
689
+ locations->len = 0;
690
+ locations->qualified_name_buf = NULL;
691
+ locations->qualified_name_buf_size = 0;
692
+ }
693
+
636
694
  uint16_t sampling_buffer_check_max_frames(int max_frames) {
637
695
  if (max_frames < 5) raise_error(rb_eArgError, "Invalid max_frames: value must be >= 5");
638
696
  if (max_frames > MAX_FRAMES_LIMIT) raise_error(rb_eArgError, "Invalid max_frames: value must be <= " MAX_FRAMES_LIMIT_AS_STRING);
@@ -665,18 +723,18 @@ void sampling_buffer_mark(sampling_buffer *buffer) {
665
723
  }
666
724
 
667
725
  buffer->is_marking = true;
668
- // Tell the compiler it's not allowed to reorder the `is_marking` flag with the iteration below.
669
- //
670
- // Specifically, in the middle of `sampling_buffer_mark` a signal handler may execute and call
671
- // `prepare_sample_thread` to add a new sample to the buffer. This flag is here to prevent that BUT we need to
672
- // make sure the signal handler actually sees the flag being set.
726
+ // The sampling buffer isn't supposed to be touched during GC. Yet, marking can happen outside of GC -- in particular
727
+ // ObjectSpace.dump/dump_all and reachable_objects_from invoke mark callbacks outside GC to enumerate references.
728
+ // Thus we keep this flag to tell the signal handler "hey you're still not allowed to touch the buffer at this time".
673
729
  //
730
+ // The fences ensure the compiler doesn't reorder the flags and a signal handler observes them
674
731
  // See https://github.com/ruby/ruby/pull/11036 for a similar change made to the Ruby VM with more context.
675
732
  atomic_signal_fence(memory_order_seq_cst);
676
733
 
677
734
  for (int i = 0; i < buffer->pending_sample_result; i++) {
735
+ rb_gc_mark((VALUE) buffer->stack_buffer[i].cme);
678
736
  if (buffer->stack_buffer[i].is_ruby_frame) {
679
- rb_gc_mark(buffer->stack_buffer[i].as.ruby_frame.iseq);
737
+ rb_gc_mark((VALUE) buffer->stack_buffer[i].as.ruby_frame.iseq);
680
738
  }
681
739
  }
682
740
 
@@ -684,3 +742,41 @@ void sampling_buffer_mark(sampling_buffer *buffer) {
684
742
  atomic_signal_fence(memory_order_seq_cst);
685
743
  buffer->is_marking = false;
686
744
  }
745
+
746
+ // On a static Ruby without libruby.so the `ruby_native_filename` returned from `dladdr` is in practice `argv[0]`
747
+ // (e.g. can be rspec, rake, etc), so here we find the actual Ruby binary to use instead
748
+ static void initialize_static_ruby_actual_filename(VALUE profiling_module) {
749
+ static_ruby_actual_filename = rb_const_get(profiling_module, rb_intern("STATIC_RUBY_PATH"));
750
+ if (NIL_P(static_ruby_actual_filename)) {
751
+ return;
752
+ }
753
+ // Makes this object immortal + pinned in-place (no moving)
754
+ rb_gc_register_mark_object(static_ruby_actual_filename);
755
+ }
756
+
757
+ static VALUE _native_set_file_info_for_cfunc(DDTRACE_UNUSED VALUE self, VALUE new_static_ruby_actual_filename) {
758
+ if (new_static_ruby_actual_filename != Qnil) ENFORCE_TYPE(new_static_ruby_actual_filename, T_STRING);
759
+
760
+ VALUE previous_static_ruby_actual_filename = static_ruby_actual_filename;
761
+ static_ruby_actual_filename = new_static_ruby_actual_filename;
762
+
763
+ ddog_CharSlice filename_slice;
764
+ int line;
765
+ st_table *native_filenames_cache = st_init_numtable();
766
+
767
+ set_file_info_for_cfunc(
768
+ &filename_slice,
769
+ &line,
770
+ DDOG_CHARSLICE_C("(not used when testing)"),
771
+ 0,
772
+ rb_ary_new, // Symbol inside Ruby VM to trigger comparison logic
773
+ false,
774
+ true,
775
+ native_filenames_cache
776
+ );
777
+
778
+ st_free_table(native_filenames_cache);
779
+ static_ruby_actual_filename = previous_static_ruby_actual_filename;
780
+
781
+ return rb_utf8_str_new(filename_slice.ptr, filename_slice.len);
782
+ }