datadog 2.7.1 → 2.18.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 (441) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +353 -1
  3. data/ext/datadog_profiling_native_extension/clock_id.h +2 -2
  4. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +78 -102
  5. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
  6. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
  7. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +16 -16
  8. data/ext/datadog_profiling_native_extension/collectors_stack.c +235 -57
  9. data/ext/datadog_profiling_native_extension/collectors_stack.h +21 -5
  10. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +376 -156
  11. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +1 -0
  12. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  13. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  14. data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
  15. data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
  16. data/ext/datadog_profiling_native_extension/extconf.rb +14 -8
  17. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +2 -0
  18. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +0 -8
  19. data/ext/datadog_profiling_native_extension/heap_recorder.c +295 -532
  20. data/ext/datadog_profiling_native_extension/heap_recorder.h +6 -8
  21. data/ext/datadog_profiling_native_extension/http_transport.c +64 -98
  22. data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +22 -0
  23. data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +8 -5
  24. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +69 -1
  25. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +16 -4
  26. data/ext/datadog_profiling_native_extension/profiling.c +19 -8
  27. data/ext/datadog_profiling_native_extension/ruby_helpers.c +9 -21
  28. data/ext/datadog_profiling_native_extension/ruby_helpers.h +2 -10
  29. data/ext/datadog_profiling_native_extension/stack_recorder.c +231 -181
  30. data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -2
  31. data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
  32. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
  33. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
  34. data/ext/libdatadog_api/crashtracker.c +17 -15
  35. data/ext/libdatadog_api/crashtracker.h +5 -0
  36. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  37. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  38. data/ext/libdatadog_api/extconf.rb +2 -2
  39. data/ext/libdatadog_api/init.c +15 -0
  40. data/ext/libdatadog_api/library_config.c +164 -0
  41. data/ext/libdatadog_api/library_config.h +25 -0
  42. data/ext/libdatadog_api/macos_development.md +3 -3
  43. data/ext/libdatadog_api/process_discovery.c +112 -0
  44. data/ext/libdatadog_api/process_discovery.h +5 -0
  45. data/ext/libdatadog_extconf_helpers.rb +2 -2
  46. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  47. data/lib/datadog/appsec/actions_handler.rb +49 -0
  48. data/lib/datadog/appsec/anonymizer.rb +16 -0
  49. data/lib/datadog/appsec/api_security/lru_cache.rb +56 -0
  50. data/lib/datadog/appsec/api_security/route_extractor.rb +65 -0
  51. data/lib/datadog/appsec/api_security/sampler.rb +59 -0
  52. data/lib/datadog/appsec/api_security.rb +23 -0
  53. data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
  54. data/lib/datadog/appsec/assets/waf_rules/recommended.json +623 -253
  55. data/lib/datadog/appsec/assets/waf_rules/strict.json +69 -107
  56. data/lib/datadog/appsec/autoload.rb +1 -1
  57. data/lib/datadog/appsec/component.rb +49 -65
  58. data/lib/datadog/appsec/compressed_json.rb +40 -0
  59. data/lib/datadog/appsec/configuration/settings.rb +212 -27
  60. data/lib/datadog/appsec/context.rb +74 -0
  61. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +92 -0
  62. data/lib/datadog/appsec/contrib/active_record/integration.rb +41 -0
  63. data/lib/datadog/appsec/contrib/active_record/patcher.rb +101 -0
  64. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  65. data/lib/datadog/appsec/contrib/devise/configuration.rb +52 -0
  66. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  67. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  68. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
  69. data/lib/datadog/appsec/contrib/devise/patcher.rb +33 -25
  70. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  71. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  72. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +3 -3
  73. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
  74. data/lib/datadog/appsec/contrib/excon/integration.rb +41 -0
  75. data/lib/datadog/appsec/contrib/excon/patcher.rb +28 -0
  76. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +42 -0
  77. data/lib/datadog/appsec/contrib/faraday/connection_patch.rb +22 -0
  78. data/lib/datadog/appsec/contrib/faraday/integration.rb +42 -0
  79. data/lib/datadog/appsec/contrib/faraday/patcher.rb +53 -0
  80. data/lib/datadog/appsec/contrib/faraday/rack_builder_patch.rb +22 -0
  81. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +41 -0
  82. data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +1 -7
  83. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +17 -30
  84. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  85. data/lib/datadog/appsec/contrib/graphql/patcher.rb +0 -3
  86. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  87. data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
  88. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +78 -98
  89. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  90. data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -3
  91. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
  92. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +73 -78
  93. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +16 -33
  94. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  95. data/lib/datadog/appsec/contrib/rails/patcher.rb +25 -38
  96. data/lib/datadog/appsec/contrib/rest_client/integration.rb +45 -0
  97. data/lib/datadog/appsec/contrib/rest_client/patcher.rb +28 -0
  98. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +38 -0
  99. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +31 -68
  100. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  101. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +5 -31
  102. data/lib/datadog/appsec/event.rb +96 -135
  103. data/lib/datadog/appsec/ext.rb +12 -3
  104. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
  105. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  106. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  107. data/lib/datadog/appsec/metrics/collector.rb +38 -0
  108. data/lib/datadog/appsec/metrics/exporter.rb +35 -0
  109. data/lib/datadog/appsec/metrics/telemetry.rb +23 -0
  110. data/lib/datadog/appsec/metrics.rb +13 -0
  111. data/lib/datadog/appsec/monitor/gateway/watcher.rb +52 -32
  112. data/lib/datadog/appsec/processor/rule_loader.rb +30 -36
  113. data/lib/datadog/appsec/remote.rb +31 -57
  114. data/lib/datadog/appsec/response.rb +19 -85
  115. data/lib/datadog/appsec/security_engine/engine.rb +194 -0
  116. data/lib/datadog/appsec/security_engine/result.rb +67 -0
  117. data/lib/datadog/appsec/security_engine/runner.rb +87 -0
  118. data/lib/datadog/appsec/security_engine.rb +9 -0
  119. data/lib/datadog/appsec/security_event.rb +39 -0
  120. data/lib/datadog/appsec/utils.rb +0 -2
  121. data/lib/datadog/appsec.rb +22 -12
  122. data/lib/datadog/auto_instrument.rb +3 -0
  123. data/lib/datadog/core/buffer/random.rb +18 -2
  124. data/lib/datadog/core/configuration/agent_settings.rb +52 -0
  125. data/lib/datadog/core/configuration/agent_settings_resolver.rb +4 -18
  126. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  127. data/lib/datadog/core/configuration/components.rb +74 -32
  128. data/lib/datadog/core/configuration/components_state.rb +23 -0
  129. data/lib/datadog/core/configuration/ext.rb +5 -1
  130. data/lib/datadog/core/configuration/option.rb +81 -45
  131. data/lib/datadog/core/configuration/option_definition.rb +6 -4
  132. data/lib/datadog/core/configuration/options.rb +3 -3
  133. data/lib/datadog/core/configuration/settings.rb +121 -50
  134. data/lib/datadog/core/configuration/stable_config.rb +22 -0
  135. data/lib/datadog/core/configuration.rb +43 -11
  136. data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
  137. data/lib/datadog/core/crashtracking/component.rb +4 -13
  138. data/lib/datadog/core/crashtracking/tag_builder.rb +4 -22
  139. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  140. data/lib/datadog/core/encoding.rb +17 -1
  141. data/lib/datadog/core/environment/agent_info.rb +78 -0
  142. data/lib/datadog/core/environment/cgroup.rb +10 -12
  143. data/lib/datadog/core/environment/container.rb +38 -40
  144. data/lib/datadog/core/environment/ext.rb +6 -6
  145. data/lib/datadog/core/environment/git.rb +1 -0
  146. data/lib/datadog/core/environment/identity.rb +3 -3
  147. data/lib/datadog/core/environment/platform.rb +3 -3
  148. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  149. data/lib/datadog/core/error.rb +11 -9
  150. data/lib/datadog/core/logger.rb +2 -2
  151. data/lib/datadog/core/metrics/client.rb +27 -27
  152. data/lib/datadog/core/metrics/logging.rb +5 -5
  153. data/lib/datadog/core/process_discovery/tracer_memfd.rb +15 -0
  154. data/lib/datadog/core/process_discovery.rb +36 -0
  155. data/lib/datadog/core/rate_limiter.rb +4 -2
  156. data/lib/datadog/core/remote/client/capabilities.rb +6 -0
  157. data/lib/datadog/core/remote/client.rb +107 -92
  158. data/lib/datadog/core/remote/component.rb +18 -19
  159. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  160. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  161. data/lib/datadog/core/remote/configuration/repository.rb +14 -1
  162. data/lib/datadog/core/remote/negotiation.rb +9 -9
  163. data/lib/datadog/core/remote/transport/config.rb +4 -3
  164. data/lib/datadog/core/remote/transport/http/api.rb +13 -18
  165. data/lib/datadog/core/remote/transport/http/client.rb +5 -4
  166. data/lib/datadog/core/remote/transport/http/config.rb +27 -55
  167. data/lib/datadog/core/remote/transport/http/negotiation.rb +8 -51
  168. data/lib/datadog/core/remote/transport/http.rb +25 -94
  169. data/lib/datadog/core/remote/transport/negotiation.rb +17 -4
  170. data/lib/datadog/core/remote/worker.rb +10 -7
  171. data/lib/datadog/core/runtime/metrics.rb +12 -5
  172. data/lib/datadog/core/tag_builder.rb +56 -0
  173. data/lib/datadog/core/telemetry/component.rb +84 -49
  174. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  175. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +66 -0
  176. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  177. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  178. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  179. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  180. data/lib/datadog/core/telemetry/event/app_started.rb +269 -0
  181. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  182. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  183. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  184. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  185. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  186. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  187. data/lib/datadog/core/telemetry/event.rb +17 -383
  188. data/lib/datadog/core/telemetry/ext.rb +1 -0
  189. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  190. data/lib/datadog/core/telemetry/logger.rb +5 -4
  191. data/lib/datadog/core/telemetry/logging.rb +12 -6
  192. data/lib/datadog/core/telemetry/metric.rb +28 -6
  193. data/lib/datadog/core/telemetry/request.rb +4 -4
  194. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  195. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  196. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  197. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  198. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  199. data/lib/datadog/core/telemetry/worker.rb +128 -25
  200. data/lib/datadog/core/transport/http/adapters/net.rb +17 -2
  201. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  202. data/lib/datadog/core/transport/http/adapters/unix_socket.rb +1 -1
  203. data/lib/datadog/{tracing → core}/transport/http/api/instance.rb +18 -1
  204. data/lib/datadog/core/transport/http/api/spec.rb +36 -0
  205. data/lib/datadog/{tracing → core}/transport/http/builder.rb +53 -31
  206. data/lib/datadog/core/transport/http/env.rb +8 -0
  207. data/lib/datadog/core/transport/http.rb +75 -0
  208. data/lib/datadog/core/transport/response.rb +4 -0
  209. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  210. data/lib/datadog/core/utils/duration.rb +32 -32
  211. data/lib/datadog/core/utils/forking.rb +2 -2
  212. data/lib/datadog/core/utils/network.rb +6 -6
  213. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  214. data/lib/datadog/core/utils/time.rb +20 -0
  215. data/lib/datadog/core/utils/truncation.rb +21 -0
  216. data/lib/datadog/core/utils.rb +7 -0
  217. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  218. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  219. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  220. data/lib/datadog/core/worker.rb +1 -1
  221. data/lib/datadog/core/workers/async.rb +29 -12
  222. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  223. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  224. data/lib/datadog/core.rb +8 -0
  225. data/lib/datadog/di/base.rb +115 -0
  226. data/lib/datadog/di/boot.rb +34 -0
  227. data/lib/datadog/di/code_tracker.rb +26 -15
  228. data/lib/datadog/di/component.rb +23 -14
  229. data/lib/datadog/di/configuration/settings.rb +25 -1
  230. data/lib/datadog/di/contrib/active_record.rb +1 -0
  231. data/lib/datadog/di/contrib/railtie.rb +15 -0
  232. data/lib/datadog/di/contrib.rb +28 -0
  233. data/lib/datadog/di/error.rb +5 -0
  234. data/lib/datadog/di/instrumenter.rb +162 -21
  235. data/lib/datadog/di/logger.rb +30 -0
  236. data/lib/datadog/di/preload.rb +18 -0
  237. data/lib/datadog/di/probe.rb +14 -7
  238. data/lib/datadog/di/probe_builder.rb +1 -0
  239. data/lib/datadog/di/probe_manager.rb +11 -5
  240. data/lib/datadog/di/probe_notification_builder.rb +54 -38
  241. data/lib/datadog/di/probe_notifier_worker.rb +60 -26
  242. data/lib/datadog/di/redactor.rb +0 -1
  243. data/lib/datadog/di/remote.rb +147 -0
  244. data/lib/datadog/di/serializer.rb +19 -8
  245. data/lib/datadog/di/transport/diagnostics.rb +62 -0
  246. data/lib/datadog/di/transport/http/api.rb +42 -0
  247. data/lib/datadog/di/transport/http/client.rb +47 -0
  248. data/lib/datadog/di/transport/http/diagnostics.rb +65 -0
  249. data/lib/datadog/di/transport/http/input.rb +77 -0
  250. data/lib/datadog/di/transport/http.rb +57 -0
  251. data/lib/datadog/di/transport/input.rb +70 -0
  252. data/lib/datadog/di/utils.rb +103 -0
  253. data/lib/datadog/di.rb +14 -76
  254. data/lib/datadog/error_tracking/collector.rb +87 -0
  255. data/lib/datadog/error_tracking/component.rb +167 -0
  256. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  257. data/lib/datadog/error_tracking/configuration.rb +11 -0
  258. data/lib/datadog/error_tracking/ext.rb +18 -0
  259. data/lib/datadog/error_tracking/extensions.rb +16 -0
  260. data/lib/datadog/error_tracking/filters.rb +77 -0
  261. data/lib/datadog/error_tracking.rb +18 -0
  262. data/lib/datadog/kit/appsec/events.rb +15 -3
  263. data/lib/datadog/kit/identity.rb +9 -5
  264. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  265. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  266. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  267. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  268. data/lib/datadog/opentelemetry.rb +2 -1
  269. data/lib/datadog/profiling/collectors/code_provenance.rb +18 -9
  270. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +4 -0
  271. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -0
  272. data/lib/datadog/profiling/collectors/info.rb +3 -0
  273. data/lib/datadog/profiling/collectors/thread_context.rb +17 -2
  274. data/lib/datadog/profiling/component.rb +64 -82
  275. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  276. data/lib/datadog/profiling/exporter.rb +3 -4
  277. data/lib/datadog/profiling/ext.rb +0 -14
  278. data/lib/datadog/profiling/flush.rb +5 -8
  279. data/lib/datadog/profiling/http_transport.rb +8 -87
  280. data/lib/datadog/profiling/load_native_extension.rb +1 -33
  281. data/lib/datadog/profiling/profiler.rb +2 -0
  282. data/lib/datadog/profiling/scheduler.rb +10 -2
  283. data/lib/datadog/profiling/stack_recorder.rb +9 -9
  284. data/lib/datadog/profiling/tag_builder.rb +5 -41
  285. data/lib/datadog/profiling/tasks/setup.rb +2 -0
  286. data/lib/datadog/profiling.rb +6 -2
  287. data/lib/datadog/tracing/analytics.rb +1 -1
  288. data/lib/datadog/tracing/component.rb +16 -12
  289. data/lib/datadog/tracing/configuration/ext.rb +8 -1
  290. data/lib/datadog/tracing/configuration/settings.rb +22 -10
  291. data/lib/datadog/tracing/context_provider.rb +1 -1
  292. data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
  293. data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
  294. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +15 -0
  295. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +19 -12
  296. data/lib/datadog/tracing/contrib/action_pack/ext.rb +2 -0
  297. data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
  298. data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
  299. data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
  300. data/lib/datadog/tracing/contrib/active_record/integration.rb +7 -3
  301. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +7 -2
  302. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +36 -1
  303. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  304. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +14 -4
  305. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
  306. data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
  307. data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
  308. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
  309. data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
  310. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
  311. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
  312. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  313. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +4 -0
  314. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
  315. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  316. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  317. data/lib/datadog/tracing/contrib/ext.rb +1 -0
  318. data/lib/datadog/tracing/contrib/extensions.rb +29 -3
  319. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  320. data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +21 -0
  321. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +11 -0
  322. data/lib/datadog/tracing/contrib/graphql/ext.rb +5 -0
  323. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +102 -11
  324. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  325. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  326. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  327. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  328. data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
  329. data/lib/datadog/tracing/contrib/http/integration.rb +3 -0
  330. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
  331. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
  332. data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
  333. data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
  334. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
  335. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
  336. data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
  337. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  338. data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
  339. data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
  340. data/lib/datadog/tracing/contrib/karafka.rb +37 -0
  341. data/lib/datadog/tracing/contrib/lograge/patcher.rb +4 -2
  342. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  343. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  344. data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
  345. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  346. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  347. data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
  348. data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
  349. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
  350. data/lib/datadog/tracing/contrib/patcher.rb +5 -2
  351. data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
  352. data/lib/datadog/tracing/contrib/rack/header_collection.rb +11 -1
  353. data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
  354. data/lib/datadog/tracing/contrib/rack/middlewares.rb +1 -1
  355. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  356. data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
  357. data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
  358. data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
  359. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  360. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  361. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  362. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
  363. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -2
  364. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +6 -1
  365. data/lib/datadog/tracing/contrib/support.rb +28 -0
  366. data/lib/datadog/tracing/contrib.rb +1 -0
  367. data/lib/datadog/tracing/correlation.rb +9 -2
  368. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  369. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  370. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  371. data/lib/datadog/tracing/distributed/datadog.rb +4 -2
  372. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  373. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  374. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  375. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  376. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  377. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  378. data/lib/datadog/tracing/metadata.rb +2 -0
  379. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  380. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  381. data/lib/datadog/tracing/span.rb +22 -5
  382. data/lib/datadog/tracing/span_event.rb +124 -4
  383. data/lib/datadog/tracing/span_operation.rb +52 -16
  384. data/lib/datadog/tracing/sync_writer.rb +10 -6
  385. data/lib/datadog/tracing/trace_digest.rb +9 -2
  386. data/lib/datadog/tracing/trace_operation.rb +55 -27
  387. data/lib/datadog/tracing/trace_segment.rb +6 -4
  388. data/lib/datadog/tracing/tracer.rb +66 -14
  389. data/lib/datadog/tracing/transport/http/api.rb +5 -4
  390. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  391. data/lib/datadog/tracing/transport/http/traces.rb +13 -44
  392. data/lib/datadog/tracing/transport/http.rb +13 -70
  393. data/lib/datadog/tracing/transport/serializable_trace.rb +31 -7
  394. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  395. data/lib/datadog/tracing/transport/traces.rb +47 -13
  396. data/lib/datadog/tracing/utils.rb +1 -1
  397. data/lib/datadog/tracing/workers/trace_writer.rb +8 -5
  398. data/lib/datadog/tracing/workers.rb +5 -4
  399. data/lib/datadog/tracing/writer.rb +10 -6
  400. data/lib/datadog/tracing.rb +16 -3
  401. data/lib/datadog/version.rb +2 -2
  402. data/lib/datadog.rb +2 -0
  403. metadata +149 -54
  404. data/ext/datadog_profiling_loader/datadog_profiling_loader.c +0 -142
  405. data/ext/datadog_profiling_loader/extconf.rb +0 -60
  406. data/lib/datadog/appsec/assets/waf_rules/processors.json +0 -92
  407. data/lib/datadog/appsec/assets/waf_rules/scanners.json +0 -114
  408. data/lib/datadog/appsec/contrib/devise/event.rb +0 -57
  409. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -77
  410. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -54
  411. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  412. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  413. data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +0 -46
  414. data/lib/datadog/appsec/contrib/patcher.rb +0 -12
  415. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +0 -69
  416. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +0 -47
  417. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +0 -53
  418. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +0 -53
  419. data/lib/datadog/appsec/contrib/sinatra/ext.rb +0 -14
  420. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +0 -48
  421. data/lib/datadog/appsec/monitor/reactive/set_user.rb +0 -45
  422. data/lib/datadog/appsec/processor/actions.rb +0 -49
  423. data/lib/datadog/appsec/processor/context.rb +0 -107
  424. data/lib/datadog/appsec/processor/rule_merger.rb +0 -170
  425. data/lib/datadog/appsec/processor.rb +0 -106
  426. data/lib/datadog/appsec/reactive/address_hash.rb +0 -22
  427. data/lib/datadog/appsec/reactive/engine.rb +0 -47
  428. data/lib/datadog/appsec/reactive/operation.rb +0 -68
  429. data/lib/datadog/appsec/reactive/subscriber.rb +0 -19
  430. data/lib/datadog/appsec/scope.rb +0 -58
  431. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  432. data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
  433. data/lib/datadog/core/remote/transport/http/api/instance.rb +0 -39
  434. data/lib/datadog/core/remote/transport/http/api/spec.rb +0 -21
  435. data/lib/datadog/core/remote/transport/http/builder.rb +0 -219
  436. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  437. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  438. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  439. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
  440. data/lib/datadog/di/transport.rb +0 -81
  441. data/lib/datadog/tracing/transport/http/api/spec.rb +0 -19
