datadog 2.21.0 → 2.38.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 (623) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +574 -1
  3. data/ext/LIBDATADOG_DEVELOPMENT.md +3 -0
  4. data/ext/datadog_profiling_native_extension/clock_id.h +9 -1
  5. data/ext/datadog_profiling_native_extension/clock_id_from_mach.c +66 -0
  6. data/ext/datadog_profiling_native_extension/clock_id_from_pthread.c +3 -2
  7. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +301 -82
  8. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +4 -4
  9. data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.c +3 -2
  10. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +18 -4
  11. data/ext/datadog_profiling_native_extension/collectors_stack.c +63 -32
  12. data/ext/datadog_profiling_native_extension/collectors_stack.h +7 -2
  13. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +728 -436
  14. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +19 -6
  15. data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +239 -0
  16. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +65 -1
  17. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +40 -1
  18. data/ext/datadog_profiling_native_extension/encoded_profile.c +2 -1
  19. data/ext/datadog_profiling_native_extension/extconf.rb +41 -37
  20. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +4 -43
  21. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +15 -47
  22. data/ext/datadog_profiling_native_extension/heap_recorder.c +252 -103
  23. data/ext/datadog_profiling_native_extension/heap_recorder.h +12 -1
  24. data/ext/datadog_profiling_native_extension/http_transport.c +66 -68
  25. data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +3 -22
  26. data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +0 -5
  27. data/ext/datadog_profiling_native_extension/macos_sampler_thread.h +55 -0
  28. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +0 -13
  29. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +40 -43
  30. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +6 -0
  31. data/ext/datadog_profiling_native_extension/profiling.c +65 -19
  32. data/ext/datadog_profiling_native_extension/ruby_helpers.c +63 -46
  33. data/ext/datadog_profiling_native_extension/ruby_helpers.h +17 -5
  34. data/ext/datadog_profiling_native_extension/setup_signal_handler.c +32 -10
  35. data/ext/datadog_profiling_native_extension/setup_signal_handler.h +2 -1
  36. data/ext/datadog_profiling_native_extension/stack_recorder.c +110 -85
  37. data/ext/datadog_profiling_native_extension/stack_recorder.h +3 -1
  38. data/ext/datadog_profiling_native_extension/time_helpers.h +13 -7
  39. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +2 -1
  40. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +9 -4
  41. data/ext/libdatadog_api/crashtracker.c +16 -15
  42. data/ext/libdatadog_api/crashtracker_report_exception.c +126 -0
  43. data/ext/libdatadog_api/datadog_ruby_common.c +65 -1
  44. data/ext/libdatadog_api/datadog_ruby_common.h +40 -1
  45. data/ext/libdatadog_api/ddsketch.c +102 -0
  46. data/ext/libdatadog_api/di.c +203 -0
  47. data/ext/libdatadog_api/extconf.rb +18 -24
  48. data/ext/libdatadog_api/feature_flags.c +554 -0
  49. data/ext/libdatadog_api/feature_flags.h +5 -0
  50. data/ext/libdatadog_api/helpers.h +27 -0
  51. data/ext/libdatadog_api/init.c +13 -1
  52. data/ext/libdatadog_api/library_config.c +34 -25
  53. data/ext/libdatadog_api/process_discovery.c +19 -13
  54. data/ext/libdatadog_extconf_helpers.rb +94 -11
  55. data/lib/datadog/ai_guard/api_client.rb +84 -0
  56. data/lib/datadog/ai_guard/autoload.rb +10 -0
  57. data/lib/datadog/ai_guard/component.rb +44 -0
  58. data/lib/datadog/ai_guard/configuration/ext.rb +17 -0
  59. data/lib/datadog/ai_guard/configuration.rb +115 -0
  60. data/lib/datadog/ai_guard/contrib/auto_instrument.rb +24 -0
  61. data/lib/datadog/ai_guard/contrib/integration.rb +37 -0
  62. data/lib/datadog/ai_guard/contrib/rack/integration.rb +42 -0
  63. data/lib/datadog/ai_guard/contrib/rack/patcher.rb +26 -0
  64. data/lib/datadog/ai_guard/contrib/rack/request_middleware.rb +97 -0
  65. data/lib/datadog/ai_guard/contrib/rails/integration.rb +41 -0
  66. data/lib/datadog/ai_guard/contrib/rails/patcher.rb +97 -0
  67. data/lib/datadog/ai_guard/contrib/ruby_llm/chat_instrumentation.rb +80 -0
  68. data/lib/datadog/ai_guard/contrib/ruby_llm/integration.rb +41 -0
  69. data/lib/datadog/ai_guard/contrib/ruby_llm/patcher.rb +30 -0
  70. data/lib/datadog/ai_guard/evaluation/content_builder.rb +31 -0
  71. data/lib/datadog/ai_guard/evaluation/content_part.rb +36 -0
  72. data/lib/datadog/ai_guard/evaluation/message.rb +25 -0
  73. data/lib/datadog/ai_guard/evaluation/no_op_result.rb +36 -0
  74. data/lib/datadog/ai_guard/evaluation/request.rb +86 -0
  75. data/lib/datadog/ai_guard/evaluation/result.rb +45 -0
  76. data/lib/datadog/ai_guard/evaluation/tool_call.rb +18 -0
  77. data/lib/datadog/ai_guard/evaluation.rb +108 -0
  78. data/lib/datadog/ai_guard/ext.rb +29 -0
  79. data/lib/datadog/ai_guard.rb +181 -0
  80. data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +26 -0
  81. data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +66 -0
  82. data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +36 -0
  83. data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +26 -0
  84. data/lib/datadog/appsec/api_security/endpoint_collection.rb +10 -0
  85. data/lib/datadog/appsec/api_security/route_extractor.rb +38 -9
  86. data/lib/datadog/appsec/api_security/sampler.rb +7 -4
  87. data/lib/datadog/appsec/assets/blocked.html +10 -1
  88. data/lib/datadog/appsec/assets/blocked.json +1 -1
  89. data/lib/datadog/appsec/assets/blocked.text +3 -1
  90. data/lib/datadog/appsec/assets/waf_rules/README.md +30 -36
  91. data/lib/datadog/appsec/assets/waf_rules/recommended.json +359 -4
  92. data/lib/datadog/appsec/assets/waf_rules/strict.json +43 -2
  93. data/lib/datadog/appsec/assets.rb +1 -1
  94. data/lib/datadog/appsec/autoload.rb +1 -1
  95. data/lib/datadog/appsec/component.rb +16 -9
  96. data/lib/datadog/appsec/compressed_json.rb +3 -3
  97. data/lib/datadog/appsec/configuration.rb +427 -1
  98. data/lib/datadog/appsec/context.rb +51 -13
  99. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +3 -1
  100. data/lib/datadog/appsec/contrib/active_record/integration.rb +1 -1
  101. data/lib/datadog/appsec/contrib/active_record/patcher.rb +4 -1
  102. data/lib/datadog/appsec/contrib/aws_lambda/gateway/watcher.rb +75 -0
  103. data/lib/datadog/appsec/contrib/aws_lambda/integration.rb +39 -0
  104. data/lib/datadog/appsec/contrib/aws_lambda/patcher.rb +30 -0
  105. data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +144 -0
  106. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -1
  107. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +2 -1
  108. data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
  109. data/lib/datadog/appsec/contrib/excon/patcher.rb +3 -1
  110. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +152 -12
  111. data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
  112. data/lib/datadog/appsec/contrib/faraday/patcher.rb +1 -1
  113. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +138 -12
  114. data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +74 -24
  115. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +4 -2
  116. data/lib/datadog/appsec/contrib/graphql/integration.rb +2 -1
  117. data/lib/datadog/appsec/contrib/rack/buffered_input.rb +83 -0
  118. data/lib/datadog/appsec/contrib/rack/ext.rb +1 -1
  119. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +52 -13
  120. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +40 -19
  121. data/lib/datadog/appsec/contrib/rack/input_peeker.rb +79 -0
  122. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  123. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +48 -33
  124. data/lib/datadog/appsec/contrib/rack/response_body.rb +36 -0
  125. data/lib/datadog/appsec/contrib/rails/gateway/request.rb +40 -1
  126. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +26 -5
  127. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  128. data/lib/datadog/appsec/contrib/rails/patcher.rb +38 -0
  129. data/lib/datadog/appsec/contrib/rails/patches/process_action_patch.rb +2 -0
  130. data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
  131. data/lib/datadog/appsec/contrib/rest_client/patcher.rb +3 -1
  132. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +167 -11
  133. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +43 -13
  134. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  135. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +4 -4
  136. data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +1 -1
  137. data/lib/datadog/appsec/counter_sampler.rb +25 -0
  138. data/lib/datadog/appsec/default_header_tags.rb +52 -0
  139. data/lib/datadog/appsec/event.rb +13 -31
  140. data/lib/datadog/appsec/ext.rb +3 -0
  141. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +2 -3
  142. data/lib/datadog/appsec/instrumentation/gateway.rb +2 -15
  143. data/lib/datadog/appsec/metrics/collector.rb +43 -5
  144. data/lib/datadog/appsec/metrics/exporter.rb +16 -3
  145. data/lib/datadog/appsec/metrics/telemetry.rb +20 -3
  146. data/lib/datadog/appsec/metrics/telemetry_exporter.rb +20 -1
  147. data/lib/datadog/appsec/metrics.rb +5 -5
  148. data/lib/datadog/appsec/monitor/gateway/watcher.rb +8 -6
  149. data/lib/datadog/appsec/remote.rb +44 -29
  150. data/lib/datadog/appsec/response.rb +18 -4
  151. data/lib/datadog/appsec/route_normalizer/rails_route_pattern.rb +176 -0
  152. data/lib/datadog/appsec/route_normalizer/route_pattern.rb +378 -0
  153. data/lib/datadog/appsec/route_normalizer/route_text.rb +57 -0
  154. data/lib/datadog/appsec/route_normalizer.rb +80 -0
  155. data/lib/datadog/appsec/security_engine/engine.rb +26 -5
  156. data/lib/datadog/appsec/security_engine/result.rb +29 -9
  157. data/lib/datadog/appsec/security_engine/runner.rb +20 -10
  158. data/lib/datadog/appsec/security_event.rb +5 -7
  159. data/lib/datadog/appsec/trace_keeper.rb +18 -6
  160. data/lib/datadog/appsec/utils/http/body.rb +38 -0
  161. data/lib/datadog/appsec/utils/http/body_reader.rb +61 -0
  162. data/lib/datadog/appsec/utils/http/media_range.rb +2 -1
  163. data/lib/datadog/appsec/utils/http/media_type.rb +32 -26
  164. data/lib/datadog/appsec/utils/http/url_encoded.rb +52 -0
  165. data/lib/datadog/appsec.rb +6 -3
  166. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +2 -2
  167. data/lib/datadog/core/configuration/base.rb +17 -5
  168. data/lib/datadog/core/configuration/components.rb +185 -17
  169. data/lib/datadog/core/configuration/components_state.rb +6 -1
  170. data/lib/datadog/core/configuration/config_helper.rb +11 -2
  171. data/lib/datadog/core/configuration/deprecations.rb +2 -2
  172. data/lib/datadog/core/configuration/option.rb +32 -6
  173. data/lib/datadog/core/configuration/option_definition.rb +42 -14
  174. data/lib/datadog/core/configuration/options.rb +49 -12
  175. data/lib/datadog/core/configuration/settings.rb +115 -16
  176. data/lib/datadog/core/configuration/stable_config.rb +10 -0
  177. data/lib/datadog/core/configuration/supported_configurations.rb +379 -300
  178. data/lib/datadog/core/configuration.rb +3 -3
  179. data/lib/datadog/core/contrib/rails/railtie.rb +32 -0
  180. data/lib/datadog/core/contrib/rails/utils.rb +7 -3
  181. data/lib/datadog/core/crashtracking/component.rb +73 -21
  182. data/lib/datadog/core/crashtracking/tag_builder.rb +6 -0
  183. data/lib/datadog/core/ddsketch.rb +19 -0
  184. data/lib/datadog/core/diagnostics/environment_logger.rb +3 -1
  185. data/lib/datadog/core/environment/agent_info.rb +65 -1
  186. data/lib/datadog/core/environment/cgroup.rb +52 -25
  187. data/lib/datadog/core/environment/container.rb +140 -46
  188. data/lib/datadog/core/environment/ext.rb +13 -0
  189. data/lib/datadog/core/environment/identity.rb +40 -4
  190. data/lib/datadog/core/environment/process.rb +122 -0
  191. data/lib/datadog/core/environment/socket.rb +13 -0
  192. data/lib/datadog/core/environment/yjit.rb +2 -1
  193. data/lib/datadog/core/error.rb +6 -6
  194. data/lib/datadog/core/evp.rb +11 -0
  195. data/lib/datadog/core/feature_flags.rb +61 -0
  196. data/lib/datadog/core/knuth_sampler.rb +59 -0
  197. data/lib/datadog/core/logger.rb +1 -1
  198. data/lib/datadog/core/metrics/client.rb +6 -6
  199. data/lib/datadog/core/metrics/logging.rb +1 -1
  200. data/lib/datadog/core/pin.rb +8 -8
  201. data/lib/datadog/core/process_discovery.rb +21 -18
  202. data/lib/datadog/core/rate_limiter.rb +11 -1
  203. data/lib/datadog/core/remote/client/capabilities.rb +49 -6
  204. data/lib/datadog/core/remote/client.rb +15 -7
  205. data/lib/datadog/core/remote/component.rb +64 -36
  206. data/lib/datadog/core/remote/configuration/content.rb +15 -2
  207. data/lib/datadog/core/remote/configuration/digest.rb +14 -7
  208. data/lib/datadog/core/remote/configuration/repository.rb +1 -1
  209. data/lib/datadog/core/remote/configuration/target.rb +13 -6
  210. data/lib/datadog/core/remote/transport/config.rb +9 -36
  211. data/lib/datadog/core/remote/transport/http/config.rb +15 -55
  212. data/lib/datadog/core/remote/transport/http/negotiation.rb +14 -44
  213. data/lib/datadog/core/remote/transport/http.rb +15 -24
  214. data/lib/datadog/core/remote/transport/negotiation.rb +8 -33
  215. data/lib/datadog/core/remote/worker.rb +25 -37
  216. data/lib/datadog/core/runtime/metrics.rb +11 -2
  217. data/lib/datadog/core/semaphore.rb +1 -4
  218. data/lib/datadog/core/tag_builder.rb +0 -4
  219. data/lib/datadog/core/tag_normalizer.rb +84 -0
  220. data/lib/datadog/core/telemetry/component.rb +59 -15
  221. data/lib/datadog/core/telemetry/emitter.rb +6 -6
  222. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +2 -3
  223. data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +30 -0
  224. data/lib/datadog/core/telemetry/event/app_extended_heartbeat.rb +32 -0
  225. data/lib/datadog/core/telemetry/event/app_started.rb +177 -171
  226. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +27 -4
  227. data/lib/datadog/core/telemetry/event.rb +2 -7
  228. data/lib/datadog/core/telemetry/ext.rb +1 -0
  229. data/lib/datadog/core/telemetry/logger.rb +4 -2
  230. data/lib/datadog/core/telemetry/logging.rb +17 -5
  231. data/lib/datadog/core/telemetry/metrics_manager.rb +9 -0
  232. data/lib/datadog/core/telemetry/request.rb +17 -5
  233. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +8 -34
  234. data/lib/datadog/core/telemetry/transport/http.rb +21 -16
  235. data/lib/datadog/core/telemetry/transport/telemetry.rb +8 -17
  236. data/lib/datadog/core/telemetry/worker.rb +108 -32
  237. data/lib/datadog/core/transport/ext.rb +3 -0
  238. data/lib/datadog/core/transport/http/api/endpoint.rb +9 -4
  239. data/lib/datadog/core/transport/http/api/instance.rb +4 -21
  240. data/lib/datadog/core/transport/http/builder.rb +10 -6
  241. data/lib/datadog/core/transport/http/client.rb +80 -0
  242. data/lib/datadog/core/transport/http/response.rb +4 -0
  243. data/lib/datadog/core/transport/http.rb +24 -19
  244. data/lib/datadog/core/transport/parcel.rb +61 -9
  245. data/lib/datadog/core/transport/response.rb +16 -2
  246. data/lib/datadog/core/transport/transport.rb +90 -0
  247. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +2 -2
  248. data/lib/datadog/core/utils/{base64.rb → base64_codec.rb} +4 -3
  249. data/lib/datadog/core/utils/enumerable_compat.rb +29 -0
  250. data/lib/datadog/core/utils/fnv.rb +26 -0
  251. data/lib/datadog/core/utils/forking.rb +3 -1
  252. data/lib/datadog/core/utils/hash.rb +0 -23
  253. data/lib/datadog/{appsec/api_security → core/utils}/lru_cache.rb +10 -21
  254. data/lib/datadog/core/utils/network.rb +22 -1
  255. data/lib/datadog/core/utils/only_once.rb +1 -1
  256. data/lib/datadog/core/utils/only_once_successful.rb +8 -2
  257. data/lib/datadog/core/utils/safe_dup.rb +2 -2
  258. data/lib/datadog/core/utils/sequence.rb +2 -0
  259. data/lib/datadog/core/utils/spawn_monkey_patch.rb +68 -0
  260. data/lib/datadog/core/utils/time.rb +6 -2
  261. data/lib/datadog/core/utils.rb +3 -1
  262. data/lib/datadog/core/workers/async.rb +11 -2
  263. data/lib/datadog/core/workers/interval_loop.rb +51 -3
  264. data/lib/datadog/core/workers/polling.rb +2 -0
  265. data/lib/datadog/core/workers/queue.rb +96 -1
  266. data/lib/datadog/core/workers/runtime_metrics.rb +9 -1
  267. data/lib/datadog/core.rb +10 -3
  268. data/lib/datadog/data_streams/configuration.rb +50 -0
  269. data/lib/datadog/data_streams/ext.rb +11 -0
  270. data/lib/datadog/data_streams/extensions.rb +16 -0
  271. data/lib/datadog/data_streams/pathway_context.rb +169 -0
  272. data/lib/datadog/data_streams/processor.rb +511 -0
  273. data/lib/datadog/data_streams/transport/http/stats.rb +58 -0
  274. data/lib/datadog/data_streams/transport/http.rb +36 -0
  275. data/lib/datadog/data_streams/transport/stats.rb +39 -0
  276. data/lib/datadog/data_streams.rb +100 -0
  277. data/lib/datadog/di/base.rb +15 -7
  278. data/lib/datadog/di/boot.rb +7 -2
  279. data/lib/datadog/di/capture_expression.rb +21 -0
  280. data/lib/datadog/di/capture_expression_evaluator.rb +71 -0
  281. data/lib/datadog/di/capture_limits.rb +41 -0
  282. data/lib/datadog/di/code_tracker.rb +217 -15
  283. data/lib/datadog/di/component.rb +139 -51
  284. data/lib/datadog/di/configuration.rb +241 -2
  285. data/lib/datadog/di/context.rb +82 -0
  286. data/lib/datadog/di/contrib/active_record.rb +34 -5
  287. data/lib/datadog/di/el/compiler.rb +168 -0
  288. data/lib/datadog/di/el/evaluator.rb +159 -0
  289. data/lib/datadog/di/el/expression.rb +42 -0
  290. data/lib/datadog/di/el.rb +5 -0
  291. data/lib/datadog/di/error.rb +44 -0
  292. data/lib/datadog/di/fatal_exceptions.rb +26 -0
  293. data/lib/datadog/di/instrumenter.rb +623 -147
  294. data/lib/datadog/di/logger.rb +2 -2
  295. data/lib/datadog/di/probe.rb +122 -14
  296. data/lib/datadog/di/probe_builder.rb +124 -3
  297. data/lib/datadog/di/probe_file_loader/railtie.rb +1 -1
  298. data/lib/datadog/di/probe_file_loader.rb +12 -7
  299. data/lib/datadog/di/probe_manager.rb +195 -100
  300. data/lib/datadog/di/probe_notification_builder.rb +321 -90
  301. data/lib/datadog/di/probe_notifier_worker.rb +112 -36
  302. data/lib/datadog/di/probe_repository.rb +198 -0
  303. data/lib/datadog/di/proc_responder.rb +36 -0
  304. data/lib/datadog/di/redactor.rb +24 -2
  305. data/lib/datadog/di/remote.rb +258 -93
  306. data/lib/datadog/di/serializer.rb +310 -29
  307. data/lib/datadog/di/transport/diagnostics.rb +12 -42
  308. data/lib/datadog/di/transport/http/diagnostics.rb +4 -34
  309. data/lib/datadog/di/transport/http/input.rb +2 -34
  310. data/lib/datadog/di/transport/http.rb +43 -19
  311. data/lib/datadog/di/transport/input.rb +112 -38
  312. data/lib/datadog/di/utils.rb +42 -14
  313. data/lib/datadog/di.rb +204 -4
  314. data/lib/datadog/error_tracking/collector.rb +2 -1
  315. data/lib/datadog/error_tracking/component.rb +2 -2
  316. data/lib/datadog/error_tracking/configuration.rb +55 -2
  317. data/lib/datadog/error_tracking/filters.rb +2 -2
  318. data/lib/datadog/kit/appsec/events/v2.rb +60 -3
  319. data/lib/datadog/kit/enable_core_dumps.rb +1 -1
  320. data/lib/datadog/kit/tracing/method_tracer.rb +135 -0
  321. data/lib/datadog/open_feature/component.rb +100 -0
  322. data/lib/datadog/open_feature/configuration.rb +37 -0
  323. data/lib/datadog/open_feature/evaluation_engine.rb +70 -0
  324. data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
  325. data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
  326. data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
  327. data/lib/datadog/open_feature/exposures/event.rb +60 -0
  328. data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
  329. data/lib/datadog/open_feature/exposures/worker.rb +116 -0
  330. data/lib/datadog/open_feature/ext.rb +16 -0
  331. data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +286 -0
  332. data/lib/datadog/open_feature/flag_evaluation/writer.rb +433 -0
  333. data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +101 -0
  334. data/lib/datadog/open_feature/hooks/flag_eval_metrics_hook.rb +49 -0
  335. data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +149 -0
  336. data/lib/datadog/open_feature/native_evaluator.rb +60 -0
  337. data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
  338. data/lib/datadog/open_feature/provider.rb +191 -0
  339. data/lib/datadog/open_feature/remote.rb +67 -0
  340. data/lib/datadog/open_feature/resolution_details.rb +35 -0
  341. data/lib/datadog/open_feature/transport.rb +121 -0
  342. data/lib/datadog/open_feature.rb +19 -0
  343. data/lib/datadog/opentelemetry/api/baggage.rb +1 -1
  344. data/lib/datadog/opentelemetry/configuration/settings.rb +226 -0
  345. data/lib/datadog/opentelemetry/ext.rb +9 -0
  346. data/lib/datadog/opentelemetry/logs.rb +98 -0
  347. data/lib/datadog/opentelemetry/metrics.rb +90 -0
  348. data/lib/datadog/opentelemetry/sdk/configurator.rb +65 -1
  349. data/lib/datadog/opentelemetry/sdk/id_generator.rb +16 -10
  350. data/lib/datadog/opentelemetry/sdk/logs_exporter.rb +30 -0
  351. data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +28 -0
  352. data/lib/datadog/opentelemetry/sdk/propagator.rb +9 -3
  353. data/lib/datadog/opentelemetry/sdk/span_processor.rb +4 -1
  354. data/lib/datadog/opentelemetry/sdk.rb +19 -0
  355. data/lib/datadog/opentelemetry/signal_configuration.rb +53 -0
  356. data/lib/datadog/opentelemetry.rb +4 -0
  357. data/lib/datadog/profiling/collectors/code_provenance.rb +71 -12
  358. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +52 -4
  359. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +13 -5
  360. data/lib/datadog/profiling/collectors/info.rb +18 -4
  361. data/lib/datadog/profiling/collectors/thread_context.rb +10 -5
  362. data/lib/datadog/profiling/component.rb +82 -40
  363. data/lib/datadog/profiling/exporter.rb +41 -12
  364. data/lib/datadog/profiling/ext/dir_monkey_patches.rb +24 -5
  365. data/lib/datadog/profiling/ext/exec_monkey_patch.rb +32 -0
  366. data/lib/datadog/profiling/ext.rb +0 -2
  367. data/lib/datadog/profiling/flush.rb +23 -11
  368. data/lib/datadog/profiling/http_transport.rb +21 -8
  369. data/lib/datadog/profiling/load_native_extension.rb +2 -2
  370. data/lib/datadog/profiling/profiler.rb +31 -14
  371. data/lib/datadog/profiling/scheduler.rb +10 -9
  372. data/lib/datadog/profiling/stack_recorder.rb +0 -8
  373. data/lib/datadog/profiling/tag_builder.rb +37 -3
  374. data/lib/datadog/profiling/tasks/exec.rb +8 -3
  375. data/lib/datadog/profiling/tasks/help.rb +1 -0
  376. data/lib/datadog/profiling/tasks/setup.rb +2 -2
  377. data/lib/datadog/profiling.rb +1 -3
  378. data/lib/datadog/ruby_version.rb +25 -0
  379. data/lib/datadog/single_step_instrument.rb +2 -2
  380. data/lib/datadog/symbol_database/component.rb +734 -0
  381. data/lib/datadog/symbol_database/configuration.rb +73 -0
  382. data/lib/datadog/symbol_database/extensions.rb +19 -0
  383. data/lib/datadog/symbol_database/extractor.rb +1110 -0
  384. data/lib/datadog/symbol_database/file_hash.rb +48 -0
  385. data/lib/datadog/symbol_database/logger.rb +43 -0
  386. data/lib/datadog/symbol_database/remote.rb +180 -0
  387. data/lib/datadog/symbol_database/scope.rb +102 -0
  388. data/lib/datadog/symbol_database/scope_batcher.rb +292 -0
  389. data/lib/datadog/symbol_database/service_version.rb +66 -0
  390. data/lib/datadog/symbol_database/symbol.rb +69 -0
  391. data/lib/datadog/symbol_database/transport/http/endpoint.rb +28 -0
  392. data/lib/datadog/symbol_database/transport/http.rb +45 -0
  393. data/lib/datadog/symbol_database/transport.rb +54 -0
  394. data/lib/datadog/symbol_database/uploader.rb +230 -0
  395. data/lib/datadog/symbol_database.rb +71 -0
  396. data/lib/datadog/tracing/buffer.rb +3 -3
  397. data/lib/datadog/tracing/component.rb +17 -17
  398. data/lib/datadog/tracing/configuration/dynamic.rb +2 -2
  399. data/lib/datadog/tracing/configuration/ext.rb +22 -0
  400. data/lib/datadog/tracing/configuration/settings.rb +96 -4
  401. data/lib/datadog/tracing/contrib/action_cable/events/broadcast.rb +4 -1
  402. data/lib/datadog/tracing/contrib/action_cable/events/perform_action.rb +4 -1
  403. data/lib/datadog/tracing/contrib/action_cable/events/transmit.rb +4 -1
  404. data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +4 -1
  405. data/lib/datadog/tracing/contrib/action_mailer/event.rb +4 -1
  406. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +10 -7
  407. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +28 -0
  408. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +3 -1
  409. data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -2
  410. data/lib/datadog/tracing/contrib/action_view/events/render_partial.rb +4 -1
  411. data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +5 -2
  412. data/lib/datadog/tracing/contrib/active_job/data_streams.rb +62 -0
  413. data/lib/datadog/tracing/contrib/active_job/events/discard.rb +5 -2
  414. data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +5 -2
  415. data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +5 -2
  416. data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +5 -2
  417. data/lib/datadog/tracing/contrib/active_job/events/perform.rb +5 -2
  418. data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +5 -2
  419. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +21 -7
  420. data/lib/datadog/tracing/contrib/active_job/patcher.rb +17 -1
  421. data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
  422. data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +3 -4
  423. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
  424. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
  425. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +2 -5
  426. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  427. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +2 -5
  428. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +1 -4
  429. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +2 -2
  430. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +6 -8
  431. data/lib/datadog/tracing/contrib/component.rb +3 -3
  432. data/lib/datadog/tracing/contrib/configurable.rb +18 -3
  433. data/lib/datadog/tracing/contrib/configuration/resolver.rb +14 -4
  434. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +1 -5
  435. data/lib/datadog/tracing/contrib/dalli/integration.rb +4 -1
  436. data/lib/datadog/tracing/contrib/dalli/quantize.rb +1 -1
  437. data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +2 -0
  438. data/lib/datadog/tracing/contrib/delayed_job/server_internal_tracer/worker.rb +1 -0
  439. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +2 -6
  440. data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +2 -2
  441. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +5 -1
  442. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +5 -6
  443. data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
  444. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +1 -8
  445. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +16 -5
  446. data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
  447. data/lib/datadog/tracing/contrib/excon/middleware.rb +3 -7
  448. data/lib/datadog/tracing/contrib/ext.rb +3 -1
  449. data/lib/datadog/tracing/contrib/extensions.rb +19 -2
  450. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +16 -9
  451. data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
  452. data/lib/datadog/tracing/contrib/faraday/middleware.rb +3 -7
  453. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +7 -3
  454. data/lib/datadog/tracing/contrib/grape/endpoint.rb +10 -7
  455. data/lib/datadog/tracing/contrib/grape/instrumentation.rb +13 -8
  456. data/lib/datadog/tracing/contrib/grape/patcher.rb +6 -1
  457. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +7 -0
  458. data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
  459. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +75 -44
  460. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +5 -2
  461. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +3 -7
  462. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +3 -7
  463. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +2 -0
  464. data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
  465. data/lib/datadog/tracing/contrib/grpc.rb +1 -0
  466. data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +1 -0
  467. data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +1 -0
  468. data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +1 -0
  469. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +16 -5
  470. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +2 -0
  471. data/lib/datadog/tracing/contrib/http/ext.rb +1 -0
  472. data/lib/datadog/tracing/contrib/http/instrumentation.rb +4 -8
  473. data/lib/datadog/tracing/contrib/http/integration.rb +0 -2
  474. data/lib/datadog/tracing/contrib/http.rb +1 -0
  475. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +16 -5
  476. data/lib/datadog/tracing/contrib/httpclient/ext.rb +1 -0
  477. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +7 -7
  478. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +16 -5
  479. data/lib/datadog/tracing/contrib/httprb/ext.rb +1 -0
  480. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +4 -8
  481. data/lib/datadog/tracing/contrib/kafka/event.rb +1 -0
  482. data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +66 -0
  483. data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +66 -0
  484. data/lib/datadog/tracing/contrib/kafka/patcher.rb +14 -0
  485. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +5 -1
  486. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +2 -0
  487. data/lib/datadog/tracing/contrib/karafka/ext.rb +1 -0
  488. data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
  489. data/lib/datadog/tracing/contrib/karafka/monitor.rb +11 -0
  490. data/lib/datadog/tracing/contrib/karafka/patcher.rb +35 -4
  491. data/lib/datadog/tracing/contrib/karafka.rb +1 -0
  492. data/lib/datadog/tracing/contrib/mongodb/parsers.rb +5 -5
  493. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +5 -8
  494. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +6 -0
  495. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +3 -6
  496. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +2 -6
  497. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +2 -2
  498. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +6 -0
  499. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +15 -18
  500. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +6 -8
  501. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +13 -0
  502. data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +6 -2
  503. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +24 -0
  504. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +5 -2
  505. data/lib/datadog/tracing/contrib/que/ext.rb +1 -0
  506. data/lib/datadog/tracing/contrib/que/tracer.rb +1 -0
  507. data/lib/datadog/tracing/contrib/racecar/event.rb +1 -5
  508. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +11 -1
  509. data/lib/datadog/tracing/contrib/rack/ext.rb +28 -0
  510. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +23 -0
  511. data/lib/datadog/tracing/contrib/rack/middlewares.rb +62 -27
  512. data/lib/datadog/tracing/contrib/rack/patcher.rb +2 -2
  513. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  514. data/lib/datadog/tracing/contrib/rack/route_inference.rb +67 -0
  515. data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +119 -1
  516. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +5 -2
  517. data/lib/datadog/tracing/contrib/rails/ext.rb +1 -0
  518. data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
  519. data/lib/datadog/tracing/contrib/rails/middlewares.rb +2 -2
  520. data/lib/datadog/tracing/contrib/rails/patcher.rb +0 -1
  521. data/lib/datadog/tracing/contrib/rails/runner.rb +3 -1
  522. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +6 -4
  523. data/lib/datadog/tracing/contrib/redis/quantize.rb +1 -1
  524. data/lib/datadog/tracing/contrib/redis/tags.rb +1 -6
  525. data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +2 -0
  526. data/lib/datadog/tracing/contrib/registerable.rb +11 -0
  527. data/lib/datadog/tracing/contrib/resque/resque_job.rb +1 -0
  528. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +5 -2
  529. data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -0
  530. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -6
  531. data/lib/datadog/tracing/contrib/roda/ext.rb +1 -0
  532. data/lib/datadog/tracing/contrib/roda/instrumentation.rb +7 -2
  533. data/lib/datadog/tracing/contrib/sequel/database.rb +1 -0
  534. data/lib/datadog/tracing/contrib/sequel/dataset.rb +1 -0
  535. data/lib/datadog/tracing/contrib/sequel/utils.rb +2 -7
  536. data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +1 -0
  537. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +1 -0
  538. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +5 -1
  539. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +2 -0
  540. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
  541. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/heartbeat.rb +2 -0
  542. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/job_fetch.rb +1 -0
  543. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/redis_info.rb +1 -0
  544. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/scheduled_poller.rb +2 -0
  545. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/stop.rb +1 -0
  546. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +3 -2
  547. data/lib/datadog/tracing/contrib/sidekiq/utils.rb +1 -1
  548. data/lib/datadog/tracing/contrib/sidekiq.rb +1 -0
  549. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +5 -1
  550. data/lib/datadog/tracing/contrib/sinatra/ext.rb +1 -0
  551. data/lib/datadog/tracing/contrib/sinatra/framework.rb +1 -1
  552. data/lib/datadog/tracing/contrib/sinatra/tracer.rb +1 -0
  553. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +4 -1
  554. data/lib/datadog/tracing/contrib/sneakers/integration.rb +15 -4
  555. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -0
  556. data/lib/datadog/tracing/contrib/status_range_matcher.rb +13 -1
  557. data/lib/datadog/tracing/contrib/stripe/request.rb +1 -1
  558. data/lib/datadog/tracing/contrib/sucker_punch/instrumentation.rb +1 -0
  559. data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +6 -0
  560. data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +4 -6
  561. data/lib/datadog/tracing/contrib/utils/quantization/{hash.rb → hash_formatter.rb} +4 -2
  562. data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +31 -0
  563. data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +50 -0
  564. data/lib/datadog/tracing/contrib/waterdrop/ext.rb +18 -0
  565. data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
  566. data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
  567. data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +49 -0
  568. data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
  569. data/lib/datadog/tracing/contrib/waterdrop.rb +42 -0
  570. data/lib/datadog/tracing/contrib.rb +9 -0
  571. data/lib/datadog/tracing/diagnostics/environment_logger.rb +4 -2
  572. data/lib/datadog/tracing/distributed/baggage.rb +64 -8
  573. data/lib/datadog/tracing/distributed/datadog.rb +13 -11
  574. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -14
  575. data/lib/datadog/tracing/distributed/propagation.rb +35 -3
  576. data/lib/datadog/tracing/distributed/trace_context.rb +85 -62
  577. data/lib/datadog/tracing/event.rb +1 -1
  578. data/lib/datadog/tracing/ext.rb +9 -0
  579. data/lib/datadog/tracing/metadata/ext.rb +23 -1
  580. data/lib/datadog/tracing/metadata/tagging.rb +2 -2
  581. data/lib/datadog/tracing/pipeline.rb +1 -1
  582. data/lib/datadog/tracing/remote.rb +36 -13
  583. data/lib/datadog/tracing/sampling/ext.rb +2 -0
  584. data/lib/datadog/tracing/sampling/priority_sampler.rb +16 -1
  585. data/lib/datadog/tracing/sampling/rate_sampler.rb +8 -19
  586. data/lib/datadog/tracing/sampling/rule.rb +1 -1
  587. data/lib/datadog/tracing/sampling/rule_sampler.rb +54 -25
  588. data/lib/datadog/tracing/sampling/span/rule_parser.rb +2 -2
  589. data/lib/datadog/tracing/span.rb +1 -1
  590. data/lib/datadog/tracing/span_event.rb +2 -2
  591. data/lib/datadog/tracing/span_operation.rb +34 -10
  592. data/lib/datadog/tracing/sync_writer.rb +0 -1
  593. data/lib/datadog/tracing/trace_digest.rb +7 -0
  594. data/lib/datadog/tracing/trace_operation.rb +123 -16
  595. data/lib/datadog/tracing/tracer.rb +82 -23
  596. data/lib/datadog/tracing/transport/http/client.rb +12 -26
  597. data/lib/datadog/tracing/transport/http/traces.rb +2 -50
  598. data/lib/datadog/tracing/transport/http.rb +15 -9
  599. data/lib/datadog/tracing/transport/io/client.rb +6 -9
  600. data/lib/datadog/tracing/transport/io/traces.rb +28 -34
  601. data/lib/datadog/tracing/transport/trace_formatter.rb +22 -0
  602. data/lib/datadog/tracing/transport/traces.rb +13 -81
  603. data/lib/datadog/tracing/workers.rb +2 -1
  604. data/lib/datadog/tracing/writer.rb +1 -1
  605. data/lib/datadog/version.rb +2 -2
  606. data/lib/datadog.rb +8 -1
  607. metadata +185 -36
  608. data/ext/datadog_profiling_native_extension/clock_id_noop.c +0 -21
  609. data/ext/libdatadog_api/macos_development.md +0 -26
  610. data/lib/datadog/appsec/configuration/settings.rb +0 -400
  611. data/lib/datadog/appsec/contrib/rails/ext.rb +0 -13
  612. data/lib/datadog/core/remote/transport/http/api.rb +0 -53
  613. data/lib/datadog/core/remote/transport/http/client.rb +0 -49
  614. data/lib/datadog/core/telemetry/transport/http/api.rb +0 -43
  615. data/lib/datadog/core/telemetry/transport/http/client.rb +0 -49
  616. data/lib/datadog/core/transport/http/api/spec.rb +0 -36
  617. data/lib/datadog/di/configuration/settings.rb +0 -212
  618. data/lib/datadog/di/transport/http/api.rb +0 -42
  619. data/lib/datadog/di/transport/http/client.rb +0 -47
  620. data/lib/datadog/error_tracking/configuration/settings.rb +0 -63
  621. data/lib/datadog/opentelemetry/api/baggage.rbs +0 -26
  622. data/lib/datadog/tracing/transport/http/api.rb +0 -44
  623. data/lib/datadog/tracing/workers/trace_writer.rb +0 -199
