datadog 2.20.0 → 2.26.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 (310) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +212 -1
  3. data/README.md +0 -1
  4. data/ext/LIBDATADOG_DEVELOPMENT.md +3 -0
  5. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +93 -23
  6. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
  7. data/ext/datadog_profiling_native_extension/collectors_stack.c +21 -5
  8. data/ext/datadog_profiling_native_extension/crashtracking_runtime_stacks.c +239 -0
  9. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +1 -1
  10. data/ext/datadog_profiling_native_extension/extconf.rb +9 -4
  11. data/ext/datadog_profiling_native_extension/heap_recorder.c +1 -1
  12. data/ext/datadog_profiling_native_extension/http_transport.c +1 -0
  13. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +12 -0
  14. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +4 -0
  15. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  16. data/ext/libdatadog_api/datadog_ruby_common.h +1 -1
  17. data/ext/libdatadog_api/ddsketch.c +106 -0
  18. data/ext/libdatadog_api/feature_flags.c +554 -0
  19. data/ext/libdatadog_api/feature_flags.h +5 -0
  20. data/ext/libdatadog_api/init.c +5 -0
  21. data/ext/libdatadog_api/library_config.c +34 -25
  22. data/ext/libdatadog_api/process_discovery.c +24 -18
  23. data/ext/libdatadog_extconf_helpers.rb +1 -1
  24. data/lib/datadog/ai_guard/api_client.rb +82 -0
  25. data/lib/datadog/ai_guard/component.rb +42 -0
  26. data/lib/datadog/ai_guard/configuration/ext.rb +17 -0
  27. data/lib/datadog/ai_guard/configuration/settings.rb +98 -0
  28. data/lib/datadog/ai_guard/configuration.rb +11 -0
  29. data/lib/datadog/ai_guard/evaluation/message.rb +25 -0
  30. data/lib/datadog/ai_guard/evaluation/no_op_result.rb +34 -0
  31. data/lib/datadog/ai_guard/evaluation/request.rb +81 -0
  32. data/lib/datadog/ai_guard/evaluation/result.rb +43 -0
  33. data/lib/datadog/ai_guard/evaluation/tool_call.rb +18 -0
  34. data/lib/datadog/ai_guard/evaluation.rb +72 -0
  35. data/lib/datadog/ai_guard/ext.rb +16 -0
  36. data/lib/datadog/ai_guard.rb +153 -0
  37. data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +26 -0
  38. data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +59 -0
  39. data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +29 -0
  40. data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +26 -0
  41. data/lib/datadog/appsec/api_security/endpoint_collection.rb +10 -0
  42. data/lib/datadog/appsec/api_security/route_extractor.rb +26 -5
  43. data/lib/datadog/appsec/api_security/sampler.rb +7 -4
  44. data/lib/datadog/appsec/assets/blocked.html +8 -0
  45. data/lib/datadog/appsec/assets/blocked.json +1 -1
  46. data/lib/datadog/appsec/assets/blocked.text +3 -1
  47. data/lib/datadog/appsec/assets/waf_rules/README.md +30 -36
  48. data/lib/datadog/appsec/assets/waf_rules/recommended.json +359 -4
  49. data/lib/datadog/appsec/assets/waf_rules/strict.json +43 -2
  50. data/lib/datadog/appsec/assets.rb +1 -1
  51. data/lib/datadog/appsec/autoload.rb +1 -1
  52. data/lib/datadog/appsec/compressed_json.rb +1 -1
  53. data/lib/datadog/appsec/configuration/settings.rb +9 -0
  54. data/lib/datadog/appsec/context.rb +2 -1
  55. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +3 -1
  56. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +3 -2
  57. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +3 -1
  58. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +3 -1
  59. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +9 -4
  60. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +5 -1
  61. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +7 -2
  62. data/lib/datadog/appsec/contrib/rails/patcher.rb +30 -0
  63. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +3 -1
  64. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +10 -4
  65. data/lib/datadog/appsec/event.rb +12 -14
  66. data/lib/datadog/appsec/metrics/collector.rb +19 -3
  67. data/lib/datadog/appsec/metrics/telemetry_exporter.rb +2 -1
  68. data/lib/datadog/appsec/monitor/gateway/watcher.rb +4 -4
  69. data/lib/datadog/appsec/remote.rb +34 -25
  70. data/lib/datadog/appsec/response.rb +18 -4
  71. data/lib/datadog/appsec/security_engine/engine.rb +3 -3
  72. data/lib/datadog/appsec/security_engine/result.rb +29 -9
  73. data/lib/datadog/appsec/security_engine/runner.rb +19 -9
  74. data/lib/datadog/appsec/security_event.rb +5 -7
  75. data/lib/datadog/core/configuration/agent_settings_resolver.rb +4 -4
  76. data/lib/datadog/core/configuration/components.rb +59 -11
  77. data/lib/datadog/core/configuration/config_helper.rb +100 -0
  78. data/lib/datadog/core/configuration/deprecations.rb +36 -0
  79. data/lib/datadog/core/configuration/ext.rb +0 -1
  80. data/lib/datadog/core/configuration/option.rb +38 -43
  81. data/lib/datadog/core/configuration/option_definition.rb +4 -11
  82. data/lib/datadog/core/configuration/options.rb +9 -10
  83. data/lib/datadog/core/configuration/settings.rb +38 -9
  84. data/lib/datadog/core/configuration/stable_config.rb +10 -0
  85. data/lib/datadog/core/configuration/supported_configurations.rb +373 -0
  86. data/lib/datadog/core/configuration.rb +2 -2
  87. data/lib/datadog/core/ddsketch.rb +19 -0
  88. data/lib/datadog/core/deprecations.rb +2 -2
  89. data/lib/datadog/core/environment/cgroup.rb +52 -25
  90. data/lib/datadog/core/environment/container.rb +140 -46
  91. data/lib/datadog/core/environment/ext.rb +7 -2
  92. data/lib/datadog/core/environment/git.rb +2 -2
  93. data/lib/datadog/core/environment/process.rb +87 -0
  94. data/lib/datadog/core/environment/variable_helpers.rb +3 -3
  95. data/lib/datadog/core/environment/yjit.rb +2 -1
  96. data/lib/datadog/core/error.rb +6 -6
  97. data/lib/datadog/core/feature_flags.rb +61 -0
  98. data/lib/datadog/core/metrics/client.rb +2 -2
  99. data/lib/datadog/core/pin.rb +8 -8
  100. data/lib/datadog/core/process_discovery/tracer_memfd.rb +2 -4
  101. data/lib/datadog/core/process_discovery.rb +48 -23
  102. data/lib/datadog/core/rate_limiter.rb +9 -1
  103. data/lib/datadog/core/remote/client/capabilities.rb +7 -0
  104. data/lib/datadog/core/remote/client.rb +14 -6
  105. data/lib/datadog/core/remote/component.rb +10 -10
  106. data/lib/datadog/core/remote/configuration/content.rb +15 -2
  107. data/lib/datadog/core/remote/configuration/digest.rb +14 -7
  108. data/lib/datadog/core/remote/configuration/repository.rb +1 -1
  109. data/lib/datadog/core/remote/configuration/target.rb +13 -6
  110. data/lib/datadog/core/remote/transport/config.rb +4 -25
  111. data/lib/datadog/core/remote/transport/http/config.rb +10 -50
  112. data/lib/datadog/core/remote/transport/http/negotiation.rb +14 -44
  113. data/lib/datadog/core/remote/transport/http.rb +15 -24
  114. data/lib/datadog/core/remote/transport/negotiation.rb +8 -33
  115. data/lib/datadog/core/remote/worker.rb +25 -37
  116. data/lib/datadog/core/runtime/ext.rb +0 -1
  117. data/lib/datadog/core/runtime/metrics.rb +11 -1
  118. data/lib/datadog/core/semaphore.rb +1 -4
  119. data/lib/datadog/core/tag_builder.rb +0 -4
  120. data/lib/datadog/core/tag_normalizer.rb +84 -0
  121. data/lib/datadog/core/telemetry/component.rb +69 -15
  122. data/lib/datadog/core/telemetry/emitter.rb +6 -6
  123. data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +30 -0
  124. data/lib/datadog/core/telemetry/event/app_started.rb +89 -51
  125. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +27 -4
  126. data/lib/datadog/core/telemetry/event.rb +1 -0
  127. data/lib/datadog/core/telemetry/logger.rb +2 -2
  128. data/lib/datadog/core/telemetry/logging.rb +2 -8
  129. data/lib/datadog/core/telemetry/metrics_manager.rb +9 -0
  130. data/lib/datadog/core/telemetry/request.rb +17 -3
  131. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +3 -34
  132. data/lib/datadog/core/telemetry/transport/http.rb +21 -16
  133. data/lib/datadog/core/telemetry/transport/telemetry.rb +3 -11
  134. data/lib/datadog/core/telemetry/worker.rb +88 -32
  135. data/lib/datadog/core/transport/ext.rb +2 -0
  136. data/lib/datadog/core/transport/http/api/endpoint.rb +9 -4
  137. data/lib/datadog/core/transport/http/api/instance.rb +4 -21
  138. data/lib/datadog/core/transport/http/builder.rb +9 -5
  139. data/lib/datadog/core/transport/http/client.rb +80 -0
  140. data/lib/datadog/core/transport/http.rb +22 -19
  141. data/lib/datadog/core/transport/response.rb +15 -1
  142. data/lib/datadog/core/transport/transport.rb +90 -0
  143. data/lib/datadog/core/utils/array.rb +29 -0
  144. data/lib/datadog/{appsec/api_security → core/utils}/lru_cache.rb +10 -21
  145. data/lib/datadog/core/utils/network.rb +22 -1
  146. data/lib/datadog/core/utils/only_once_successful.rb +8 -2
  147. data/lib/datadog/core/utils/safe_dup.rb +2 -2
  148. data/lib/datadog/core/utils/sequence.rb +2 -0
  149. data/lib/datadog/core/utils/time.rb +1 -1
  150. data/lib/datadog/core/utils.rb +2 -0
  151. data/lib/datadog/core/workers/async.rb +10 -1
  152. data/lib/datadog/core/workers/interval_loop.rb +44 -3
  153. data/lib/datadog/core/workers/polling.rb +2 -0
  154. data/lib/datadog/core/workers/queue.rb +100 -1
  155. data/lib/datadog/core.rb +2 -0
  156. data/lib/datadog/data_streams/configuration/settings.rb +49 -0
  157. data/lib/datadog/data_streams/configuration.rb +11 -0
  158. data/lib/datadog/data_streams/ext.rb +11 -0
  159. data/lib/datadog/data_streams/extensions.rb +16 -0
  160. data/lib/datadog/data_streams/pathway_context.rb +169 -0
  161. data/lib/datadog/data_streams/processor.rb +509 -0
  162. data/lib/datadog/data_streams/transport/http/stats.rb +52 -0
  163. data/lib/datadog/data_streams/transport/http.rb +40 -0
  164. data/lib/datadog/data_streams/transport/stats.rb +46 -0
  165. data/lib/datadog/data_streams.rb +100 -0
  166. data/lib/datadog/di/boot.rb +7 -3
  167. data/lib/datadog/di/component.rb +14 -16
  168. data/lib/datadog/di/context.rb +70 -0
  169. data/lib/datadog/di/contrib/active_record.rb +30 -5
  170. data/lib/datadog/di/el/compiler.rb +168 -0
  171. data/lib/datadog/di/el/evaluator.rb +159 -0
  172. data/lib/datadog/di/el/expression.rb +42 -0
  173. data/lib/datadog/di/el.rb +5 -0
  174. data/lib/datadog/di/error.rb +34 -0
  175. data/lib/datadog/di/instrumenter.rb +189 -55
  176. data/lib/datadog/di/logger.rb +2 -2
  177. data/lib/datadog/di/probe.rb +55 -15
  178. data/lib/datadog/di/probe_builder.rb +41 -2
  179. data/lib/datadog/di/probe_file_loader/railtie.rb +1 -1
  180. data/lib/datadog/di/probe_file_loader.rb +1 -1
  181. data/lib/datadog/di/probe_manager.rb +50 -35
  182. data/lib/datadog/di/probe_notification_builder.rb +121 -70
  183. data/lib/datadog/di/probe_notifier_worker.rb +5 -5
  184. data/lib/datadog/di/proc_responder.rb +32 -0
  185. data/lib/datadog/di/remote.rb +89 -84
  186. data/lib/datadog/di/serializer.rb +151 -7
  187. data/lib/datadog/di/transport/diagnostics.rb +8 -36
  188. data/lib/datadog/di/transport/http/diagnostics.rb +1 -33
  189. data/lib/datadog/di/transport/http/input.rb +1 -33
  190. data/lib/datadog/di/transport/http.rb +32 -17
  191. data/lib/datadog/di/transport/input.rb +67 -34
  192. data/lib/datadog/di.rb +61 -5
  193. data/lib/datadog/error_tracking/filters.rb +2 -2
  194. data/lib/datadog/kit/appsec/events/v2.rb +2 -3
  195. data/lib/datadog/open_feature/component.rb +60 -0
  196. data/lib/datadog/open_feature/configuration.rb +27 -0
  197. data/lib/datadog/open_feature/evaluation_engine.rb +70 -0
  198. data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
  199. data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
  200. data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
  201. data/lib/datadog/open_feature/exposures/event.rb +60 -0
  202. data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
  203. data/lib/datadog/open_feature/exposures/worker.rb +116 -0
  204. data/lib/datadog/open_feature/ext.rb +14 -0
  205. data/lib/datadog/open_feature/native_evaluator.rb +38 -0
  206. data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
  207. data/lib/datadog/open_feature/provider.rb +141 -0
  208. data/lib/datadog/open_feature/remote.rb +67 -0
  209. data/lib/datadog/open_feature/resolution_details.rb +35 -0
  210. data/lib/datadog/open_feature/transport.rb +70 -0
  211. data/lib/datadog/open_feature.rb +19 -0
  212. data/lib/datadog/opentelemetry/api/baggage.rb +1 -1
  213. data/lib/datadog/opentelemetry/configuration/settings.rb +159 -0
  214. data/lib/datadog/opentelemetry/metrics.rb +117 -0
  215. data/lib/datadog/opentelemetry/sdk/configurator.rb +26 -2
  216. data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +35 -0
  217. data/lib/datadog/opentelemetry.rb +3 -0
  218. data/lib/datadog/profiling/collectors/code_provenance.rb +41 -7
  219. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +3 -2
  220. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -1
  221. data/lib/datadog/profiling/collectors/info.rb +6 -5
  222. data/lib/datadog/profiling/component.rb +12 -11
  223. data/lib/datadog/profiling/ext/dir_monkey_patches.rb +18 -0
  224. data/lib/datadog/profiling/ext.rb +2 -1
  225. data/lib/datadog/profiling/http_transport.rb +5 -2
  226. data/lib/datadog/profiling/profiler.rb +4 -0
  227. data/lib/datadog/profiling/tag_builder.rb +36 -3
  228. data/lib/datadog/profiling/tasks/exec.rb +2 -2
  229. data/lib/datadog/profiling.rb +1 -2
  230. data/lib/datadog/single_step_instrument.rb +1 -1
  231. data/lib/datadog/tracing/component.rb +6 -17
  232. data/lib/datadog/tracing/configuration/dynamic.rb +2 -2
  233. data/lib/datadog/tracing/configuration/ext.rb +9 -3
  234. data/lib/datadog/tracing/configuration/settings.rb +89 -10
  235. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +4 -4
  236. data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -2
  237. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +21 -7
  238. data/lib/datadog/tracing/contrib/active_job/patcher.rb +5 -1
  239. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +4 -2
  240. data/lib/datadog/tracing/contrib/component.rb +2 -2
  241. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -1
  242. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +11 -3
  243. data/lib/datadog/tracing/contrib/extensions.rb +10 -2
  244. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +11 -7
  245. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +7 -3
  246. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +7 -0
  247. data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
  248. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +84 -43
  249. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +11 -3
  250. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +11 -3
  251. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +11 -3
  252. data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +66 -0
  253. data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +66 -0
  254. data/lib/datadog/tracing/contrib/kafka/patcher.rb +14 -0
  255. data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
  256. data/lib/datadog/tracing/contrib/karafka/monitor.rb +11 -0
  257. data/lib/datadog/tracing/contrib/karafka/patcher.rb +35 -4
  258. data/lib/datadog/tracing/contrib/rack/middlewares.rb +59 -27
  259. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -0
  260. data/lib/datadog/tracing/contrib/rack/route_inference.rb +53 -0
  261. data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +7 -1
  262. data/lib/datadog/tracing/contrib/rails/ext.rb +2 -1
  263. data/lib/datadog/tracing/contrib/rails/integration.rb +1 -1
  264. data/lib/datadog/tracing/contrib/rails/middlewares.rb +2 -2
  265. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +4 -1
  266. data/lib/datadog/tracing/contrib/roda/instrumentation.rb +3 -1
  267. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -1
  268. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +1 -1
  269. data/lib/datadog/tracing/contrib/status_range_matcher.rb +9 -1
  270. data/lib/datadog/tracing/contrib/utils/quantization/hash.rb +3 -1
  271. data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +27 -0
  272. data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +48 -0
  273. data/lib/datadog/tracing/contrib/waterdrop/ext.rb +17 -0
  274. data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
  275. data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
  276. data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +49 -0
  277. data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
  278. data/lib/datadog/tracing/contrib/waterdrop.rb +41 -0
  279. data/lib/datadog/tracing/contrib.rb +1 -0
  280. data/lib/datadog/tracing/diagnostics/environment_logger.rb +1 -1
  281. data/lib/datadog/tracing/distributed/baggage.rb +3 -2
  282. data/lib/datadog/tracing/metadata/ext.rb +9 -1
  283. data/lib/datadog/tracing/remote.rb +1 -9
  284. data/lib/datadog/tracing/sampling/priority_sampler.rb +3 -1
  285. data/lib/datadog/tracing/span.rb +1 -1
  286. data/lib/datadog/tracing/span_event.rb +2 -2
  287. data/lib/datadog/tracing/span_operation.rb +20 -9
  288. data/lib/datadog/tracing/trace_operation.rb +44 -6
  289. data/lib/datadog/tracing/tracer.rb +42 -16
  290. data/lib/datadog/tracing/transport/http/client.rb +12 -26
  291. data/lib/datadog/tracing/transport/http/traces.rb +2 -50
  292. data/lib/datadog/tracing/transport/http.rb +15 -9
  293. data/lib/datadog/tracing/transport/io/client.rb +1 -1
  294. data/lib/datadog/tracing/transport/trace_formatter.rb +11 -0
  295. data/lib/datadog/tracing/transport/traces.rb +9 -71
  296. data/lib/datadog/tracing/workers/trace_writer.rb +5 -0
  297. data/lib/datadog/tracing/writer.rb +1 -0
  298. data/lib/datadog/version.rb +2 -2
  299. data/lib/datadog.rb +3 -0
  300. metadata +110 -24
  301. data/ext/libdatadog_api/macos_development.md +0 -26
  302. data/lib/datadog/core/remote/transport/http/api.rb +0 -53
  303. data/lib/datadog/core/remote/transport/http/client.rb +0 -49
  304. data/lib/datadog/core/telemetry/transport/http/api.rb +0 -43
  305. data/lib/datadog/core/telemetry/transport/http/client.rb +0 -49
  306. data/lib/datadog/core/transport/http/api/spec.rb +0 -36
  307. data/lib/datadog/di/transport/http/api.rb +0 -42
  308. data/lib/datadog/di/transport/http/client.rb +0 -47
  309. data/lib/datadog/opentelemetry/api/baggage.rbs +0 -26
  310. data/lib/datadog/tracing/transport/http/api.rb +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b5e6a8c0374f599db43eabbbee53ea6a9e0b4079b04880e81298b8f4aa55545