@@ -17,7 +17,7 @@
17
17
  typedef struct heap_recorder heap_recorder;
18
18
 
19
19
  // Extra data associated with each live object being tracked.
20
- typedef struct live_object_data {
20
+ typedef struct {
21
21
  // The weight of this object from a sampling perspective.
22
22
  //
23
23
  // A notion of weight is preserved for each tracked object to allow for an approximate
@@ -34,7 +34,7 @@ typedef struct live_object_data {
34
34
 
35
35
  // The class of the object that we're tracking.
36
36
  // NOTE: This is optional and will be set to NULL if not set.
37
- char* class;
37
+ ddog_prof_ManagedStringId class;
38
38
 
39
39
  // The GC allocation gen in which we saw this object being allocated.
40
40
  //
@@ -59,7 +59,7 @@ typedef struct {
59
59
  } heap_recorder_iteration_data;
60
60
 
61
61
  // Initialize a new heap recorder.
62
- heap_recorder* heap_recorder_new(void);
62
+ heap_recorder* heap_recorder_new(ddog_prof_ManagedStringStorage string_storage);
63
63
 
64
64
  // Free a previously initialized heap recorder.
65
65
  void heap_recorder_free(heap_recorder *heap_recorder);
@@ -105,7 +105,7 @@ 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
+ void start_heap_allocation_recording(heap_recorder *heap_recorder, VALUE new_obj, unsigned int weight, ddog_CharSlice alloc_class);
109
109
 
110
110
  // End a previously started heap allocation recording on the heap recorder.
111
111
  //
@@ -164,10 +164,6 @@ VALUE heap_recorder_state_snapshot(heap_recorder *heap_recorder);
164
164
 
165
165
  // v--- TEST-ONLY APIs ---v
166
166
 
167
- // Assert internal hashing logic is valid for the provided locations and its
168
- // corresponding internal representations in heap recorder.
169
- void heap_recorder_testonly_assert_hash_matches(ddog_prof_Slice_Location locations);
170
-
171
167
  // Returns a Ruby string with a representation of internal data helpful to
172
168
  // troubleshoot issues such as unexpected test failures.
173
169
  VALUE heap_recorder_testonly_debug(heap_recorder *heap_recorder);
@@ -177,3 +173,5 @@ VALUE heap_recorder_testonly_is_object_recorded(heap_recorder *heap_recorder, VA
177
173
 
178
174
  // Used to ensure that a GC actually triggers an update of the objects
179
175
  void heap_recorder_testonly_reset_last_update(heap_recorder *heap_recorder);
176
+
177
+ void heap_recorder_testonly_benchmark_intern(heap_recorder *heap_recorder, ddog_CharSlice string, int times, bool use_all);
@@ -4,6 +4,7 @@
4
4
  #include "helpers.h"
5
5
  #include "libdatadog_helpers.h"
6
6
  #include "ruby_helpers.h"
7
+ #include "encoded_profile.h"
7
8
 
8
9
  // Used to report profiling data to Datadog.
9
10
  // This file implements the native bits of the Datadog::Profiling::HttpTransport class
@@ -13,33 +14,23 @@ static VALUE error_symbol = Qnil; // :error in Ruby
13
14
 
14
15
  static VALUE library_version_string = Qnil;
15
16
 
16
- struct call_exporter_without_gvl_arguments {
17
- ddog_prof_Exporter *exporter;
18
- ddog_prof_Exporter_Request_BuildResult *build_result;
17
+ typedef struct {
18
+ ddog_prof_ProfileExporter *exporter;
19
+ ddog_prof_Request_Result *build_result;
19
20
  ddog_CancellationToken *cancel_token;
20
- ddog_prof_Exporter_SendResult result;
21
+ ddog_prof_Result_HttpStatus result;
21
22
  bool send_ran;
22
- };
23
+ } call_exporter_without_gvl_arguments;
23
24
 
24
25
  static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string);
25
26
  static VALUE _native_validate_exporter(VALUE self, VALUE exporter_configuration);
26
- static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration, VALUE tags_as_array);
27
- static VALUE handle_exporter_failure(ddog_prof_Exporter_NewResult exporter_result);
27
+ static ddog_prof_ProfileExporter_Result create_exporter(VALUE exporter_configuration, VALUE tags_as_array);
28
+ static VALUE handle_exporter_failure(ddog_prof_ProfileExporter_Result exporter_result);
28
29
  static VALUE _native_do_export(
29
30
  VALUE self,
30
31
  VALUE exporter_configuration,
31
32
  VALUE upload_timeout_milliseconds,
32
- VALUE start_timespec_seconds,
33
- VALUE start_timespec_nanoseconds,
34
- VALUE finish_timespec_seconds,
35
- VALUE finish_timespec_nanoseconds,
36
- VALUE pprof_file_name,
37
- VALUE pprof_data,
38
- VALUE code_provenance_file_name,
39
- VALUE code_provenance_data,
40
- VALUE tags_as_array,
41
- VALUE internal_metadata_json,
42
- VALUE info_json
33
+ VALUE flush
43
34
  );
44
35
  static void *call_exporter_without_gvl(void *call_args);
45
36
  static void interrupt_exporter_call(void *cancel_token);
@@ -48,7 +39,7 @@ void http_transport_init(VALUE profiling_module) {
48
39
  VALUE http_transport_class = rb_define_class_under(profiling_module, "HttpTransport", rb_cObject);
49
40
 
50
41
  rb_define_singleton_method(http_transport_class, "_native_validate_exporter", _native_validate_exporter, 1);
51
- rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export, 13);
42
+ rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export, 3);
52
43
 
53
44
  ok_symbol = ID2SYM(rb_intern_const("ok"));
54
45
  error_symbol = ID2SYM(rb_intern_const("error"));
@@ -65,14 +56,14 @@ static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string) {
65
56
 
66
57
  static VALUE _native_validate_exporter(DDTRACE_UNUSED VALUE _self, VALUE exporter_configuration) {
67
58
  ENFORCE_TYPE(exporter_configuration, T_ARRAY);
68
- ddog_prof_Exporter_NewResult exporter_result = create_exporter(exporter_configuration, rb_ary_new());
59
+ ddog_prof_ProfileExporter_Result exporter_result = create_exporter(exporter_configuration, rb_ary_new());
69
60
 
70
61
  VALUE failure_tuple = handle_exporter_failure(exporter_result);
71
62
  if (!NIL_P(failure_tuple)) return failure_tuple;
72
63
 
73
64
  // We don't actually need the exporter for now -- we just wanted to validate that we could create it with the
74
65
  // settings we were given
75
- ddog_prof_Exporter_drop(exporter_result.ok);
66
+ ddog_prof_Exporter_drop(&exporter_result.ok);
76
67
 
77
68
  return rb_ary_new_from_args(2, ok_symbol, Qnil);
78
69
  }
@@ -84,26 +75,21 @@ static ddog_prof_Endpoint endpoint_from(VALUE exporter_configuration) {
84
75
  ENFORCE_TYPE(exporter_working_mode, T_SYMBOL);
85
76
  ID working_mode = SYM2ID(exporter_working_mode);
86
77
 
87
- ID agentless_id = rb_intern("agentless");
88
- ID agent_id = rb_intern("agent");
89
-
90
- if (working_mode != agentless_id && working_mode != agent_id) {
91
- rb_raise(rb_eArgError, "Failed to initialize transport: Unexpected working mode, expected :agentless or :agent");
92
- }
93
-
94
- if (working_mode == agentless_id) {
78
+ if (working_mode == rb_intern("agentless")) {
95
79
  VALUE site = rb_ary_entry(exporter_configuration, 1);
96
80
  VALUE api_key = rb_ary_entry(exporter_configuration, 2);
97
81
 
98
82
  return ddog_prof_Endpoint_agentless(char_slice_from_ruby_string(site), char_slice_from_ruby_string(api_key));
99
- } else { // agent_id
83
+ } else if (working_mode == rb_intern("agent")) {
100
84
  VALUE base_url = rb_ary_entry(exporter_configuration, 1);
101
85
 
102
86
  return ddog_prof_Endpoint_agent(char_slice_from_ruby_string(base_url));
87
+ } else {
88
+ rb_raise(rb_eArgError, "Failed to initialize transport: Unexpected working mode, expected :agentless or :agent");
103
89
  }
104
90
  }
105
91
 
106
- static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration, VALUE tags_as_array) {
92
+ static ddog_prof_ProfileExporter_Result create_exporter(VALUE exporter_configuration, VALUE tags_as_array) {
107
93
  ENFORCE_TYPE(exporter_configuration, T_ARRAY);
108
94
  ENFORCE_TYPE(tags_as_array, T_ARRAY);
109
95
 
@@ -117,7 +103,7 @@ static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration
117
103
  ddog_CharSlice library_version = char_slice_from_ruby_string(library_version_string);
118
104
  ddog_CharSlice profiling_family = DDOG_CHARSLICE_C("ruby");
119
105
 
120
- ddog_prof_Exporter_NewResult exporter_result =
106
+ ddog_prof_ProfileExporter_Result exporter_result =
121
107
  ddog_prof_Exporter_new(library_name, library_version, profiling_family, &tags, endpoint);
122
108
 
123
109
  ddog_Vec_Tag_drop(tags);
@@ -125,8 +111,12 @@ static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration
125
111
  return exporter_result;
126
112
  }
127
113
 
128
- static VALUE handle_exporter_failure(ddog_prof_Exporter_NewResult exporter_result) {
129
- return exporter_result.tag == DDOG_PROF_EXPORTER_NEW_RESULT_OK ?
114
+ 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);
116
+ }
117
+
118
+ static VALUE handle_exporter_failure(ddog_prof_ProfileExporter_Result exporter_result) {
119
+ return exporter_result.tag == DDOG_PROF_PROFILE_EXPORTER_RESULT_OK_HANDLE_PROFILE_EXPORTER ?
130
120
  Qnil :
131
121
  rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&exporter_result.err));