@@ -105,7 +105,9 @@ void heap_recorder_after_fork(heap_recorder *heap_recorder);
105
105
  // The sampling weight of this object.
106
106
  //
107
107
  // WARN: It needs to be paired with a ::end_heap_allocation_recording call.
108
- void start_heap_allocation_recording(heap_recorder *heap_recorder, VALUE new_obj, unsigned int weight, ddog_CharSlice alloc_class);
108
+ // Returns needs_after_allocation: true whenever the pending_recordings buffer goes from empty to non-empty and thus
109
+ // a after_sample callback is required to flush it
110
+ bool start_heap_allocation_recording(heap_recorder *heap_recorder, VALUE new_obj, unsigned int weight, ddog_CharSlice alloc_class);
109
111
 
110
112
  // End a previously started heap allocation recording on the heap recorder.
111
113
  //
@@ -123,6 +125,15 @@ int end_heap_allocation_recording_with_rb_protect(heap_recorder *heap_recorder,
123
125
  // these objects quicker) and hopefully reduces tail latency (because there's less objects at serialization time to check).
124
126
  void heap_recorder_update_young_objects(heap_recorder *heap_recorder);
125
127
 
128
+ // Finalize any pending heap allocation recordings by getting their object IDs.
129
+ // This should be called via a postponed job, after the on_newobj_event has completed.
130
+ // Raises an exception if a fatal error occurs (e.g., bignum object ID detected).
131
+ void heap_recorder_finalize_pending_recordings(heap_recorder *heap_recorder);
132
+
133
+ // Mark pending recordings to prevent GC from collecting the objects
134
+ // while they're waiting for the recordings to be finalized.
135
+ void heap_recorder_mark_pending_recordings(heap_recorder *heap_recorder);
136
+
126
137
  // Update the heap recorder to reflect the latest state of the VM and prepare internal structures
127
138
  // for efficient iteration.
128
139
  //
@@ -16,7 +16,11 @@ static VALUE library_version_string = Qnil;
16
16
 
17
17
  typedef struct {
18
18
  ddog_prof_ProfileExporter *exporter;
19
- ddog_prof_Request_Result *build_result;
19
+ ddog_prof_EncodedProfile *profile;
20
+ ddog_prof_Exporter_Slice_File files_to_compress_and_export;
21
+ ddog_CharSlice internal_metadata;
22
+ ddog_CharSlice info;
23
+ ddog_CharSlice *process_tags;
20
24
  ddog_CancellationToken *cancel_token;
21
25
  ddog_prof_Result_HttpStatus result;
22
26
  bool send_ran;
@@ -29,7 +33,6 @@ static VALUE handle_exporter_failure(ddog_prof_ProfileExporter_Result exporter_r
29
33
  static VALUE _native_do_export(
30
34
  VALUE self,
31
35
  VALUE exporter_configuration,
32
- VALUE upload_timeout_milliseconds,
33
36
  VALUE flush
34
37
  );
35
38
  static void *call_exporter_without_gvl(void *call_args);
@@ -39,7 +42,7 @@ void http_transport_init(VALUE profiling_module) {
39
42
  VALUE http_transport_class = rb_define_class_under(profiling_module, "HttpTransport", rb_cObject);
40
43
 
41
44
  rb_define_singleton_method(http_transport_class, "_native_validate_exporter", _native_validate_exporter, 1);
42
- rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export, 3);
45
+ rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export, 2);
43
46
 
44
47
  ok_symbol = ID2SYM(rb_intern_const("ok"));
45
48
  error_symbol = ID2SYM(rb_intern_const("error"));
@@ -75,17 +78,33 @@ static ddog_prof_Endpoint endpoint_from(VALUE exporter_configuration) {
75
78
  ENFORCE_TYPE(exporter_working_mode, T_SYMBOL);
76
79
  ID working_mode = SYM2ID(exporter_working_mode);
77
80
 
78
- if (working_mode == rb_intern("agentless")) {
79
- VALUE site = rb_ary_entry(exporter_configuration, 1);
80
- VALUE api_key = rb_ary_entry(exporter_configuration, 2);
81
+ VALUE timeout_milliseconds_value = rb_ary_entry(exporter_configuration, 1);
82
+ ENFORCE_TYPE(timeout_milliseconds_value, T_FIXNUM);
83
+ uint64_t timeout_milliseconds = NUM2ULONG(timeout_milliseconds_value);
84
+
85
+ VALUE use_system_dns = rb_ary_entry(exporter_configuration, 2);
86
+ ENFORCE_BOOLEAN(use_system_dns);
81
87
 
82
- return ddog_prof_Endpoint_agentless(char_slice_from_ruby_string(site), char_slice_from_ruby_string(api_key));
88
+ if (working_mode == rb_intern("agentless")) {
89
+ VALUE site = rb_ary_entry(exporter_configuration, 3);
90
+ VALUE api_key = rb_ary_entry(exporter_configuration, 4);
91
+
92
+ return ddog_prof_Endpoint_agentless(
93
+ char_slice_from_ruby_string(site),
94
+ char_slice_from_ruby_string(api_key),
95
+ timeout_milliseconds,
96
+ use_system_dns == Qtrue
97
+ );
83
98
  } else if (working_mode == rb_intern("agent")) {
84
- VALUE base_url = rb_ary_entry(exporter_configuration, 1);
99
+ VALUE base_url = rb_ary_entry(exporter_configuration, 3);
85
100
 
86
- return ddog_prof_Endpoint_agent(char_slice_from_ruby_string(base_url));
101
+ return ddog_prof_Endpoint_agent(
102
+ char_slice_from_ruby_string(base_url),
103
+ timeout_milliseconds,
104
+ use_system_dns == Qtrue
105
+ );
87
106
  } else {
88
- rb_raise(rb_eArgError, "Failed to initialize transport: Unexpected working mode, expected :agentless or :agent");
107
+ raise_error(rb_eArgError, "Failed to initialize transport: Unexpected working mode, expected :agentless or :agent");
89
108
  }
90
109
  }
91
110
 
@@ -112,7 +131,7 @@ static ddog_prof_ProfileExporter_Result create_exporter(VALUE exporter_configura
112
131
  }
113
132
 
114
133
  static void validate_token(ddog_CancellationToken token, const char *file, int line) {
115
- if (token.inner == NULL) rb_raise(rb_eRuntimeError, "Unexpected: Validation token was empty at %s:%d", file, line);
134
+ if (token.inner == NULL) raise_error(rb_eRuntimeError, "Unexpected: Validation token was empty at %s:%d", file, line);
116
135
  }
117
136
 
118
137
  static VALUE handle_exporter_failure(ddog_prof_ProfileExporter_Result exporter_result) {
@@ -123,39 +142,18 @@ static VALUE handle_exporter_failure(ddog_prof_ProfileExporter_Result exporter_r
123
142
 
124
143
  // Note: This function handles a bunch of libdatadog dynamically-allocated objects, so it MUST not use any Ruby APIs
125
144
  // which can raise exceptions, otherwise the objects will be leaked.
126
- static VALUE perform_export(
127
- ddog_prof_ProfileExporter *exporter,
128
- ddog_prof_EncodedProfile *profile,
129
- ddog_prof_Exporter_Slice_File files_to_compress_and_export,
130
- ddog_CharSlice internal_metadata,
131
- ddog_CharSlice info
132
- ) {
133
- ddog_prof_Request_Result build_result = ddog_prof_Exporter_Request_build(
134
- exporter,
135
- profile,
136
- files_to_compress_and_export,
137
- /* files_to_export_unmodified: */ ddog_prof_Exporter_Slice_File_empty(),
138
- /* optional_additional_tags: */ NULL,
139
- &internal_metadata,
140
- &info
141
- );
142
-
143
- if (build_result.tag == DDOG_PROF_REQUEST_RESULT_ERR_HANDLE_REQUEST) {
144
- ddog_prof_Exporter_drop(exporter);
145
- return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&build_result.err));
146
- }
147
-
145
+ static VALUE perform_export(call_exporter_without_gvl_arguments args) {
148
146
  ddog_CancellationToken cancel_token_request = ddog_CancellationToken_new();
149
147
  ddog_CancellationToken cancel_token_interrupt = ddog_CancellationToken_clone(&cancel_token_request);
150
148
 
151
149
  validate_token(cancel_token_request, __FILE__, __LINE__);
152
150
  validate_token(cancel_token_interrupt, __FILE__, __LINE__);
153
151
 
152
+ args.cancel_token = &cancel_token_request;
153
+ args.send_ran = false;
154
+
154
155
  // We'll release the Global VM Lock while we're calling send, so that the Ruby VM can continue to work while this
155
156
  // is pending
156
- call_exporter_without_gvl_arguments args =
157
- {.exporter = exporter, .build_result = &build_result, .cancel_token = &cancel_token_request, .send_ran = false};
158
-
159
157
  // We use rb_thread_call_without_gvl2 instead of rb_thread_call_without_gvl as the gvl2 variant never raises any
160
158
  // exceptions.
161
159
  //
@@ -180,18 +178,13 @@ static VALUE perform_export(
180
178
  // Cleanup exporter and token, no longer needed
181
179
  ddog_CancellationToken_drop(&cancel_token_request);
182
180
  ddog_CancellationToken_drop(&cancel_token_interrupt);
183
- ddog_prof_Exporter_drop(exporter);
181
+ ddog_prof_Exporter_drop(args.exporter);
184
182
 
185
183
  if (pending_exception) {
186
- // If we got here send did not run, so we need to explicitly dispose of the request
187
- ddog_prof_Exporter_Request_drop(&build_result.ok);
188
-
189
184
  // Let Ruby propagate the exception. This will not return.
190
185
  rb_jump_tag(pending_exception);
191
186
  }
192
187
 
193
- // The request itself does not need to be freed as libdatadog takes ownership of it as part of sending.
194
-
195
188
  ddog_prof_Result_HttpStatus result = args.result;
196
189
 
197
190
  return result.tag == DDOG_PROF_RESULT_HTTP_STATUS_OK_HTTP_STATUS ?
@@ -202,42 +195,46 @@ static VALUE perform_export(
202
195
  static VALUE _native_do_export(
203
196
  DDTRACE_UNUSED VALUE _self,
204
197
  VALUE exporter_configuration,
205
- VALUE upload_timeout_milliseconds,
206
198
  VALUE flush
207
199
  ) {
208
200
  VALUE encoded_profile = rb_funcall(flush, rb_intern("encoded_profile"), 0);
209
- VALUE code_provenance_file_name = rb_funcall(flush, rb_intern("code_provenance_file_name"), 0);
210
201
  VALUE code_provenance_data = rb_funcall(flush, rb_intern("code_provenance_data"), 0);
202
+ VALUE metrics_json = rb_funcall(flush, rb_intern("metrics"), 0);
211
203
  VALUE tags_as_array = rb_funcall(flush, rb_intern("tags_as_array"), 0);
212
204
  VALUE internal_metadata_json = rb_funcall(flush, rb_intern("internal_metadata_json"), 0);
213
205
  VALUE info_json = rb_funcall(flush, rb_intern("info_json"), 0);
206
+ VALUE process_tags = rb_funcall(flush, rb_intern("process_tags"), 0);
214
207
 
215
- ENFORCE_TYPE(upload_timeout_milliseconds, T_FIXNUM);
216
208
  enforce_encoded_profile_instance(encoded_profile);
217
- ENFORCE_TYPE(code_provenance_file_name, T_STRING);
209
+ ENFORCE_TYPE(metrics_json, T_STRING);
218
210
  ENFORCE_TYPE(tags_as_array, T_ARRAY);
219
211
  ENFORCE_TYPE(internal_metadata_json, T_STRING);
220
212
  ENFORCE_TYPE(info_json, T_STRING);
213
+ ENFORCE_TYPE(process_tags, T_STRING);
221
214
 
222
215
  // Code provenance can be disabled and in that case will be set to nil
223
216
  bool have_code_provenance = !NIL_P(code_provenance_data);
224
217
  if (have_code_provenance) ENFORCE_TYPE(code_provenance_data, T_STRING);
225
218
 
226
- uint64_t timeout_milliseconds = NUM2ULONG(upload_timeout_milliseconds);
227
-
228
- int to_compress_length = have_code_provenance ? 1 : 0;
219
+ int to_compress_length = 1 + (have_code_provenance ? 1 : 0);
229
220
  ddog_prof_Exporter_File to_compress[to_compress_length];
230
221
  ddog_prof_Exporter_Slice_File files_to_compress_and_export = {.ptr = to_compress, .len = to_compress_length};
231
222
 
223
+ to_compress[0] = (ddog_prof_Exporter_File) {
224
+ .name = DDOG_CHARSLICE_C("metrics.json"),
225
+ .file = byte_slice_from_ruby_string(metrics_json),
226
+ };
227
+
232
228
  if (have_code_provenance) {
233
- to_compress[0] = (ddog_prof_Exporter_File) {
234
- .name = char_slice_from_ruby_string(code_provenance_file_name),
229
+ to_compress[1] = (ddog_prof_Exporter_File) {
230
+ .name = DDOG_CHARSLICE_C("code-provenance.json"),
235
231
  .file = byte_slice_from_ruby_string(code_provenance_data),
236
232
  };
237
233
  }
238
234
 
239
235
  ddog_CharSlice internal_metadata = char_slice_from_ruby_string(internal_metadata_json);
240
236
  ddog_CharSlice info = char_slice_from_ruby_string(info_json);
237
+ ddog_CharSlice process_tags_slice = char_slice_from_ruby_string(process_tags);
241
238
 
242
239
  ddog_prof_ProfileExporter_Result exporter_result = create_exporter(exporter_configuration, tags_as_array);
243
240
  // Note: Do not add anything that can raise exceptions after this line, as otherwise the exporter memory will leak
@@ -245,28 +242,29 @@ static VALUE _native_do_export(
245
242
  VALUE failure_tuple = handle_exporter_failure(exporter_result);
246
243
  if (!NIL_P(failure_tuple)) return failure_tuple;
247
244
 
248
- ddog_VoidResult timeout_result = ddog_prof_Exporter_set_timeout(&exporter_result.ok, timeout_milliseconds);
249
- if (timeout_result.tag == DDOG_VOID_RESULT_ERR) {
250
- // NOTE: Seems a bit harsh to fail the upload if we can't set a timeout. OTOH, this is only expected to fail
251
- // if the exporter is not well built. Because such a situation should already be caught above I think it's
252
- // preferable to leave this here as a virtually unreachable exception rather than ignoring it.
253
- ddog_prof_Exporter_drop(&exporter_result.ok);
254
- return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&timeout_result.err));
255
- }
256
-
257
- return perform_export(
258
- &exporter_result.ok,
259
- to_ddog_prof_EncodedProfile(encoded_profile),
260
- files_to_compress_and_export,
261
- internal_metadata,
262
- info
263
- );
245
+ return perform_export((call_exporter_without_gvl_arguments) {
246
+ .exporter = &exporter_result.ok,
247
+ .profile = to_ddog_prof_EncodedProfile(encoded_profile),
248
+ .files_to_compress_and_export = files_to_compress_and_export,
249
+ .internal_metadata = internal_metadata,
250
+ .info = info,
251
+ .process_tags = &process_tags_slice
252
+ });
264
253
  }
265
254
 
266
255
  static void *call_exporter_without_gvl(void *call_args) {
267
256
  call_exporter_without_gvl_arguments *args = (call_exporter_without_gvl_arguments*) call_args;
268
257
 
269
- args->result = ddog_prof_Exporter_send(args->exporter, &args->build_result->ok, args->cancel_token);
258
+ args->result = ddog_prof_Exporter_send_blocking(
259
+ args->exporter,
260
+ args->profile,
261
+ args->files_to_compress_and_export,
262
+ /* optional_additional_tags: */ NULL,
263
+ /* optional_process_tags: */ args->process_tags,
264
+ &args->internal_metadata,
265
+ &args->info,
266
+ args->cancel_token
267
+ );
270
268
  args->send_ran = true;
271
269
 
272
270
  return NULL; // Unused
@@ -1,6 +1,7 @@
1
1
  #include "libdatadog_helpers.h"
2
2
 
3
3
  #include <ruby.h>
4
+ #include "ruby_helpers.h"
4
5
 
5
6
  const char *ruby_value_type_to_string(enum ruby_value_type type) {
6
7
  return ruby_value_type_to_char_slice(type).ptr;
@@ -41,32 +42,12 @@ ddog_CharSlice ruby_value_type_to_char_slice(enum ruby_value_type type) {
41
42
  }
42
43
  }
43
44
 
44
- size_t read_ddogerr_string_and_drop(ddog_Error *error, char *string, size_t capacity) {
45
- if (capacity == 0 || string == NULL) {
46
- // short-circuit, we can't write anything
47
- ddog_Error_drop(error);
48
- return 0;
49
- }
50
-
51
- ddog_CharSlice error_msg_slice = ddog_Error_message(error);
52
- size_t error_msg_size = error_msg_slice.len;
53
- // Account for extra null char for proper cstring
54
- if (error_msg_size >= capacity) {
55
- // Error message too big, lets truncate it to capacity - 1 to allow for extra null at end
56
- error_msg_size = capacity - 1;
57
- }
58
- strncpy(string, error_msg_slice.ptr, error_msg_size);
59
- string[error_msg_size] = '\0';
60
- ddog_Error_drop(error);
61
- return error_msg_size;
62
- }
63
-
64
45
  ddog_prof_ManagedStringId intern_or_raise(ddog_prof_ManagedStringStorage string_storage, ddog_CharSlice string) {
65
46
  if (string.len == 0) return (ddog_prof_ManagedStringId) { 0 }; // Id 0 is always an empty string, no need to ask
66
47
 
67
48
  ddog_prof_ManagedStringStorageInternResult intern_result = ddog_prof_ManagedStringStorage_intern(string_storage, string);
68
49
  if (intern_result.tag == DDOG_PROF_MANAGED_STRING_STORAGE_INTERN_RESULT_ERR) {
69
- rb_raise(rb_eRuntimeError, "Failed to intern string: %"PRIsVALUE, get_error_details_and_drop(&intern_result.err));
50
+ raise_error(rb_eRuntimeError, "Failed to intern string: %"PRIsVALUE, get_error_details_and_drop(&intern_result.err));
70
51
  }
71
52
  return intern_result.ok;
72
53
  }
@@ -79,6 +60,6 @@ void intern_all_or_raise(
79
60
  ) {
80
61
  ddog_prof_MaybeError result = ddog_prof_ManagedStringStorage_intern_all(string_storage, strings, output_ids, output_ids_size);
81
62
  if (result.tag == DDOG_PROF_OPTION_ERROR_SOME_ERROR) {
82
- rb_raise(rb_eRuntimeError, "Failed to intern_all: %"PRIsVALUE, get_error_details_and_drop(&result.some));
63
+ raise_error(rb_eRuntimeError, "Failed to intern_all: %"PRIsVALUE, get_error_details_and_drop(&result.some));
83
64
  }
84
65
  }
@@ -7,11 +7,6 @@ static inline VALUE ruby_string_from_vec_u8(ddog_Vec_U8 string) {
7
7
  return rb_str_new((char *) string.ptr, string.len);
8
8
  }
9
9
 
10
- // Utility function to be able to extract an error cstring from a ddog_Error.
11
- // Returns the amount of characters written to string (which are necessarily
12
- // bounded by capacity - 1 since the string will be null-terminated).
13
- size_t read_ddogerr_string_and_drop(ddog_Error *error, char *string, size_t capacity);
14
-
15
10
  // Used for pretty printing this Ruby enum. Returns "T_UNKNOWN_OR_MISSING_RUBY_VALUE_TYPE_ENTRY" for unknown elements.
16
11
  // In practice, there's a few types that the profiler will probably never encounter, but I've added all entries of
17
12
  // ruby_value_type that Ruby uses so that we can also use this for debugging.
@@ -0,0 +1,55 @@
1
+ #pragma once
2
+
3
+ #include <mach/mach.h>
4
+ #include <mach/mach_time.h>
5
+ #include <mach/thread_policy.h>
6
+ #include <pthread.h>
7
+ #include <stdio.h>
8
+
9
+ #include "time_helpers.h"
10
+
11
+ // On macOS the default scheduler wake latency for a timeshare thread is ~1-2ms,
12
+ // so nanosleep regularly overshoots a 10ms request by ~2ms. Marking the worker
13
+ // thread with THREAD_TIME_CONSTRAINT_POLICY tells the scheduler this thread has
14
+ // a periodic deadline; the kernel then wakes it close to the requested time.
15
+ //
16
+ // This only affects the sampler worker thread. We pair it with a demote call
17
+ // before the thread can be reused by Ruby for unrelated Ruby threads (see the
18
+ // SIGPROF unblock dance in _native_sampling_loop).
19
+ static inline void promote_sampler_thread_to_realtime(uint64_t period_ns) {
20
+ mach_timebase_info_data_t timebase = (mach_timebase_info_data_t) {};
21
+ mach_timebase_info(&timebase);
22
+
23
+ // ns -> mach ticks: each mach tick is (numer/denom) ns, so divide by that.
24
+ #define NS_TO_MACH_TICKS(ns) ((uint32_t) (((uint64_t)(ns) * (uint64_t) timebase.denom) / (uint64_t) timebase.numer))
25
+
26
+ struct thread_time_constraint_policy policy = {
27
+ .period = NS_TO_MACH_TICKS(period_ns),
28
+ .computation = NS_TO_MACH_TICKS(MICROS_AS_NS(200)), // 200us upper bound on the work we do per period
29
+ .constraint = NS_TO_MACH_TICKS(MILLIS_AS_NS(1)), // wake us within 1ms of the deadline
30
+ .preemptible = TRUE,
31
+ };
32
+
33
+ #undef NS_TO_MACH_TICKS
34
+
35
+ kern_return_t kr = thread_policy_set(
36
+ pthread_mach_thread_np(pthread_self()),
37
+ THREAD_TIME_CONSTRAINT_POLICY,
38
+ (thread_policy_t) &policy,
39
+ THREAD_TIME_CONSTRAINT_POLICY_COUNT
40
+ );
41
+ if (kr != KERN_SUCCESS) {
42
+ // Non-fatal: we'll fall back to the default scheduler behavior (overshoot ~2ms).
43
+ fprintf(stderr, "[ddtrace] Failed to set real-time policy on profiler sampler thread (kr=%d); sample cadence may be imprecise\n", kr);
44
+ }
45
+ }
46
+
47
+ static inline void demote_sampler_thread_from_realtime(void) {
48
+ struct thread_standard_policy policy = {.no_data = 0};
49
+ thread_policy_set(
50
+ pthread_mach_thread_np(pthread_self()),
51
+ THREAD_STANDARD_POLICY,
52
+ (thread_policy_t) &policy,
53
+ THREAD_STANDARD_POLICY_COUNT
54
+ );
55
+ }
@@ -104,19 +104,6 @@ module Datadog
104
104
  suggested: CONTACT_SUPPORT,
105
105
  )
106
106
 
107
- # Validation for this check is done in extconf.rb because it relies on mkmf
108
- PKG_CONFIG_IS_MISSING = explain_issue(
109
- # ----------------------------------------------------------------------------+
110
- "the `pkg-config` system tool is missing.",
111
- "This issue can usually be fixed by installing one of the following:",
112
- "the `pkg-config` package on Homebrew and Debian/Ubuntu-based Linux;",
113
- "the `pkgconf` package on Arch and Alpine-based Linux;",
114
- "the `pkgconf-pkg-config` package on Fedora/Red Hat-based Linux.",
115
- "(Tip: When fixing this, ensure `pkg-config` is installed **before**",
116
- "running `bundle install`, and remember to clear any installed gems cache).",
117
- suggested: CONTACT_SUPPORT,
118
- )
119
-
120
107
  # Validation for this check is done in extconf.rb because it relies on mkmf
121
108
  COMPILER_ATOMIC_MISSING = explain_issue(
122
109
  "your C compiler is missing support for the <stdatomic.h> header.",
@@ -76,6 +76,18 @@ rb_nativethread_id_t pthread_id_for(VALUE thread) {
76
76
  #endif
77
77
  }
78
78
 
79
+ size_t sizeof_rb_iseq_t(void) {
80
+ return sizeof(rb_iseq_t);
81
+ }
82
+
83
+ VALUE ddtrace_iseq_base_label(const void *iseq) {
84
+ return rb_iseq_base_label((const rb_iseq_t *)iseq);
85
+ }
86
+
87
+ VALUE ddtrace_iseq_path(const void *iseq) {
88
+ return rb_iseq_path((const rb_iseq_t *)iseq);
89
+ }
90
+
79
91
  // Queries if the current thread is the owner of the global VM lock.
80
92
  //
81
93
  // @ivoanjo: Ruby has a similarly-named `ruby_thread_has_gvl_p` but that API is insufficient for our needs because it can
@@ -444,27 +456,28 @@ int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, frame_info *st
444
456
  // here.
445
457
  if (ec == NULL) return 0;
446
458
 
459
+ // Avoid sampling dead threads
460
+ if (th->status == THREAD_KILLED) return 0;
461
+
462
+ const rb_control_frame_t *cfp = ec->cfp;
463
+
464
+ // This happens on newly-created threads (we even had a flaky test because of it)
465
+ if (cfp == NULL) return PLACEHOLDER_STACK_IN_NATIVE_CODE;
466
+
447
467
  // I suspect this won't happen for ddtrace, but just-in-case we've imported a potential fix for
448
468
  // https://github.com/ruby/ruby/pull/13643 by assuming that these can be NULL/zero with the cfp being non-NULL yet.
449
469
  if (ec->vm_stack == NULL || ec->vm_stack_size == 0) return 0;
450
470
 
451
- const rb_control_frame_t *cfp = ec->cfp, *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec);
471
+ const rb_control_frame_t *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec);
452
472
  #ifndef NO_JIT_RETURN
453
473
  const rb_control_frame_t *top = cfp;
454
474
  #endif
455
475
  const rb_callable_method_entry_t *cme;
456
476
 
457
- // Avoid sampling dead threads
458
- if (th->status == THREAD_KILLED) return 0;
459
-
460
477
  // `vm_backtrace.c` includes this check in several methods. This happens on newly-created threads, and may
461
478
  // also (not entirely sure) happen on dead threads
462
479
  if (end_cfp == NULL) return PLACEHOLDER_STACK_IN_NATIVE_CODE;
463
480
 
464
- // This should not happen for ddtrace (it can only happen when a thread is still being created), but I've imported
465
- // it from https://github.com/ruby/ruby/pull/7116 in a "just in case" kind of mindset.
466
- if (cfp == NULL) return 0;
467
-
468
481
  // Fix: Skip dummy frame that shows up in main thread.
469
482
  //
470
483
  // According to a comment in `backtrace_each` (`vm_backtrace.c`), there's two dummy frames that we should ignore
@@ -777,15 +790,11 @@ static inline int ddtrace_imemo_type(VALUE imemo) {
777
790
  }
778
791
  #endif
779
792
 
780
- #ifdef USE_GVL_PROFILING_3_2_WORKAROUNDS // Ruby 3.2
793
+ #ifndef HAVE_RUBY_THREAD_STORAGE_API
781
794
  #include "gvl_profiling_helper.h"
782
795
 
783
- gvl_profiling_thread thread_from_thread_object(VALUE thread) {
784
- return (gvl_profiling_thread) {.thread = thread_struct_from_object(thread)};
785
- }
786
-
787
796
  // Hack: In Ruby 3.3+ we attach gvl profiling state to Ruby threads using the
788
- // rb_internal_thread_specific_* APIs. These APIs did not exist on Ruby 3.2. On Ruby 3.2 we instead store the
797
+ // rb_internal_thread_specific_* APIs. These APIs did not exist on Ruby <= 3.2. On Ruby <= 3.2 we instead store the
789
798
  // needed data inside the `rb_thread_t` structure, specifically in `stat_insn_usage` as a Ruby FIXNUM.
790
799
  //
791
800
  // Why `stat_insn_usage`? We needed some per-thread storage, and while looking at the Ruby VM sources I noticed
@@ -793,38 +802,21 @@ static inline int ddtrace_imemo_type(VALUE imemo) {
793
802
  // code. There's a comment attached to it "/* statistics data for profiler */" but other than marking this
794
803
  // field for GC, I could not find any place in the VM commit history or on GitHub where this has ever been used.
795
804
  //
796
- // Thus, since this hack is only for 3.2, which presumably will never see this field either removed or used
797
- // during its remaining maintenance release period we... kinda take it for our own usage. It's ugly, I know...
798
- intptr_t gvl_profiling_state_get(gvl_profiling_thread thread) {
799
- if (thread.thread == NULL) return 0;
800
-
801
- VALUE current_value = ((rb_thread_t *)thread.thread)->stat_insn_usage;
802
- intptr_t result = current_value == Qnil ? 0 : FIX2LONG(current_value);
803
- return result;
804
- }
805
-
806
- void gvl_profiling_state_set(gvl_profiling_thread thread, intptr_t value) {
807
- if (thread.thread == NULL) return;
808
- ((rb_thread_t *)thread.thread)->stat_insn_usage = LONG2FIX(value);
805
+ // Thus, since this hack is only for Ruby <= 3.2, which presumably will never see this field either removed or used
806
+ // we... kinda take it for our own usage. It's ugly, I know...
807
+ //
808
+ // 64-bit pointers actually use 48-bit virtual addresses (https://muxup.com/2023q4/storing-data-in-pointers),
809
+ // so we are sure the addresses fit in Fixnums.
810
+ per_thread_context *get_per_thread_context(VALUE thread) {
811
+ VALUE current_value = thread_struct_from_object(thread)->stat_insn_usage;
812
+ return RB_FIXNUM_P(current_value) ? (per_thread_context *) FIX2LONG(current_value) : NULL;
809
813
  }
810
814
 
811
- // Because Ruby 3.2 does not give us the current thread when calling the RUBY_INTERNAL_THREAD_EVENT_READY and
812
- // RUBY_INTERNAL_THREAD_EVENT_RESUMED APIs, we need to figure out this info ourselves.
813
- //
814
- // Specifically, this method was created to be called from a RUBY_INTERNAL_THREAD_EVENT_RESUMED callback --
815
- // when it's triggered, we know the thread the code gets executed on is holding the GVL, so we use this
816
- // opportunity to initialize our thread-local value.
817
- gvl_profiling_thread gvl_profiling_state_maybe_initialize(void) {
818
- gvl_profiling_thread current_thread = gvl_waiting_tls;
819
-
820
- if (current_thread.thread == NULL) {
821
- // threads.sched.running is the thread currently holding the GVL, which when this gets executed is the
822
- // current thread!
823
- current_thread = (gvl_profiling_thread) {.thread = (void *) rb_current_ractor()->threads.sched.running};
824
- gvl_waiting_tls = current_thread;
815
+ void set_per_thread_context(VALUE thread, per_thread_context *value) {
816
+ if (!RB_FIXABLE((intptr_t) value)) {
817
+ rb_bug("per_thread_context pointer does not fit in a Fixnum: %p", value);
825
818
  }
826
-
827
- return current_thread;
819
+ thread_struct_from_object(thread)->stat_insn_usage = value ? LONG2FIX((intptr_t) value) : Qfalse;
828
820
  }
829
821
  #endif
830
822
 
@@ -879,3 +871,8 @@ bool is_raised_flag_set(VALUE thread) { return thread_struct_from_object(thread)
879
871
  VALUE current_fiber_for(DDTRACE_UNUSED VALUE thread) { rb_raise(rb_eRuntimeError, "Not implemented for Ruby < 3.1"); }
880
872
  void self_test_current_fiber_for(void) { } // Nothing to do
881
873
  #endif
874
+
875
+ bool pathobj_is_null(VALUE iseq) {
876
+ const rb_iseq_t *iseq_ptr = (const rb_iseq_t *) iseq;
877
+ return ISEQ_BODY(iseq_ptr)->location.pathobj == 0;
878
+ }
@@ -47,6 +47,10 @@ VALUE thread_name_for(VALUE thread);
47
47
 
48
48
  int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, frame_info *stack_buffer);
49
49
 
50
+ size_t sizeof_rb_iseq_t(void);
51
+ VALUE ddtrace_iseq_base_label(const void *iseq);
52
+ VALUE ddtrace_iseq_path(const void *iseq);
53
+
50
54
  // Returns true if the current thread belongs to the main Ractor or if Ruby has no Ractor support
51
55
  bool ddtrace_rb_ractor_main_p(void);
52
56
 
@@ -79,3 +83,5 @@ bool is_raised_flag_set(VALUE thread);
79
83
  VALUE current_fiber_for(VALUE thread);
80
84
 
81
85
  void self_test_current_fiber_for(void);
86
+
87
+ bool pathobj_is_null(VALUE iseq);