4
- data.tar.gz: ca1d8964d2e12768e405a0c70062dae7420f8a53d73b32bdb163c8b5dd38d794
3
+ metadata.gz: cbf89a9582401ec9fcab36ed1c165ccd447e286085668c768c4df83b5dd27d81
4
+ data.tar.gz: 0c915a22c6ba56f7d39cd03a278466100e72769ac013bb26e9bd2204b4f280ee
5
5
  SHA512:
6
- metadata.gz: 77f707de1847f987a71dfd13401c07260fc1b33997b8033bb42c466cbe55af1177f30fb4f8aaf17d36f5aa7dec2c25b87961f7a38b013e0cbd27d62ab3e8c3fa
7
- data.tar.gz: 4cf002b5b6fd6e2ca6dc2870409115624768f1f0b0d0556bea760117d8298d0657efff39bd8c2d1c8b23d03bbbf0e8ecb2c1735f6f1d55df2ca963359bf1631f
6
+ metadata.gz: 1d2fefe85cab7cff7273196e57638a62da64b6ab0f84b0a350266b0adbc64ae57249d1ab6beb74bfe0d42a233f5b36855a4210ffeb69573fa4cafa2decc12820
7
+ data.tar.gz: 6b41c594384690eed2a84f1e8046046a72bb29c276e87d6cf048b34df2d24cf54725526f0d6eebed0a523f4334385a1f796cba8a6c1112e46e5d58787410611d
data/CHANGELOG.md CHANGED
@@ -2,6 +2,140 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [2.26.0] - 2026-01-16
6
+
7
+ ### Added
8
+
9
+ * Core: Add process tags to runtime metrics when `DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED` is enabled. ([#5210][])
10
+ * SSI: Add experimental dependency injection validation.
11
+
12
+ ### Changed
13
+
14
+ * Profiling: Improve profiler error reporting. ([#5237][])
15
+ * SSI: Improve injection debug error reporting. ([#5238][])
16
+
17
+ ## [2.25.0] - 2026-01-13
18
+
19
+ ### Added
20
+
21
+ AI Guard: Add SDK for evaluating the safety of user messages and assistant commands for LLM session ([#5144][])
22
+
23
+ ### Changed
24
+
25
+ Core: Bump minimum version of `datadog-ruby_core_source` dependency ([#5215][])
26
+
27
+ ### Fixed
28
+
29
+ AppSec: Fix processing of numeric data for WAF and RASP checks ([#5222][])
30
+
31
+ ## [2.24.0] - 2026-01-08
32
+
33
+ ### Added
34
+
35
+ * Core: Add support for installing the gem on Ruby 4.0.x stable ([#5157][])
36
+ * Tracing: Add origin detection using extra headers and the `DD_EXTERNAL_ENV` variable. ([#5028][])
37
+ * Dynamic Instrumentation: Add one-click enablement support ([#5150][])
38
+ * SSI: Add support for Bundler deployment mode ([#5053][])
39
+ * SSI: Report UI-oriented injection results ([#5053][])
40
+ * SSI: Guard against Bundler global force_ruby_platform ([#5053][])
41
+ * SSI: Guard against Bundler 4.0 and Bundler 2.7 in 4.0 mode ([#5053][])
42
+ * SSI: Guard against Ruby 3.5+ ([#5053][])
43
+
44
+ ### Changed
45
+
46
+ * Profiling: Remove profiler warning related to the Ractor issue ([#5194][])
47
+ * Profiling: Disable heap profiling on Ruby 4 due to incompatibility ([#5148][])
48
+ * Dynamic Instrumentation: Stop using customer-provided time provider for method duration calculation ([#5153][])
49
+ * Live Debugger / Dynamic Instrumentation: Improve probe instrumentation ([#5165][])
50
+ * Live Debugger / Dynamic Instrumentation: Improve instrumentation reliability for probes ([#5169][])
51
+
52
+ ### Fixed
53
+
54
+ * Core: Improve reliability of worker shutdown ([#5176][])
55
+ * Core: Fix RDoc error when installing the `datadog` gem ([#5145][])
56
+ * Tracing: Ensure `Tracing.continue_from!` keeps the active trace for the full block duration. ([#4941][])
57
+ * Profiling: Fix and refine profiler thread state categorization for Ruby 4 ([#5197][])
58
+ * Profiling: Fix profiler error triggering `Bundler::PermissionError` ([#5146][])
59
+ * Live Debugger / Dynamic Instrumentation: Fix Live Debugger and Dynamic Instrumentation UI for forking web servers ([#5159][])
60
+ * Live Debugger / Dynamic Instrumentation: Fix method probe leak when a referenced class loads after the probe reaches the application ([#5168][])
61
+
62
+ ## [2.23.0] - 2025-12-11
63
+
64
+ ### Added
65
+
66
+ * Tracing: Add process tags to trace payloads with `DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED` environment variable ([#5033][])
67
+ * Tracing: Integrations: Add Data Streams Monitoring (DSM) instrumentation to Waterdrop producers ([#5031][])
68
+ * Tracing: Open Telemetry: Add OpenTelemetry metrics support with OTLP exporters using `DD_METRICS_OTEL_ENABLED` and standard OpenTelemetry environment variables ([#5021][])
69
+ * Tracing: Add `http.endpoint` tag which contains the route whenever routing info is available, and falls back to route inferred from the request path ([#4995][])
70
+ * Tracing: Add configuration of HTTP client and server error ranges via `DD_TRACE_HTTP_CLIENT_ERROR_STATUSES` and `DD_TRACE_HTTP_SERVER_ERROR_STATUSES` ([#4991][])
71
+ * Tracing: Integrations: Add Data Streams Monitoring for `ruby-kafka` and `karafka` consumers with optional manual instrumentation ([#4901][])
72
+ * Dynamic Instrumentation: Add support for Hash length operations in expression language ([#5019][])
73
+ * AppSec: Add unique security response identifier in the response body for blocked requests ([#5049][])
74
+ * AppSec: Add support for processor overrides and custom data scanners ([#5044][])
75
+ * Feature Flags: Add new component to support Open Feature SDK ([#5054][], [#5024][])
76
+
77
+ ### Changed
78
+
79
+ * Core: Update minimum `datadog-ruby_core_source` dependency to 3.4.2 ([#5122][])
80
+ * Core: Update `libdatadog` dependency to version 24.0.1 ([#5058][], [#5045][], [#5020][])
81
+ * Tracing: Treat IPs from `100.65.0.0/10` range as private. ([#4975][])
82
+
83
+ ### Fixed
84
+
85
+ * Live Debugger / Dynamic Instrumentation: Fix issues delivering large quantities of snapshots ([#5086][])
86
+ * Tracing: Integrations: Fix `NoMethodError` in GraphQL integration when error has no `locations`. ([#5025][])
87
+ * Tracing: Integrations: Fix `http.route` tag for Rack applications mounted inside Rails. ([#4988][])
88
+ * Profiling: Fix profiler support for Ruby 4.0.0-preview2 ([#5091][])
89
+ * Profiling: Fix profiler sleep and wait states not being categorized in timeline ([#5000][])
90
+ * Profiling: Fix profiler not identifying executables with gems they belong to ([#4999][])
91
+ * Stable Config: Fix potential segfault during configuration file parsing ([#5073][])
92
+ * AppSec: Fix route extraction error for Rails 8.1.1+. ([#5042][])
93
+
94
+ ## [2.22.0] - 2025-10-15
95
+
96
+ ### Added
97
+
98
+ * Tracing: Add GraphQL error tracking with OpenTelemetry semantics ([#4864][])
99
+ * AppSec: API Security: Add endpoint collection for Rails ([#4919][])
100
+ * AppSec: Updated WAF rules to add support for JWT analysis ([#4907][])
101
+ * AppSec: Enable Remote Configuration capabilities for fingerprinting, trace tagging and user auto-instrumentation ([#4965][])
102
+ * Dynamic Instrumentation: Support `[@duration][]`, `[@return][]` and `[@exception][]` in message templates ([#4914][])
103
+ * Dynamic Instrumentation: Report evaluation errors to the UI ([#4913][])
104
+ * Dynamic Instrumentation: Support conditions for method probes ([#4909][])
105
+ * Dynamic Instrumentation: Capture exceptions raised by instrumented methods in method probes ([#4906][])
106
+ * Dynamic Instrumentation: Add support for probe conditions for line probes ([#4861][])
107
+
108
+ ### Changed
109
+
110
+ * Core: Upgrade `libdatadog` dependency to 22.0.1 ([#4902][])
111
+ * Tracing: Add `Forwarded` header to the list of headers used for remote IP detection. ([#4969][])
112
+ * AppSec: Update `libbddwaf` to version 1.25.1.0.1 ([#4894][])
113
+ * AppSec: WAF rules can control whether traces are kept or sampled ([#4918][])
114
+ * Dynamic Instrumentation: Evaluate message templates when logging instrumented code ([#4908][])
115
+
116
+ ### Fixed
117
+
118
+ * Core: Improve locking code for remote configuration worker ([#4957][])
119
+ * Dynamic Instrumentation: Emit a single log event for line probes on exception-raising lines ([#4900][])
120
+
121
+ ## [2.21.0] - 2025-09-17
122
+
123
+ ### Added
124
+
125
+ * Tracing: Generate metrics for GraphQL operation execution ([#4862][])
126
+
127
+ ### Changed
128
+
129
+ * Tracing: The `graphql.execute` span resource now includes the operation type ([#4862][])
130
+
131
+ ### Fixed
132
+
133
+ * Tracing: Fix Service Discovery capabilities on forked processes ([#4877][])
134
+ * Tracing: Fix an unclosed trace issue when the Rack application has proxy spans and raises an exception. This caused traces that encompassed multiple requests ([#4779][])
135
+ * AppSec: Fix API Security route extraction for Rails ([#4887][])
136
+ * AppSec: Fix a bug with non-string Hash keys conversion ([#4893][])
137
+ * Dynamic Instrumentation: Fix incorrect template expression evaluation in some cases ([#4884][])
138
+
5
139
  ## [2.20.0] - 2025-09-04
6
140
 
7
141
  ### Added
@@ -3315,7 +3449,13 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
3315
3449
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3316
3450
 
3317
3451
 
3318
- [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.20.0...master
3452
+ [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.26.0...master
3453
+ [2.26.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.25.0...v2.26.0
3454
+ [2.25.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.24.0...v2.25.0
3455
+ [2.24.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.23.0...v2.24.0
3456
+ [2.23.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.22.0...v2.23.0
3457
+ [2.22.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.21.0...v2.22.0
3458
+ [2.21.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.20.0...v2.21.0
3319
3459
  [2.20.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.19.0...v2.20.0
3320
3460
  [2.19.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.18.0...v2.19.0
3321
3461
  [2.18.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.17.0...v2.18.0
@@ -4894,6 +5034,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4894
5034
  [#4771]: https://github.com/DataDog/dd-trace-rb/issues/4771
4895
5035
  [#4772]: https://github.com/DataDog/dd-trace-rb/issues/4772
4896
5036
  [#4776]: https://github.com/DataDog/dd-trace-rb/issues/4776
5037
+ [#4779]: https://github.com/DataDog/dd-trace-rb/issues/4779
4897
5038
  [#4783]: https://github.com/DataDog/dd-trace-rb/issues/4783
4898
5039
  [#4785]: https://github.com/DataDog/dd-trace-rb/issues/4785
4899
5040
  [#4786]: https://github.com/DataDog/dd-trace-rb/issues/4786
@@ -4909,7 +5050,74 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4909
5050
  [#4838]: https://github.com/DataDog/dd-trace-rb/issues/4838
4910
5051
  [#4848]: https://github.com/DataDog/dd-trace-rb/issues/4848
4911
5052
  [#4851]: https://github.com/DataDog/dd-trace-rb/issues/4851
5053
+ [#4861]: https://github.com/DataDog/dd-trace-rb/issues/4861
5054
+ [#4862]: https://github.com/DataDog/dd-trace-rb/issues/4862
4912
5055
  [#4863]: https://github.com/DataDog/dd-trace-rb/issues/4863
5056
+ [#4864]: https://github.com/DataDog/dd-trace-rb/issues/4864
5057
+ [#4877]: https://github.com/DataDog/dd-trace-rb/issues/4877
5058
+ [#4884]: https://github.com/DataDog/dd-trace-rb/issues/4884
5059
+ [#4887]: https://github.com/DataDog/dd-trace-rb/issues/4887
5060
+ [#4893]: https://github.com/DataDog/dd-trace-rb/issues/4893
5061
+ [#4894]: https://github.com/DataDog/dd-trace-rb/issues/4894
5062
+ [#4900]: https://github.com/DataDog/dd-trace-rb/issues/4900
5063
+ [#4901]: https://github.com/DataDog/dd-trace-rb/issues/4901
5064
+ [#4902]: https://github.com/DataDog/dd-trace-rb/issues/4902
5065
+ [#4906]: https://github.com/DataDog/dd-trace-rb/issues/4906
5066
+ [#4907]: https://github.com/DataDog/dd-trace-rb/issues/4907
5067
+ [#4908]: https://github.com/DataDog/dd-trace-rb/issues/4908
5068
+ [#4909]: https://github.com/DataDog/dd-trace-rb/issues/4909
5069
+ [#4913]: https://github.com/DataDog/dd-trace-rb/issues/4913
5070
+ [#4914]: https://github.com/DataDog/dd-trace-rb/issues/4914
5071
+ [#4918]: https://github.com/DataDog/dd-trace-rb/issues/4918
5072
+ [#4919]: https://github.com/DataDog/dd-trace-rb/issues/4919
5073
+ [#4941]: https://github.com/DataDog/dd-trace-rb/issues/4941
5074
+ [#4957]: https://github.com/DataDog/dd-trace-rb/issues/4957
5075
+ [#4965]: https://github.com/DataDog/dd-trace-rb/issues/4965
5076
+ [#4969]: https://github.com/DataDog/dd-trace-rb/issues/4969
5077
+ [#4975]: https://github.com/DataDog/dd-trace-rb/issues/4975
5078
+ [#4988]: https://github.com/DataDog/dd-trace-rb/issues/4988
5079
+ [#4991]: https://github.com/DataDog/dd-trace-rb/issues/4991
5080
+ [#4995]: https://github.com/DataDog/dd-trace-rb/issues/4995
5081
+ [#4999]: https://github.com/DataDog/dd-trace-rb/issues/4999
5082
+ [#5000]: https://github.com/DataDog/dd-trace-rb/issues/5000
5083
+ [#5019]: https://github.com/DataDog/dd-trace-rb/issues/5019
5084
+ [#5020]: https://github.com/DataDog/dd-trace-rb/issues/5020
5085
+ [#5021]: https://github.com/DataDog/dd-trace-rb/issues/5021
5086
+ [#5024]: https://github.com/DataDog/dd-trace-rb/issues/5024
5087
+ [#5025]: https://github.com/DataDog/dd-trace-rb/issues/5025
5088
+ [#5028]: https://github.com/DataDog/dd-trace-rb/issues/5028
5089
+ [#5031]: https://github.com/DataDog/dd-trace-rb/issues/5031
5090
+ [#5033]: https://github.com/DataDog/dd-trace-rb/issues/5033
5091
+ [#5042]: https://github.com/DataDog/dd-trace-rb/issues/5042
5092
+ [#5044]: https://github.com/DataDog/dd-trace-rb/issues/5044
5093
+ [#5045]: https://github.com/DataDog/dd-trace-rb/issues/5045
5094
+ [#5049]: https://github.com/DataDog/dd-trace-rb/issues/5049
5095
+ [#5053]: https://github.com/DataDog/dd-trace-rb/issues/5053
5096
+ [#5054]: https://github.com/DataDog/dd-trace-rb/issues/5054
5097
+ [#5058]: https://github.com/DataDog/dd-trace-rb/issues/5058
5098
+ [#5073]: https://github.com/DataDog/dd-trace-rb/issues/5073
5099
+ [#5086]: https://github.com/DataDog/dd-trace-rb/issues/5086
5100
+ [#5091]: https://github.com/DataDog/dd-trace-rb/issues/5091
5101
+ [#5122]: https://github.com/DataDog/dd-trace-rb/issues/5122
5102
+ [#5144]: https://github.com/DataDog/dd-trace-rb/issues/5144
5103
+ [#5145]: https://github.com/DataDog/dd-trace-rb/issues/5145
5104
+ [#5146]: https://github.com/DataDog/dd-trace-rb/issues/5146
5105
+ [#5148]: https://github.com/DataDog/dd-trace-rb/issues/5148
5106
+ [#5150]: https://github.com/DataDog/dd-trace-rb/issues/5150
5107
+ [#5153]: https://github.com/DataDog/dd-trace-rb/issues/5153
5108
+ [#5157]: https://github.com/DataDog/dd-trace-rb/issues/5157
5109
+ [#5159]: https://github.com/DataDog/dd-trace-rb/issues/5159
5110
+ [#5165]: https://github.com/DataDog/dd-trace-rb/issues/5165
5111
+ [#5168]: https://github.com/DataDog/dd-trace-rb/issues/5168
5112
+ [#5169]: https://github.com/DataDog/dd-trace-rb/issues/5169
5113
+ [#5176]: https://github.com/DataDog/dd-trace-rb/issues/5176
5114
+ [#5194]: https://github.com/DataDog/dd-trace-rb/issues/5194
5115
+ [#5197]: https://github.com/DataDog/dd-trace-rb/issues/5197
5116
+ [#5210]: https://github.com/DataDog/dd-trace-rb/issues/5210
5117
+ [#5215]: https://github.com/DataDog/dd-trace-rb/issues/5215
5118
+ [#5222]: https://github.com/DataDog/dd-trace-rb/issues/5222
5119
+ [#5237]: https://github.com/DataDog/dd-trace-rb/issues/5237
5120
+ [#5238]: https://github.com/DataDog/dd-trace-rb/issues/5238
4913
5121
  [@AdrianLC]: https://github.com/AdrianLC
4914
5122
  [@Azure7111]: https://github.com/Azure7111
4915
5123
  [@BabyGroot]: https://github.com/BabyGroot
@@ -4968,6 +5176,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4968
5176
  [@dorner]: https://github.com/dorner
4969
5177
  [@drcapulet]: https://github.com/drcapulet
4970
5178
  [@dudo]: https://github.com/dudo
5179
+ [@duration]: https://github.com/duration
4971
5180
  [@e1senh0rn]: https://github.com/e1senh0rn
4972
5181
  [@ecdemis123]: https://github.com/ecdemis123
4973
5182
  [@elliterate]: https://github.com/elliterate
@@ -4976,6 +5185,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4976
5185
  [@erict-square]: https://github.com/erict-square
4977
5186
  [@errriclee]: https://github.com/errriclee
4978
5187
  [@evan-waters]: https://github.com/evan-waters
5188
+ [@exception]: https://github.com/exception
4979
5189
  [@fledman]: https://github.com/fledman
4980
5190
  [@frsantos]: https://github.com/frsantos
4981
5191
  [@fteem]: https://github.com/fteem
@@ -5033,6 +5243,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
5033
5243
  [@rahul342]: https://github.com/rahul342
5034
5244
  [@randy-girard]: https://github.com/randy-girard
5035
5245
  [@renchap]: https://github.com/renchap
5246
+ [@return]: https://github.com/return
5036
5247
  [@ricbartm]: https://github.com/ricbartm
5037
5248
  [@roccoblues]: https://github.com/roccoblues
5038
5249
  [@rqz13]: https://github.com/rqz13
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # Datadog Trace Client
2
2
 
3
3
  [![Gem](https://img.shields.io/gem/v/datadog)](https://rubygems.org/gems/datadog/)
4
- [![codecov](https://codecov.io/gh/DataDog/dd-trace-rb/branch/master/graph/badge.svg)](https://app.codecov.io/gh/DataDog/dd-trace-rb/branch/master)
5
4
  [![YARD documentation](https://img.shields.io/badge/YARD-documentation-blue)][api docs]
6
5
 
7
6
  ``datadog`` is Datadog's client library for Ruby. It includes a suite of tools which provide visibility into the performance and security of Ruby applications, to enable Ruby developers to identify bottlenecks and other issues.
@@ -0,0 +1,3 @@
1
+ # Libdatadog development
2
+
3
+ Moved to <../docs/LibdatadogDevelopment.md>!
@@ -76,8 +76,6 @@
76
76
  //
77
77
  // ---
78
78
 
79
- #define ERR_CLOCK_FAIL "failed to get clock time"
80
-
81
79
  // Maximum allowed value for an allocation weight. Attempts to use higher values will result in clamping.
82
80
  // See https://docs.google.com/document/d/1lWLB714wlLBBq6T4xZyAc4a5wtWhSmr4-hgiPKeErlA/edit#heading=h.ugp0zxcj5iqh
83
81
  // (Datadog-only link) for research backing the choice of this value.
@@ -117,6 +115,7 @@ typedef struct {
117
115
  // When something goes wrong during sampling, we record the Ruby exception here, so that it can be "re-raised" on
118
116
  // the CpuAndWallTimeWorker thread
119
117
  VALUE failure_exception;
118
+ const char *failure_exception_during_operation;
120
119
  // Used by `_native_stop` to flag the worker thread to start (see comment on `_native_sampling_loop`)
121
120
  VALUE stop_thread;
122
121
 
@@ -191,17 +190,17 @@ static VALUE _native_initialize(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _sel
191
190
  static void cpu_and_wall_time_worker_typed_data_mark(void *state_ptr);
192
191
  static VALUE _native_sampling_loop(VALUE self, VALUE instance);
193
192
  static VALUE _native_stop(DDTRACE_UNUSED VALUE _self, VALUE self_instance, VALUE worker_thread);
194
- static VALUE stop(VALUE self_instance, VALUE optional_exception);
195
- static void stop_state(cpu_and_wall_time_worker_state *state, VALUE optional_exception);
193
+ static VALUE stop(VALUE self_instance, VALUE optional_exception, const char *optional_exception_during_operation);
194
+ static void stop_state(cpu_and_wall_time_worker_state *state, VALUE optional_exception, const char *optional_operation_name);
196
195
  static void handle_sampling_signal(DDTRACE_UNUSED int _signal, DDTRACE_UNUSED siginfo_t *_info, DDTRACE_UNUSED void *_ucontext);
197
196
  static void *run_sampling_trigger_loop(void *state_ptr);
198
197
  static void interrupt_sampling_trigger_loop(void *state_ptr);
199
198
  static void sample_from_postponed_job(DDTRACE_UNUSED void *_unused);
200
199
  static VALUE rescued_sample_from_postponed_job(VALUE self_instance);
201
- static VALUE handle_sampling_failure(VALUE self_instance, VALUE exception);
202
200
  static VALUE _native_current_sigprof_signal_handler(DDTRACE_UNUSED VALUE self);
203
201
  static VALUE release_gvl_and_run_sampling_trigger_loop(VALUE instance);
204
202
  static VALUE _native_is_running(DDTRACE_UNUSED VALUE self, VALUE instance);
203
+ static VALUE _native_failure_exception_during_operation(DDTRACE_UNUSED VALUE self, VALUE instance);
205
204
  static void testing_signal_handler(DDTRACE_UNUSED int _signal, DDTRACE_UNUSED siginfo_t *_info, DDTRACE_UNUSED void *_ucontext);
206
205
  static VALUE _native_install_testing_signal_handler(DDTRACE_UNUSED VALUE self);
207
206
  static VALUE _native_remove_testing_signal_handler(DDTRACE_UNUSED VALUE self);
@@ -209,7 +208,12 @@ static VALUE _native_trigger_sample(DDTRACE_UNUSED VALUE self);
209
208
  static VALUE _native_gc_tracepoint(DDTRACE_UNUSED VALUE self, VALUE instance);
210
209
  static void on_gc_event(VALUE tracepoint_data, DDTRACE_UNUSED void *unused);
211
210
  static void after_gc_from_postponed_job(DDTRACE_UNUSED void *_unused);
212
- static VALUE safely_call(VALUE (*function_to_call_safely)(VALUE), VALUE function_to_call_safely_arg, VALUE instance);
211
+ static VALUE safely_call(
212
+ VALUE (*function_to_call_safely)(VALUE),
213
+ VALUE function_to_call_safely_arg,
214
+ VALUE instance,
215
+ VALUE (*handle_sampling_failure)(VALUE, VALUE)
216
+ );
213
217
  static VALUE _native_simulate_handle_sampling_signal(DDTRACE_UNUSED VALUE self);
214
218
  static VALUE _native_simulate_sample_from_postponed_job(DDTRACE_UNUSED VALUE self);
215
219
  static VALUE _native_reset_after_fork(DDTRACE_UNUSED VALUE self, VALUE instance);
@@ -226,6 +230,7 @@ static void disable_tracepoints(cpu_and_wall_time_worker_state *state);
226
230
  static VALUE _native_with_blocked_sigprof(DDTRACE_UNUSED VALUE self);
227
231
  static VALUE rescued_sample_allocation(VALUE tracepoint_data);
228
232
  static void delayed_error(cpu_and_wall_time_worker_state *state, const char *error);
233
+ static void delayed_error_clock_failure(cpu_and_wall_time_worker_state *state);
229
234
  static VALUE _native_delayed_error(DDTRACE_UNUSED VALUE self, VALUE instance, VALUE error_msg);
230
235
  static VALUE _native_hold_signals(DDTRACE_UNUSED VALUE self);
231
236
  static VALUE _native_resume_signals(DDTRACE_UNUSED VALUE self);
@@ -235,6 +240,10 @@ static void after_gvl_running_from_postponed_job(DDTRACE_UNUSED void *_unused);
235
240
  #endif
236
241
  static VALUE rescued_after_gvl_running_from_postponed_job(VALUE self_instance);
237
242
  static VALUE _native_gvl_profiling_hook_active(DDTRACE_UNUSED VALUE self, VALUE instance);
243
+ static VALUE handle_sampling_failure_rescued_sample_from_postponed_job(VALUE self_instance, VALUE exception);
244
+ static VALUE handle_sampling_failure_thread_context_collector_sample_after_gc(VALUE self_instance, VALUE exception);
245
+ static VALUE handle_sampling_failure_rescued_sample_allocation(VALUE self_instance, VALUE exception);
246
+ static VALUE handle_sampling_failure_rescued_after_gvl_running_from_postponed_job(VALUE self_instance, VALUE exception);
238
247
  static inline void during_sample_enter(cpu_and_wall_time_worker_state* state);
239
248
  static inline void during_sample_exit(cpu_and_wall_time_worker_state* state);
240
249
 
@@ -262,6 +271,7 @@ static inline void during_sample_exit(cpu_and_wall_time_worker_state* state);
262
271
  // (e.g. signal handler) where it's impossible or just awkward to pass it as an argument.
263
272
  static VALUE active_sampler_instance = Qnil;
264
273
  static cpu_and_wall_time_worker_state *active_sampler_instance_state = NULL;
274
+ static VALUE clock_failure_exception_class = Qnil;
265
275
 
266
276
  // See handle_sampling_signal for details on what this does
267
277
  #ifdef NO_POSTPONED_TRIGGER
@@ -299,6 +309,8 @@ void collectors_cpu_and_wall_time_worker_init(VALUE profiling_module) {
299
309
  VALUE collectors_cpu_and_wall_time_worker_class = rb_define_class_under(collectors_module, "CpuAndWallTimeWorker", rb_cObject);
300
310
  // Hosts methods used for testing the native code using RSpec
301
311
  VALUE testing_module = rb_define_module_under(collectors_cpu_and_wall_time_worker_class, "Testing");
312
+ clock_failure_exception_class = rb_define_class_under(collectors_cpu_and_wall_time_worker_class, "ClockFailure", rb_eRuntimeError);
313
+ rb_gc_register_mark_object(clock_failure_exception_class);
302
314
 
303
315
  // Instances of the CpuAndWallTimeWorker class are "TypedData" objects.
304
316
  // "TypedData" objects are special objects in the Ruby VM that can wrap C structs.
@@ -318,6 +330,7 @@ void collectors_cpu_and_wall_time_worker_init(VALUE profiling_module) {
318
330
  rb_define_singleton_method(collectors_cpu_and_wall_time_worker_class, "_native_stats_reset_not_thread_safe", _native_stats_reset_not_thread_safe, 1);
319
331
  rb_define_singleton_method(collectors_cpu_and_wall_time_worker_class, "_native_allocation_count", _native_allocation_count, 0);
320
332
  rb_define_singleton_method(collectors_cpu_and_wall_time_worker_class, "_native_is_running?", _native_is_running, 1);
333
+ rb_define_singleton_method(collectors_cpu_and_wall_time_worker_class, "_native_failure_exception_during_operation", _native_failure_exception_during_operation, 1);
321
334
  rb_define_singleton_method(testing_module, "_native_current_sigprof_signal_handler", _native_current_sigprof_signal_handler, 0);
322
335
  rb_define_singleton_method(collectors_cpu_and_wall_time_worker_class, "_native_hold_signals", _native_hold_signals, 0);
323
336
  rb_define_singleton_method(collectors_cpu_and_wall_time_worker_class, "_native_resume_signals", _native_resume_signals, 0);
@@ -370,6 +383,7 @@ static VALUE _native_new(VALUE klass) {
370
383
 
371
384
  atomic_init(&state->should_run, false);
372
385
  state->failure_exception = Qnil;
386
+ state->failure_exception_during_operation = NULL;
373
387
  state->stop_thread = Qnil;
374
388
 
375
389
  during_sample_exit(state);
@@ -554,22 +568,24 @@ static VALUE _native_stop(DDTRACE_UNUSED VALUE _self, VALUE self_instance, VALUE
554
568
 
555
569
  state->stop_thread = worker_thread;
556
570
 
557
- return stop(self_instance, /* optional_exception: */ Qnil);
571
+ return stop(self_instance, Qnil, NULL);
558
572
  }
559
573
 
560
- static void stop_state(cpu_and_wall_time_worker_state *state, VALUE optional_exception) {
574
+ // When providing an `optional_exception`, `optional_exception_during_operation` should be provided as well
575
+ static void stop_state(cpu_and_wall_time_worker_state *state, VALUE optional_exception, const char *optional_exception_during_operation) {
561
576
  atomic_store(&state->should_run, false);
562
577
  state->failure_exception = optional_exception;
578
+ state->failure_exception_during_operation = optional_exception_during_operation;
563
579
 
564
580
  // Disable the tracepoints as soon as possible, so the VM doesn't keep on calling them
565
581
  disable_tracepoints(state);
566
582
  }
567
583
 
568
- static VALUE stop(VALUE self_instance, VALUE optional_exception) {
584
+ static VALUE stop(VALUE self_instance, VALUE optional_exception, const char *optional_exception_during_operation) {
569
585
  cpu_and_wall_time_worker_state *state;
570
586
  TypedData_Get_Struct(self_instance, cpu_and_wall_time_worker_state, &cpu_and_wall_time_worker_typed_data, state);
571
587
 
572
- stop_state(state, optional_exception);
588
+ stop_state(state, optional_exception, optional_exception_during_operation);
573
589
 
574
590
  return Qtrue;
575
591
  }
@@ -726,7 +742,12 @@ static void sample_from_postponed_job(DDTRACE_UNUSED void *_unused) {
726
742
  during_sample_enter(state);
727
743
 
728
744
  // Rescue against any exceptions that happen during sampling
729
- safely_call(rescued_sample_from_postponed_job, state->self_instance, state->self_instance);
745
+ safely_call(
746
+ rescued_sample_from_postponed_job,
747
+ state->self_instance,
748
+ state->self_instance,
749
+ handle_sampling_failure_rescued_sample_from_postponed_job
750
+ );
730
751
 
731
752
  during_sample_exit(state);
732
753
  }
@@ -763,11 +784,6 @@ static VALUE rescued_sample_from_postponed_job(VALUE self_instance) {
763
784
  return Qnil;
764
785
  }
765
786
 
766
- static VALUE handle_sampling_failure(VALUE self_instance, VALUE exception) {
767
- stop(self_instance, exception);
768
- return Qnil;
769
- }
770
-
771
787
  // This method exists only to enable testing Datadog::Profiling::Collectors::CpuAndWallTimeWorker behavior using RSpec.
772
788
  // It SHOULD NOT be used for other purposes.
773
789
  static VALUE _native_current_sigprof_signal_handler(DDTRACE_UNUSED VALUE self) {
@@ -844,6 +860,15 @@ static VALUE _native_is_running(DDTRACE_UNUSED VALUE self, VALUE instance) {
844
860
  return (state != NULL && is_thread_alive(state->owner_thread) && state->self_instance == instance) ? Qtrue : Qfalse;
845
861
  }
846
862
 
863
+ static VALUE _native_failure_exception_during_operation(DDTRACE_UNUSED VALUE self, VALUE instance) {
864
+ cpu_and_wall_time_worker_state *state;
865
+ TypedData_Get_Struct(instance, cpu_and_wall_time_worker_state, &cpu_and_wall_time_worker_typed_data, state);
866
+
867
+ if (state->failure_exception_during_operation == NULL) return Qnil;
868
+
869
+ return rb_str_new_cstr(state->failure_exception_during_operation);
870
+ }
871
+
847
872
  static void testing_signal_handler(DDTRACE_UNUSED int _signal, DDTRACE_UNUSED siginfo_t *_info, DDTRACE_UNUSED void *_ucontext) {
848
873
  /* Does nothing on purpose */
849
874
  }
@@ -936,14 +961,24 @@ static void after_gc_from_postponed_job(DDTRACE_UNUSED void *_unused) {
936
961
 
937
962
  during_sample_enter(state);
938
963
 
939
- safely_call(thread_context_collector_sample_after_gc, state->thread_context_collector_instance, state->self_instance);
964
+ safely_call(
965
+ thread_context_collector_sample_after_gc,
966
+ state->thread_context_collector_instance,
967
+ state->self_instance,
968
+ handle_sampling_failure_thread_context_collector_sample_after_gc
969
+ );
940
970
 
941
971
  during_sample_exit(state);
942
972
  }
943
973
 
944
974
  // Equivalent to Ruby begin/rescue call, where we call a C function and jump to the exception handler if an
945
975
  // exception gets raised within
946
- static VALUE safely_call(VALUE (*function_to_call_safely)(VALUE), VALUE function_to_call_safely_arg, VALUE instance) {
976
+ static VALUE safely_call(
977
+ VALUE (*function_to_call_safely)(VALUE),
978
+ VALUE function_to_call_safely_arg,
979
+ VALUE instance,
980
+ VALUE (*handle_sampling_failure)(VALUE, VALUE)
981
+ ) {
947
982
  VALUE exception_handler_function_arg = instance;
948
983
  return rb_rescue2(
949
984
  function_to_call_safely,
@@ -1119,7 +1154,7 @@ static VALUE _native_allocation_count(DDTRACE_UNUSED VALUE self) {
1119
1154
  #define HANDLE_CLOCK_FAILURE(call) ({ \
1120
1155
  long _result = (call); \
1121
1156
  if (_result == 0) { \
1122
- delayed_error(state, ERR_CLOCK_FAIL); \
1157
+ delayed_error_clock_failure(state); \
1123
1158
  return; \
1124
1159
  } \
1125
1160
  _result; \
@@ -1203,12 +1238,17 @@ static void on_newobj_event(DDTRACE_UNUSED VALUE unused1, DDTRACE_UNUSED void *u
1203
1238
  during_sample_enter(state);
1204
1239
 
1205
1240
  // Rescue against any exceptions that happen during sampling
1206
- safely_call(rescued_sample_allocation, Qnil, state->self_instance);
1241
+ safely_call(
1242
+ rescued_sample_allocation,
1243
+ Qnil,
1244
+ state->self_instance,
1245
+ handle_sampling_failure_rescued_sample_allocation
1246
+ );
1207
1247
 
1208
1248
  if (state->dynamic_sampling_rate_enabled) {
1209
1249
  long now = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE);
1210
1250
  if (now == 0) {
1211
- delayed_error(state, ERR_CLOCK_FAIL);
1251
+ delayed_error_clock_failure(state);
1212
1252
  // NOTE: Not short-circuiting here to make sure cleanup happens
1213
1253
  }
1214
1254
  uint64_t sampling_time_ns = discrete_dynamic_sampler_after_sample(&state->allocation_sampler, now);
@@ -1284,7 +1324,12 @@ static VALUE rescued_sample_allocation(DDTRACE_UNUSED VALUE unused) {
1284
1324
 
1285
1325
  static void delayed_error(cpu_and_wall_time_worker_state *state, const char *error) {
1286
1326
  // If we can't raise an immediate exception at the calling site, use the asynchronous flow through the main worker loop.
1287
- stop_state(state, rb_exc_new_cstr(rb_eRuntimeError, error));
1327
+ stop_state(state, rb_exc_new_cstr(rb_eRuntimeError, error), "delayed_error");
1328
+ }
1329
+
1330
+ static void delayed_error_clock_failure(cpu_and_wall_time_worker_state *state) {
1331
+ // If we can't raise an immediate exception at the calling site, use the asynchronous flow through the main worker loop.
1332
+ stop_state(state, rb_exc_new_cstr(clock_failure_exception_class, "failed to get clock time"), "delayed_error_clock_failure");
1288
1333
  }
1289
1334
 
1290
1335
  static VALUE _native_delayed_error(DDTRACE_UNUSED VALUE self, VALUE instance, VALUE error_msg) {
@@ -1365,7 +1410,12 @@ static VALUE _native_resume_signals(DDTRACE_UNUSED VALUE self) {
1365
1410
  during_sample_enter(state);
1366
1411
 
1367
1412
  // Rescue against any exceptions that happen during sampling
1368
- safely_call(rescued_after_gvl_running_from_postponed_job, state->self_instance, state->self_instance);
1413
+ safely_call(
1414
+ rescued_after_gvl_running_from_postponed_job,
1415
+ state->self_instance,
1416
+ state->self_instance,
1417
+ handle_sampling_failure_rescued_after_gvl_running_from_postponed_job
1418
+ );
1369
1419
 
1370
1420
  during_sample_exit(state);
1371
1421
  }
@@ -1404,6 +1454,26 @@ static VALUE _native_resume_signals(DDTRACE_UNUSED VALUE self) {
1404
1454
  }
1405
1455
  #endif
1406
1456
 
1457
+ static VALUE handle_sampling_failure_rescued_sample_from_postponed_job(VALUE self_instance, VALUE exception) {
1458
+ stop(self_instance, exception, "rescued_sample_from_postponed_job");
1459
+ return Qnil;
1460
+ }
1461
+
1462
+ static VALUE handle_sampling_failure_thread_context_collector_sample_after_gc(VALUE self_instance, VALUE exception) {
1463
+ stop(self_instance, exception, "thread_context_collector_sample_after_gc");
1464
+ return Qnil;
1465
+ }
1466
+
1467
+ static VALUE handle_sampling_failure_rescued_sample_allocation(VALUE self_instance, VALUE exception) {
1468
+ stop(self_instance, exception, "rescued_sample_allocation");
1469
+ return Qnil;
1470
+ }
1471
+
1472
+ static VALUE handle_sampling_failure_rescued_after_gvl_running_from_postponed_job(VALUE self_instance, VALUE exception) {
1473
+ stop(self_instance, exception, "rescued_after_gvl_running_from_postponed_job");
1474
+ return Qnil;
1475
+ }
1476
+
1407
1477
  static inline void during_sample_enter(cpu_and_wall_time_worker_state* state) {
1408
1478
  // Tell the compiler it's not allowed to reorder the `during_sample` flag with anything that happens after.
1409
1479
  //
@@ -365,7 +365,7 @@ static const rb_data_type_t sampler_typed_data = {
365
365
  };
366
366
 
367
367
  static VALUE _native_new(VALUE klass) {
368
- sampler_state *state = ruby_xcalloc(sizeof(sampler_state), 1);
368
+ sampler_state *state = ruby_xcalloc(1, sizeof(sampler_state));
369
369
 
370
370
  long now_ns = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE);
371
371
  if (now_ns == 0) {
@@ -347,13 +347,19 @@ void sample_thread(
347
347
  } else if (CHARSLICE_EQUALS("select", name_slice)) { // Expected to be Kernel.select
348
348
  state_label->str = DDOG_CHARSLICE_C("waiting");
349
349
  } else if (
350
- CHARSLICE_EQUALS("synchronize", name_slice) || // Expected to be Monitor/Mutex#synchronize
351
- CHARSLICE_EQUALS("lock", name_slice) || // Expected to be Mutex#lock
350
+ CHARSLICE_EQUALS("synchronize", name_slice) || // Expected to be Monitor/Mutex#synchronize on Ruby 2 & 3, and Monitor#synchronize on 4 (Mutex becomes <internal:thread_sync>)
351
+ #ifdef NO_PRIMITIVE_MUTEX_AND_CONDITION_VARIABLE // Ruby < 4
352
+ CHARSLICE_EQUALS("lock", name_slice) || // Expected to be Mutex#lock
353
+ #endif
352
354
  CHARSLICE_EQUALS("join", name_slice) // Expected to be Thread#join
353
355
  ) {
354
356
  state_label->str = DDOG_CHARSLICE_C("blocked");
355
357
  } else if (CHARSLICE_EQUALS("wait_readable", name_slice)) { // Expected to be IO#wait_readable
356
358
  state_label->str = DDOG_CHARSLICE_C("network");
359
+ } else if (CHARSLICE_EQUALS("_native_idle_sampling_loop", name_slice)) { // Expected to be Datadog::Profiler::Collectors::IdleSamplingHelper#_native_idle_sampling_loop
360
+ state_label->str = DDOG_CHARSLICE_C("waiting");
361
+ } else if (CHARSLICE_EQUALS("_native_sampling_loop", name_slice)) { // Expected to be Datadog::Profiler::Collectors::CpuAndWallTimeWorker#_native_sampling_loop
362
+ state_label->str = DDOG_CHARSLICE_C("sleeping");
357
363
  }
358
364
  #ifdef NO_PRIMITIVE_POP // Ruby < 3.2
359
365
  else if (CHARSLICE_EQUALS("pop", name_slice)) { // Expected to be Queue/SizedQueue#pop
@@ -362,9 +368,19 @@ void sample_thread(
362
368
  #endif
363
369
  } else {
364
370
  #ifndef NO_PRIMITIVE_POP // Ruby >= 3.2
365
- // Unlike the above, Ruby actually treats this one specially and gives it a nice file name we can match on!
366
- if (CHARSLICE_EQUALS("pop", name_slice) && CHARSLICE_EQUALS("<internal:thread_sync>", filename_slice)) { // Expected to be Queue/SizedQueue#pop
367
- state_label->str = DDOG_CHARSLICE_C("waiting");
371
+ if (CHARSLICE_EQUALS("<internal:thread_sync>", filename_slice)) {
372
+ if (CHARSLICE_EQUALS("pop", name_slice)) { // Expected to be Queue/SizedQueue#pop
373
+ state_label->str = DDOG_CHARSLICE_C("waiting");
374
+ }
375
+ #ifndef NO_PRIMITIVE_MUTEX_AND_CONDITION_VARIABLE // Ruby >= 4
376
+ else if (CHARSLICE_EQUALS("synchronize", name_slice) || CHARSLICE_EQUALS("lock", name_slice)) { // Expected to be Mutex#lock/synchronize
377
+ state_label->str = DDOG_CHARSLICE_C("blocked");
378
+ } else if (CHARSLICE_EQUALS("sleep", name_slice)) { // Expected to be Mutex#sleep
379
+ state_label->str = DDOG_CHARSLICE_C("sleeping");
380
+ } else if (CHARSLICE_EQUALS("wait", name_slice)) { // Expected to be ConditionVariable#wait
381
+ state_label->str = DDOG_CHARSLICE_C("waiting");
382
+ }
383
+ #endif
368
384
  }
369
385
  #endif
370
386
  }