132
122
  }
@@ -134,39 +124,37 @@ static VALUE handle_exporter_failure(ddog_prof_Exporter_NewResult exporter_resul
134
124
  // Note: This function handles a bunch of libdatadog dynamically-allocated objects, so it MUST not use any Ruby APIs
135
125
  // which can raise exceptions, otherwise the objects will be leaked.
136
126
  static VALUE perform_export(
137
- ddog_prof_Exporter *exporter,
138
- ddog_Timespec start,
139
- ddog_Timespec finish,
127
+ ddog_prof_ProfileExporter *exporter,
128
+ ddog_prof_EncodedProfile *profile,
140
129
  ddog_prof_Exporter_Slice_File files_to_compress_and_export,
141
- ddog_prof_Exporter_Slice_File files_to_export_unmodified,
142
- ddog_Vec_Tag *additional_tags,
143
130
  ddog_CharSlice internal_metadata,
144
131
  ddog_CharSlice info
145
132
  ) {
146
- ddog_prof_ProfiledEndpointsStats *endpoints_stats = NULL; // Not in use yet
147
- ddog_prof_Exporter_Request_BuildResult build_result = ddog_prof_Exporter_Request_build(
133
+ ddog_prof_Request_Result build_result = ddog_prof_Exporter_Request_build(
148
134
  exporter,
149
- start,
150
- finish,
135
+ profile,
151
136
  files_to_compress_and_export,
152
- files_to_export_unmodified,
153
- additional_tags,
154
- endpoints_stats,
137
+ /* files_to_export_unmodified: */ ddog_prof_Exporter_Slice_File_empty(),
138
+ /* optional_additional_tags: */ NULL,
155
139
  &internal_metadata,
156
140
  &info
157
141
  );
158
142
 
159
- if (build_result.tag == DDOG_PROF_EXPORTER_REQUEST_BUILD_RESULT_ERR) {
143
+ if (build_result.tag == DDOG_PROF_REQUEST_RESULT_ERR_HANDLE_REQUEST) {
160
144
  ddog_prof_Exporter_drop(exporter);
161
145
  return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&build_result.err));
162
146
  }
163
147
 
164
- ddog_CancellationToken *cancel_token = ddog_CancellationToken_new();
148
+ ddog_CancellationToken cancel_token_request = ddog_CancellationToken_new();
149
+ ddog_CancellationToken cancel_token_interrupt = ddog_CancellationToken_clone(&cancel_token_request);
150
+
151
+ validate_token(cancel_token_request, __FILE__, __LINE__);
152
+ validate_token(cancel_token_interrupt, __FILE__, __LINE__);
165
153
 
166
154
  // We'll release the Global VM Lock while we're calling send, so that the Ruby VM can continue to work while this
167
155
  // is pending
168
- struct call_exporter_without_gvl_arguments args =
169
- {.exporter = exporter, .build_result = &build_result, .cancel_token = cancel_token, .send_ran = false};
156
+ call_exporter_without_gvl_arguments args =
157
+ {.exporter = exporter, .build_result = &build_result, .cancel_token = &cancel_token_request, .send_ran = false};
170
158
 
171
159
  // We use rb_thread_call_without_gvl2 instead of rb_thread_call_without_gvl as the gvl2 variant never raises any
172
160
  // exceptions.
@@ -183,14 +171,15 @@ static VALUE perform_export(
183
171
  int pending_exception = 0;
184
172
 
185
173
  while (!args.send_ran && !pending_exception) {
186
- rb_thread_call_without_gvl2(call_exporter_without_gvl, &args, interrupt_exporter_call, cancel_token);
174
+ rb_thread_call_without_gvl2(call_exporter_without_gvl, &args, interrupt_exporter_call, &cancel_token_interrupt);
187
175
 
188
176
  // To make sure we don't leak memory, we never check for pending exceptions if send ran
189
177
  if (!args.send_ran) pending_exception = check_if_pending_exception();
190
178
  }
191
179
 
192
180
  // Cleanup exporter and token, no longer needed
193
- ddog_CancellationToken_drop(cancel_token);
181
+ ddog_CancellationToken_drop(&cancel_token_request);
182
+ ddog_CancellationToken_drop(&cancel_token_interrupt);
194
183
  ddog_prof_Exporter_drop(exporter);
195
184
 
196
185
  if (pending_exception) {
@@ -203,10 +192,10 @@ static VALUE perform_export(
203
192
 
204
193
  // The request itself does not need to be freed as libdatadog takes ownership of it as part of sending.
205
194
 
206
- ddog_prof_Exporter_SendResult result = args.result;
195
+ ddog_prof_Result_HttpStatus result = args.result;
207
196
 
208
- return result.tag == DDOG_PROF_EXPORTER_SEND_RESULT_HTTP_RESPONSE ?
209
- rb_ary_new_from_args(2, ok_symbol, UINT2NUM(result.http_response.code)) :
197
+ return result.tag == DDOG_PROF_RESULT_HTTP_STATUS_OK_HTTP_STATUS ?
198
+ rb_ary_new_from_args(2, ok_symbol, UINT2NUM(result.ok.code)) :
210
199
  rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&result.err));
211
200
  }
212
201
 
@@ -214,26 +203,19 @@ static VALUE _native_do_export(
214
203
  DDTRACE_UNUSED VALUE _self,
215
204
  VALUE exporter_configuration,
216
205
  VALUE upload_timeout_milliseconds,
217
- VALUE start_timespec_seconds,
218
- VALUE start_timespec_nanoseconds,
219
- VALUE finish_timespec_seconds,
220
- VALUE finish_timespec_nanoseconds,
221
- VALUE pprof_file_name,
222
- VALUE pprof_data,
223
- VALUE code_provenance_file_name,
224
- VALUE code_provenance_data,
225
- VALUE tags_as_array,
226
- VALUE internal_metadata_json,
227
- VALUE info_json
206
+ VALUE flush
228
207
  ) {
208
+ 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
+ VALUE code_provenance_data = rb_funcall(flush, rb_intern("code_provenance_data"), 0);
211
+ VALUE tags_as_array = rb_funcall(flush, rb_intern("tags_as_array"), 0);
212
+ VALUE internal_metadata_json = rb_funcall(flush, rb_intern("internal_metadata_json"), 0);
213
+ VALUE info_json = rb_funcall(flush, rb_intern("info_json"), 0);
214
+
229
215
  ENFORCE_TYPE(upload_timeout_milliseconds, T_FIXNUM);
230
- ENFORCE_TYPE(start_timespec_seconds, T_FIXNUM);
231
- ENFORCE_TYPE(start_timespec_nanoseconds, T_FIXNUM);
232
- ENFORCE_TYPE(finish_timespec_seconds, T_FIXNUM);
233
- ENFORCE_TYPE(finish_timespec_nanoseconds, T_FIXNUM);
234
- ENFORCE_TYPE(pprof_file_name, T_STRING);
235
- ENFORCE_TYPE(pprof_data, T_STRING);
216
+ enforce_encoded_profile_instance(encoded_profile);
236
217
  ENFORCE_TYPE(code_provenance_file_name, T_STRING);
218
+ ENFORCE_TYPE(tags_as_array, T_ARRAY);
237
219
  ENFORCE_TYPE(internal_metadata_json, T_STRING);
238
220
  ENFORCE_TYPE(info_json, T_STRING);
239
221
 
@@ -243,23 +225,9 @@ static VALUE _native_do_export(
243
225
 
244
226
  uint64_t timeout_milliseconds = NUM2ULONG(upload_timeout_milliseconds);
245
227
 
246
- ddog_Timespec start =
247
- {.seconds = NUM2LONG(start_timespec_seconds), .nanoseconds = NUM2UINT(start_timespec_nanoseconds)};
248
- ddog_Timespec finish =
249
- {.seconds = NUM2LONG(finish_timespec_seconds), .nanoseconds = NUM2UINT(finish_timespec_nanoseconds)};
250
-
251
228
  int to_compress_length = have_code_provenance ? 1 : 0;
252
229
  ddog_prof_Exporter_File to_compress[to_compress_length];
253
- int already_compressed_length = 1; // pprof
254
- ddog_prof_Exporter_File already_compressed[already_compressed_length];
255
-
256
230
  ddog_prof_Exporter_Slice_File files_to_compress_and_export = {.ptr = to_compress, .len = to_compress_length};
257
- ddog_prof_Exporter_Slice_File files_to_export_unmodified = {.ptr = already_compressed, .len = already_compressed_length};
258
-
259
- already_compressed[0] = (ddog_prof_Exporter_File) {
260
- .name = char_slice_from_ruby_string(pprof_file_name),
261
- .file = byte_slice_from_ruby_string(pprof_data),
262
- };
263
231
 
264
232
  if (have_code_provenance) {
265
233
  to_compress[0] = (ddog_prof_Exporter_File) {
@@ -268,39 +236,35 @@ static VALUE _native_do_export(
268
236
  };
269
237
  }
270
238
 
271
- ddog_Vec_Tag *null_additional_tags = NULL;
272
239
  ddog_CharSlice internal_metadata = char_slice_from_ruby_string(internal_metadata_json);
273
240
  ddog_CharSlice info = char_slice_from_ruby_string(info_json);
274
241
 
275
- ddog_prof_Exporter_NewResult exporter_result = create_exporter(exporter_configuration, tags_as_array);
242
+ ddog_prof_ProfileExporter_Result exporter_result = create_exporter(exporter_configuration, tags_as_array);
276
243
  // Note: Do not add anything that can raise exceptions after this line, as otherwise the exporter memory will leak
277
244
 
278
245
  VALUE failure_tuple = handle_exporter_failure(exporter_result);
279
246
  if (!NIL_P(failure_tuple)) return failure_tuple;
280
247
 
281
- ddog_prof_MaybeError timeout_result = ddog_prof_Exporter_set_timeout(exporter_result.ok, timeout_milliseconds);
282
- if (timeout_result.tag == DDOG_PROF_OPTION_ERROR_SOME_ERROR) {
248
+ ddog_VoidResult timeout_result = ddog_prof_Exporter_set_timeout(&exporter_result.ok, timeout_milliseconds);
249
+ if (timeout_result.tag == DDOG_VOID_RESULT_ERR) {
283
250
  // NOTE: Seems a bit harsh to fail the upload if we can't set a timeout. OTOH, this is only expected to fail
284
251
  // if the exporter is not well built. Because such a situation should already be caught above I think it's
285
252
  // preferable to leave this here as a virtually unreachable exception rather than ignoring it.
286
- ddog_prof_Exporter_drop(exporter_result.ok);
287
- return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&timeout_result.some));
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));
288
255
  }
289
256
 
290
257
  return perform_export(
291
- exporter_result.ok,
292
- start,
293
- finish,
258
+ &exporter_result.ok,
259
+ to_ddog_prof_EncodedProfile(encoded_profile),
294
260
  files_to_compress_and_export,
295
- files_to_export_unmodified,
296
- null_additional_tags,
297
261
  internal_metadata,
298
262
  info
299
263
  );
300
264
  }
301
265
 
302
266
  static void *call_exporter_without_gvl(void *call_args) {
303
- struct call_exporter_without_gvl_arguments *args = (struct call_exporter_without_gvl_arguments*) call_args;
267
+ call_exporter_without_gvl_arguments *args = (call_exporter_without_gvl_arguments*) call_args;
304
268
 
305
269
  args->result = ddog_prof_Exporter_send(args->exporter, &args->build_result->ok, args->cancel_token);
306
270
  args->send_ran = true;
@@ -310,5 +274,7 @@ static void *call_exporter_without_gvl(void *call_args) {
310
274
 
311
275
  // Called by Ruby when it wants to interrupt call_exporter_without_gvl above, e.g. when the app wants to exit cleanly
312
276
  static void interrupt_exporter_call(void *cancel_token) {
277
+ // TODO: False here can mean two things: it was already cancelled OR it failed to cancel.
278
+ // Would be nice to change libdatadog to be able to distinguish between them...
313
279
  ddog_CancellationToken_cancel((ddog_CancellationToken *) cancel_token);
314
280
  }
@@ -60,3 +60,25 @@ size_t read_ddogerr_string_and_drop(ddog_Error *error, char *string, size_t capa
60
60
  ddog_Error_drop(error);
61
61
  return error_msg_size;
62
62
  }
63
+
64
+ ddog_prof_ManagedStringId intern_or_raise(ddog_prof_ManagedStringStorage string_storage, ddog_CharSlice string) {
65
+ if (string.len == 0) return (ddog_prof_ManagedStringId) { 0 }; // Id 0 is always an empty string, no need to ask
66
+
67
+ ddog_prof_ManagedStringStorageInternResult intern_result = ddog_prof_ManagedStringStorage_intern(string_storage, string);
68
+ 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));
70
+ }
71
+ return intern_result.ok;
72
+ }
73
+
74
+ void intern_all_or_raise(
75
+ ddog_prof_ManagedStringStorage string_storage,
76
+ ddog_prof_Slice_CharSlice strings,
77
+ ddog_prof_ManagedStringId *output_ids,
78
+ uintptr_t output_ids_size
79
+ ) {
80
+ ddog_prof_MaybeError result = ddog_prof_ManagedStringStorage_intern_all(string_storage, strings, output_ids, output_ids_size);
81
+ 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));
83
+ }
84
+ }
@@ -18,8 +18,11 @@ size_t read_ddogerr_string_and_drop(ddog_Error *error, char *string, size_t capa
18
18
  const char *ruby_value_type_to_string(enum ruby_value_type type);
19
19
  ddog_CharSlice ruby_value_type_to_char_slice(enum ruby_value_type type);
20
20
 
21
- // Returns a dynamically allocated string from the provided char slice.
22
- // WARN: The returned string must be explicitly freed with ruby_xfree.
23
- static inline char* string_from_char_slice(ddog_CharSlice slice) {
24
- return ruby_strndup(slice.ptr, slice.len);
25
- }
21
+ ddog_prof_ManagedStringId intern_or_raise(ddog_prof_ManagedStringStorage string_storage, ddog_CharSlice string);
22
+
23
+ void intern_all_or_raise(
24
+ ddog_prof_ManagedStringStorage string_storage,
25
+ ddog_prof_Slice_CharSlice strings,
26
+ ddog_prof_ManagedStringId *output_ids,
27
+ uintptr_t output_ids_size
28
+ );
@@ -40,6 +40,13 @@
40
40
  #endif
41
41
  #endif
42
42
 
43
+ // This file can't include datadog_ruby_common.h so we replicate this here
44
+ #ifdef __GNUC__
45
+ #define DDTRACE_UNUSED __attribute__((unused))
46
+ #else
47
+ #define DDTRACE_UNUSED
48
+ #endif
49
+
43
50
  #define PRIVATE_VM_API_ACCESS_SKIP_RUBY_INCLUDES
44
51
  #include "private_vm_api_access.h"
45
52
 
@@ -158,7 +165,7 @@ bool is_current_thread_holding_the_gvl(void) {
158
165
  //
159
166
  // Thus an incorrect `is_current_thread_holding_the_gvl` result may lead to issues inside `rb_postponed_job_register_one`.
160
167
  //
161
- // For this reason we currently do not enable the new Ruby profiler on Ruby 2.5 by default, and we print a
168
+ // For this reason we default to use the "no signals workaround" on Ruby 2.5 by default, and we print a
162
169
  // warning when customers force-enable it.
163
170
  bool gvl_acquired = vm->gvl.acquired != 0;
164
171
  rb_thread_t *current_owner = vm->running_thread;
@@ -305,6 +312,7 @@ VALUE thread_name_for(VALUE thread) {
305
312
  // to support our custom rb_profile_frames (see below)
306
313
  // Modifications:
307
314
  // * Support int first_lineno for Ruby 3.2.0+ (https://github.com/ruby/ruby/pull/6430)
315
+ // * Validate iseq and pos before calling `rb_iseq_line_no` as a safety measure (see comment below for details)
308
316
  //
309
317
  // `node_id` gets used depending on Ruby VM compilation settings (USE_ISEQ_NODE_ID being defined).
310
318
  // To avoid getting false "unused argument" warnings in setups where it's not used, we need to do this weird dance
@@ -351,6 +359,13 @@ calc_pos(const rb_iseq_t *iseq, const VALUE *pc, int *lineno, int *node_id)
351
359
  __builtin_trap();
352
360
  }
353
361
  #endif
362
+
363
+ // In PROF-11475 we spotted a crash when calling `rb_iseq_line_no` from this method. We couldn't reproduce or
364
+ // figure out the root cause, but "just in case", we're validating that the iseq looks valid and that the
365
+ // `n` used for the position is also sane, and if they don't look good, we don't calculate the line, rather
366
+ // than potentially trigger any issues.
367
+ if (RB_UNLIKELY(!RB_TYPE_P((VALUE) iseq, T_IMEMO) || n < 0 || n > ISEQ_BODY(iseq)->iseq_size)) return 0;
368
+
354
369
  if (lineno) *lineno = rb_iseq_line_no(iseq, pos);
355
370
  #ifdef USE_ISEQ_NODE_ID
356
371
  if (node_id) *node_id = rb_iseq_node_id(iseq, pos);
@@ -554,6 +569,7 @@ int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, frame_info *st
554
569
 
555
570
  stack_buffer[i].as.native_frame.caching_cme = (VALUE)cme;
556
571
  stack_buffer[i].as.native_frame.method_id = cme->def->original_id;
572
+ stack_buffer[i].as.native_frame.function = cme->def->body.cfunc.func;
557
573
  stack_buffer[i].is_ruby_frame = false;
558
574
  i++;
559
575
  }
@@ -800,3 +816,55 @@ static inline int ddtrace_imemo_type(VALUE imemo) {
800
816
  return current_thread;
801
817
  }
802
818
  #endif
819
+
820
+ // Is the VM smack in the middle of raising an exception?
821
+ bool is_raised_flag_set(VALUE thread) { return thread_struct_from_object(thread)->ec->raised_flag > 0; }
822
+
823
+ #ifndef NO_CURRENT_FIBER_FOR
824
+ // The following three declarations are all
825
+ // taken from upstream cont.c at commit d97884a58be32e829fd03a80cd521f4733d65c79 (February 2025, master branch)
826
+ // (See the Ruby project copyright and license above)
827
+ // to enable building `current_fiber_for`.
828
+ //
829
+ // We needed to copy them because they aren't otherwise exposed in any VM APIs or headers.
830
+ // @ivoanjo: I manually checked the Ruby 3.1, 3.2, 3.3 and 3.4 branches + master, and the parts we care about in these
831
+ // structures have not changed in many years (in fact, last change I spotted was for 2.7).
832
+ enum context_type {
833
+ CONTINUATION_CONTEXT = 0,
834
+ FIBER_CONTEXT = 1
835
+ };
836
+
837
+ typedef struct rb_context_struct { // This declaration is incomplete -- only contains up to `self` which is the part we care about
838
+ enum context_type type;
839
+ int argc;
840
+ int kw_splat;
841
+ VALUE self;
842
+ } rb_context_t;
843
+
844
+ struct rb_fiber_struct { // This declaration is incomplete -- only contains the first entry which is the part we care about
845
+ rb_context_t cont;
846
+ };
847
+
848
+ VALUE current_fiber_for(VALUE thread) {
849
+ VALUE self = thread_struct_from_object(thread)->ec->fiber_ptr->cont.self;
850
+ return self == 0 ? Qnil : self;
851
+ }
852
+
853
+ void self_test_current_fiber_for(void) {
854
+ VALUE expected_current_fiber = current_fiber_for(rb_thread_current());
855
+ VALUE actual_current_fiber = rb_fiber_current();
856
+
857
+ if (expected_current_fiber == Qnil) {
858
+ // On purpose above we tried reading before calling `rb_fiber_current()` so the fiber may have not existed yet.
859
+ // But now it should be there.
860
+ expected_current_fiber = current_fiber_for(rb_thread_current());
861
+ }
862
+
863
+ if (expected_current_fiber != actual_current_fiber) rb_raise(rb_eRuntimeError, "current_fiber_for() self-test failed");
864
+ }
865
+ #else
866
+ NORETURN(VALUE current_fiber_for(DDTRACE_UNUSED VALUE thread));
867
+
868
+ VALUE current_fiber_for(DDTRACE_UNUSED VALUE thread) { rb_raise(rb_eRuntimeError, "Not implemented for Ruby < 3.1"); }
869
+ void self_test_current_fiber_for(void) { } // Nothing to do
870
+ #endif
@@ -18,16 +18,19 @@ typedef struct {
18
18
  rb_nativethread_id_t owner;
19
19
  } current_gvl_owner;
20
20
 
21
- typedef struct frame_info {
21
+ // If a sample is kept around for later use, some of its fields need marking. Remember to
22
+ // update the marking code in `sampling_buffer_mark` if new fields are added.
23
+ typedef struct {
22
24
  union {
23
25
  struct {
24
- VALUE iseq;
25
- void *caching_pc; // For caching only
26
+ VALUE iseq; // Needs marking if kept around
27
+ void *caching_pc; // For caching validation/invalidation only (does not need marking)
26
28
  int line;
27
29
  } ruby_frame;
28
30
  struct {
29
- VALUE caching_cme; // For caching only
31
+ VALUE caching_cme; // For caching validation/invalidation only (does not need marking)
30
32
  ID method_id;
33
+ void *function;
31
34
  } native_frame;
32
35
  } as;
33
36
  bool is_ruby_frame : 1;
@@ -44,6 +47,7 @@ bool is_thread_alive(VALUE thread);
44
47
  VALUE thread_name_for(VALUE thread);
45
48
 
46
49
  int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, frame_info *stack_buffer);
50
+
47
51
  // Returns true if the current thread belongs to the main Ractor or if Ruby has no Ractor support
48
52
  bool ddtrace_rb_ractor_main_p(void);
49
53
 
@@ -68,3 +72,11 @@ const char *imemo_kind(VALUE imemo);
68
72
 
69
73
  #define ENFORCE_THREAD(value) \
70
74
  { if (RB_UNLIKELY(!rb_typeddata_is_kind_of(value, RTYPEDDATA_TYPE(rb_thread_current())))) raise_unexpected_type(value, ADD_QUOTES(value), "Thread", __FILE__, __LINE__, __func__); }
75
+
76
+ bool is_raised_flag_set(VALUE thread);
77
+
78
+ // Can be nil if `rb_fiber_current()` or similar has not been called (gets allocated lazily)
79
+ // Only implemented for Ruby 3.1+
80
+ VALUE current_fiber_for(VALUE thread);
81
+
82
+ void self_test_current_fiber_for(void);