datadog 2.15.0 → 2.17.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 (194) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +74 -2
  3. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  4. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +7 -0
  5. data/ext/datadog_profiling_native_extension/encoded_profile.c +22 -12
  6. data/ext/datadog_profiling_native_extension/encoded_profile.h +1 -0
  7. data/ext/datadog_profiling_native_extension/extconf.rb +3 -0
  8. data/ext/datadog_profiling_native_extension/heap_recorder.c +8 -1
  9. data/ext/datadog_profiling_native_extension/http_transport.c +45 -72
  10. data/ext/datadog_profiling_native_extension/stack_recorder.c +4 -5
  11. data/ext/libdatadog_api/crashtracker.c +11 -12
  12. data/ext/libdatadog_api/crashtracker.h +5 -0
  13. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  14. data/ext/libdatadog_api/datadog_ruby_common.h +7 -0
  15. data/ext/libdatadog_api/init.c +15 -0
  16. data/ext/libdatadog_api/library_config.c +122 -0
  17. data/ext/libdatadog_api/library_config.h +19 -0
  18. data/ext/libdatadog_api/macos_development.md +3 -3
  19. data/ext/libdatadog_api/process_discovery.c +117 -0
  20. data/ext/libdatadog_api/process_discovery.h +5 -0
  21. data/ext/libdatadog_extconf_helpers.rb +1 -1
  22. data/lib/datadog/appsec/actions_handler.rb +3 -2
  23. data/lib/datadog/appsec/api_security/lru_cache.rb +49 -0
  24. data/lib/datadog/appsec/api_security.rb +9 -0
  25. data/lib/datadog/appsec/assets/waf_rules/recommended.json +1344 -0
  26. data/lib/datadog/appsec/assets/waf_rules/strict.json +1344 -0
  27. data/lib/datadog/appsec/autoload.rb +1 -1
  28. data/lib/datadog/appsec/component.rb +11 -4
  29. data/lib/datadog/appsec/configuration/settings.rb +31 -18
  30. data/lib/datadog/appsec/context.rb +1 -1
  31. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +10 -12
  32. data/lib/datadog/appsec/contrib/active_record/integration.rb +1 -1
  33. data/lib/datadog/appsec/contrib/active_record/patcher.rb +22 -22
  34. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +2 -3
  35. data/lib/datadog/appsec/contrib/devise/ext.rb +1 -0
  36. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -1
  37. data/lib/datadog/appsec/contrib/devise/patcher.rb +3 -5
  38. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +17 -4
  39. data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
  40. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +9 -10
  41. data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
  42. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +8 -9
  43. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +8 -9
  44. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  45. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +22 -32
  46. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  47. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +16 -16
  48. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +11 -13
  49. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  50. data/lib/datadog/appsec/contrib/rails/patcher.rb +21 -21
  51. data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
  52. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +10 -11
  53. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -23
  54. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  55. data/lib/datadog/appsec/event.rb +85 -95
  56. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +5 -2
  57. data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
  58. data/lib/datadog/appsec/monitor/gateway/watcher.rb +42 -12
  59. data/lib/datadog/appsec/processor/rule_loader.rb +26 -28
  60. data/lib/datadog/appsec/processor/rule_merger.rb +5 -5
  61. data/lib/datadog/appsec/processor.rb +1 -1
  62. data/lib/datadog/appsec/remote.rb +14 -13
  63. data/lib/datadog/appsec/response.rb +6 -6
  64. data/lib/datadog/appsec/security_engine/runner.rb +1 -1
  65. data/lib/datadog/appsec/security_event.rb +39 -0
  66. data/lib/datadog/appsec.rb +1 -1
  67. data/lib/datadog/core/buffer/random.rb +18 -2
  68. data/lib/datadog/core/configuration/agent_settings_resolver.rb +5 -5
  69. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  70. data/lib/datadog/core/configuration/components.rb +48 -30
  71. data/lib/datadog/core/configuration/components_state.rb +23 -0
  72. data/lib/datadog/core/configuration/option.rb +79 -43
  73. data/lib/datadog/core/configuration/option_definition.rb +4 -4
  74. data/lib/datadog/core/configuration/options.rb +1 -1
  75. data/lib/datadog/core/configuration/settings.rb +20 -10
  76. data/lib/datadog/core/configuration/stable_config.rb +23 -0
  77. data/lib/datadog/core/configuration.rb +40 -16
  78. data/lib/datadog/core/crashtracking/component.rb +3 -10
  79. data/lib/datadog/core/encoding.rb +1 -1
  80. data/lib/datadog/core/environment/cgroup.rb +10 -12
  81. data/lib/datadog/core/environment/container.rb +38 -40
  82. data/lib/datadog/core/environment/ext.rb +6 -6
  83. data/lib/datadog/core/environment/git.rb +1 -0
  84. data/lib/datadog/core/environment/identity.rb +3 -3
  85. data/lib/datadog/core/environment/platform.rb +3 -3
  86. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  87. data/lib/datadog/core/error.rb +11 -9
  88. data/lib/datadog/core/logger.rb +2 -2
  89. data/lib/datadog/core/metrics/client.rb +20 -21
  90. data/lib/datadog/core/metrics/logging.rb +5 -5
  91. data/lib/datadog/core/process_discovery.rb +32 -0
  92. data/lib/datadog/core/rate_limiter.rb +4 -2
  93. data/lib/datadog/core/remote/client.rb +39 -31
  94. data/lib/datadog/core/remote/component.rb +3 -3
  95. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  96. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  97. data/lib/datadog/core/remote/transport/http/client.rb +1 -1
  98. data/lib/datadog/core/remote/transport/http/config.rb +21 -5
  99. data/lib/datadog/core/remote/transport/http/negotiation.rb +1 -1
  100. data/lib/datadog/core/runtime/metrics.rb +4 -4
  101. data/lib/datadog/core/telemetry/component.rb +78 -53
  102. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  103. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -0
  104. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  105. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  106. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  107. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  108. data/lib/datadog/core/telemetry/event/app_started.rb +179 -0
  109. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  110. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  111. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  112. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  113. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  114. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  115. data/lib/datadog/core/telemetry/event.rb +17 -472
  116. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  117. data/lib/datadog/core/telemetry/logger.rb +1 -1
  118. data/lib/datadog/core/telemetry/metric.rb +3 -3
  119. data/lib/datadog/core/telemetry/request.rb +3 -3
  120. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  121. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  122. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  123. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  124. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  125. data/lib/datadog/core/telemetry/worker.rb +90 -24
  126. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  127. data/lib/datadog/core/transport/http/builder.rb +13 -13
  128. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  129. data/lib/datadog/core/utils/duration.rb +32 -32
  130. data/lib/datadog/core/utils/forking.rb +2 -2
  131. data/lib/datadog/core/utils/network.rb +6 -6
  132. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  133. data/lib/datadog/core/utils/time.rb +20 -0
  134. data/lib/datadog/core/utils/truncation.rb +21 -0
  135. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  136. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  137. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  138. data/lib/datadog/core/worker.rb +1 -1
  139. data/lib/datadog/core/workers/async.rb +29 -12
  140. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  141. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  142. data/lib/datadog/core.rb +8 -0
  143. data/lib/datadog/di/boot.rb +34 -0
  144. data/lib/datadog/di/remote.rb +2 -0
  145. data/lib/datadog/di.rb +5 -32
  146. data/lib/datadog/error_tracking/collector.rb +87 -0
  147. data/lib/datadog/error_tracking/component.rb +167 -0
  148. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  149. data/lib/datadog/error_tracking/configuration.rb +11 -0
  150. data/lib/datadog/error_tracking/ext.rb +18 -0
  151. data/lib/datadog/error_tracking/extensions.rb +16 -0
  152. data/lib/datadog/error_tracking/filters.rb +77 -0
  153. data/lib/datadog/error_tracking.rb +18 -0
  154. data/lib/datadog/kit/identity.rb +1 -1
  155. data/lib/datadog/profiling/collectors/code_provenance.rb +1 -1
  156. data/lib/datadog/profiling/exporter.rb +1 -1
  157. data/lib/datadog/profiling/ext.rb +0 -1
  158. data/lib/datadog/profiling/flush.rb +1 -1
  159. data/lib/datadog/profiling/http_transport.rb +1 -6
  160. data/lib/datadog/profiling/scheduler.rb +8 -1
  161. data/lib/datadog/profiling/tag_builder.rb +1 -5
  162. data/lib/datadog/tracing/analytics.rb +1 -1
  163. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +4 -1
  164. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +33 -0
  165. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  166. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +2 -4
  167. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
  168. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
  169. data/lib/datadog/tracing/contrib/http/instrumentation.rb +1 -5
  170. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +1 -5
  171. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +1 -5
  172. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +2 -0
  173. data/lib/datadog/tracing/contrib/karafka/monitor.rb +1 -1
  174. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  175. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  176. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  177. data/lib/datadog/tracing/contrib/patcher.rb +5 -2
  178. data/lib/datadog/tracing/contrib/support.rb +28 -0
  179. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  180. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  181. data/lib/datadog/tracing/distributed/datadog.rb +2 -2
  182. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  183. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  184. data/lib/datadog/tracing/span_operation.rb +38 -14
  185. data/lib/datadog/tracing/trace_operation.rb +15 -7
  186. data/lib/datadog/tracing/tracer.rb +7 -3
  187. data/lib/datadog/tracing/utils.rb +1 -1
  188. data/lib/datadog/version.rb +1 -1
  189. data/lib/datadog.rb +2 -3
  190. metadata +53 -10
  191. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  192. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  193. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  194. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d17c177691be6204c922253f717344b69cbf2ccf0e6cc51b5d2063e484ffcf9
4
- data.tar.gz: fb55233c5db1aa2d80562d7d2a0f7297f4d13b0b1f1c8a3f3a6feec8f15bb947
3
+ metadata.gz: 28053ce1bca4cce2032cb068c38e99a56524e6ccecec3068c4d26d1e750f9790
4
+ data.tar.gz: 29b6b57640638184370c5176e4da94e74c9770bae8afd7884d1c2baea782350d
5
5
  SHA512:
6
- metadata.gz: ef69c8e13819833ce2b1a0987ec66a674a15ca029bd4ad0a29703a613c7dd263015ca0018433ac366f69e655fa264a74aa949a1d6b12e30753b249fa8b7d62c2
7
- data.tar.gz: 1d44dca02ab71b49b87e371825bbdda696fbd686bc9d24662d5d90c5091c4ddf82226abda23c56da9da8e8274ab06759a90b73fd3eb44cecc081598fd8cc188a
6
+ metadata.gz: caf719b7c9a2e5ee3f47ad0c3e02670b90b1f76bfa5de56c10f69169c97b827f4b9e81df822e548d1390f152f15e756c54c200e9f35904138e7c672af99ef30b
7
+ data.tar.gz: eda75252942b8c7d278bab14da78c7752b17b136a3f0bd9ed145512a64b3fb8acb110a8cbbfb280b2bcf7c558409ce83b5d311fce5f019ff34516ceb3883255c
data/CHANGELOG.md CHANGED
@@ -2,6 +2,53 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [2.17.0] - 2025-06-02
6
+
7
+ ### Added
8
+
9
+ * Tracing: Add support for Rails 8.0. ([#4455][])
10
+
11
+ ### Changed
12
+
13
+ * Core: Improve tracer error reporting when agent responds with error responses to remote configuration requests ([#4669][])
14
+ * Core: Profiling: Upgrade libdatadog dependency to version 18.1 ([#4577][])
15
+ * Dynamic Instrumentation: Improve UI reporting of application and host status ([#4678][])
16
+ * Tracing: Mark AWS integration spans as errored when AWS requests fail ([#4672][])
17
+
18
+ ### Fixed
19
+
20
+ * Error Tracking: remove error tracking support on Ruby 2.6 ([#4665][])
21
+ * Profiling: Fix profiling scheduler reporting corner case during shutdown ([#4679][])
22
+ * Tracing: Fix: The `on_error` warning for HTTP instrumentations ([#4673][])
23
+
24
+ ## [2.16.0] - 2025-05-19
25
+
26
+ ### Added
27
+
28
+ * Core: Add new configuration precedence value `environment` ([#4610][])
29
+ * Core: Add Source Code Integration (SCI) tags in Telemetry app-started event and in each Remote Config request ([#4653][])
30
+ * Core: Tracing: ErrorTracking: Add automatic reporting of handled errors ([#4604][])
31
+ * AppSec: Integrations: Add session tracking and attacker fingerprinting to `devise` and `rails` ([#4644][], [#4625][])
32
+ * Profiling: Add support for Ruby 3.5.0-preview1 ([#4600][])
33
+ * Tracing: Add warning when `on_error` handler is not a `Proc` ([#4611][])
34
+ * Tracing: Integrations: Add option to serialize MongoDB command as JSON ([#4403][])
35
+ * Tracing: Integrations: Add baggage to `karafka` list of propagation styles ([#4614][])
36
+
37
+ ### Changed
38
+
39
+ * Tracing: Adjust trace sampling formula ([#4616][])
40
+ * Profiling: Replace `JSON.fast_generate` with `JSON.generate` ([#4602][])
41
+
42
+ ### Fixed
43
+
44
+ * Core: Fix Ruby warnings when providing a custom time provider ([#4613][])
45
+ * Core: Fix Telemetry configuration in agentless mode to respect the timeout specified for the Agent ([#4590][])
46
+ * Profiling: Fix profiler compatibility with ruby-head (3.5) ([#4656][])
47
+
48
+ ### Removed
49
+
50
+ * Core: Remove duplicated classes from Telemetry transport ([#4575][])
51
+
5
52
  ## [2.15.0] - 2025-04-17
6
53
 
7
54
  ### Added
@@ -3194,7 +3241,9 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
3194
3241
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3195
3242
 
3196
3243
 
3197
- [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.15.0...master
3244
+ [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.17.0...master
3245
+ [2.17.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.16.0...v2.17.0
3246
+ [2.16.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.15.0...v2.16.0
3198
3247
  [2.15.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.14.0...v2.15.0
3199
3248
  [2.14.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.13.0...v2.14.0
3200
3249
  [2.13.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.12.2...v2.13.0
@@ -4696,6 +4745,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4696
4745
  [#4391]: https://github.com/DataDog/dd-trace-rb/issues/4391
4697
4746
  [#4398]: https://github.com/DataDog/dd-trace-rb/issues/4398
4698
4747
  [#4399]: https://github.com/DataDog/dd-trace-rb/issues/4399
4748
+ [#4403]: https://github.com/DataDog/dd-trace-rb/issues/4403
4699
4749
  [#4406]: https://github.com/DataDog/dd-trace-rb/issues/4406
4700
4750
  [#4411]: https://github.com/DataDog/dd-trace-rb/issues/4411
4701
4751
  [#4422]: https://github.com/DataDog/dd-trace-rb/issues/4422
@@ -4704,6 +4754,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4704
4754
  [#4426]: https://github.com/DataDog/dd-trace-rb/issues/4426
4705
4755
  [#4433]: https://github.com/DataDog/dd-trace-rb/issues/4433
4706
4756
  [#4437]: https://github.com/DataDog/dd-trace-rb/issues/4437
4757
+ [#4455]: https://github.com/DataDog/dd-trace-rb/issues/4455
4707
4758
  [#4473]: https://github.com/DataDog/dd-trace-rb/issues/4473
4708
4759
  [#4493]: https://github.com/DataDog/dd-trace-rb/issues/4493
4709
4760
  [#4497]: https://github.com/DataDog/dd-trace-rb/issues/4497
@@ -4721,8 +4772,29 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4721
4772
  [#4558]: https://github.com/DataDog/dd-trace-rb/issues/4558
4722
4773
  [#4568]: https://github.com/DataDog/dd-trace-rb/issues/4568
4723
4774
  [#4573]: https://github.com/DataDog/dd-trace-rb/issues/4573
4775
+ [#4575]: https://github.com/DataDog/dd-trace-rb/issues/4575
4776
+ [#4577]: https://github.com/DataDog/dd-trace-rb/issues/4577
4724
4777
  [#4580]: https://github.com/DataDog/dd-trace-rb/issues/4580
4725
4778
  [#4581]: https://github.com/DataDog/dd-trace-rb/issues/4581
4779
+ [#4590]: https://github.com/DataDog/dd-trace-rb/issues/4590
4780
+ [#4600]: https://github.com/DataDog/dd-trace-rb/issues/4600
4781
+ [#4602]: https://github.com/DataDog/dd-trace-rb/issues/4602
4782
+ [#4604]: https://github.com/DataDog/dd-trace-rb/issues/4604
4783
+ [#4610]: https://github.com/DataDog/dd-trace-rb/issues/4610
4784
+ [#4611]: https://github.com/DataDog/dd-trace-rb/issues/4611
4785
+ [#4613]: https://github.com/DataDog/dd-trace-rb/issues/4613
4786
+ [#4614]: https://github.com/DataDog/dd-trace-rb/issues/4614
4787
+ [#4616]: https://github.com/DataDog/dd-trace-rb/issues/4616
4788
+ [#4625]: https://github.com/DataDog/dd-trace-rb/issues/4625
4789
+ [#4644]: https://github.com/DataDog/dd-trace-rb/issues/4644
4790
+ [#4653]: https://github.com/DataDog/dd-trace-rb/issues/4653
4791
+ [#4656]: https://github.com/DataDog/dd-trace-rb/issues/4656
4792
+ [#4665]: https://github.com/DataDog/dd-trace-rb/issues/4665
4793
+ [#4669]: https://github.com/DataDog/dd-trace-rb/issues/4669
4794
+ [#4672]: https://github.com/DataDog/dd-trace-rb/issues/4672
4795
+ [#4673]: https://github.com/DataDog/dd-trace-rb/issues/4673
4796
+ [#4678]: https://github.com/DataDog/dd-trace-rb/issues/4678
4797
+ [#4679]: https://github.com/DataDog/dd-trace-rb/issues/4679
4726
4798
  [@AdrianLC]: https://github.com/AdrianLC
4727
4799
  [@Azure7111]: https://github.com/Azure7111
4728
4800
  [@BabyGroot]: https://github.com/BabyGroot
@@ -4874,4 +4946,4 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4874
4946
  [@y-yagi]: https://github.com/y-yagi
4875
4947
  [@yujideveloper]: https://github.com/yujideveloper
4876
4948
  [@yukimurasawa]: https://github.com/yukimurasawa
4877
- [@zachmccormick]: https://github.com/zachmccormick
4949
+ [@zachmccormick]: https://github.com/zachmccormick
@@ -29,10 +29,7 @@ VALUE datadog_gem_version(void) {
29
29
  }
30
30
 
31
31
  static VALUE log_failure_to_process_tag(VALUE err_details) {
32
- VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
33
- VALUE logger = rb_funcall(datadog_module, rb_intern("logger"), 0);
34
-
35
- return rb_funcall(logger, rb_intern("warn"), 1, rb_sprintf("Failed to convert tag: %"PRIsVALUE, err_details));
32
+ return log_warning(rb_sprintf("Failed to convert tag: %"PRIsVALUE, err_details));
36
33
  }
37
34
 
38
35
  __attribute__((warn_unused_result))
@@ -41,6 +41,13 @@ static inline ddog_CharSlice char_slice_from_ruby_string(VALUE string) {
41
41
  return char_slice;
42
42
  }
43
43
 
44
+ static inline VALUE log_warning(VALUE warning) {
45
+ VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
46
+ VALUE logger = rb_funcall(datadog_module, rb_intern("logger"), 0);
47
+
48
+ return rb_funcall(logger, rb_intern("warn"), 1, warning);
49
+ }
50
+
44
51
  __attribute__((warn_unused_result))
45
52
  ddog_Vec_Tag convert_tags(VALUE tags_as_array);
46
53
 
@@ -38,6 +38,26 @@ VALUE from_ddog_prof_EncodedProfile(ddog_prof_EncodedProfile profile) {
38
38
  return TypedData_Wrap_Struct(encoded_profile_class, &encoded_profile_typed_data, state);
39
39
  }
40
40
 
41
+ static ddog_ByteSlice get_bytes(ddog_prof_EncodedProfile *state) {
42
+ ddog_prof_Result_ByteSlice raw_bytes = ddog_prof_EncodedProfile_bytes(state);
43
+ if (raw_bytes.tag == DDOG_PROF_RESULT_BYTE_SLICE_ERR_BYTE_SLICE) {
44
+ rb_raise(rb_eRuntimeError, "Failed to get bytes from profile: %"PRIsVALUE, get_error_details_and_drop(&raw_bytes.err));
45
+ }
46
+ return raw_bytes.ok;
47
+ }
48
+
49
+ static ddog_prof_EncodedProfile *internal_to_ddog_prof_EncodedProfile(VALUE object) {
50
+ ddog_prof_EncodedProfile *state;
51
+ TypedData_Get_Struct(object, ddog_prof_EncodedProfile, &encoded_profile_typed_data, state);
52
+ return state;
53
+ }
54
+
55
+ ddog_prof_EncodedProfile *to_ddog_prof_EncodedProfile(VALUE object) {
56
+ ddog_prof_EncodedProfile *state = internal_to_ddog_prof_EncodedProfile(object);
57
+ get_bytes(state); // Validate profile is still usable -- if it's not, this will raise an exception
58
+ return state;
59
+ }
60
+
41
61
  static void encoded_profile_typed_data_free(void *state_ptr) {
42
62
  ddog_prof_EncodedProfile *state = (ddog_prof_EncodedProfile *) state_ptr;
43
63
 
@@ -49,18 +69,8 @@ static void encoded_profile_typed_data_free(void *state_ptr) {
49
69
  }
50
70
 
51
71
  static VALUE _native_bytes(VALUE self) {
52
- ddog_prof_EncodedProfile *state;
53
- TypedData_Get_Struct(self, ddog_prof_EncodedProfile, &encoded_profile_typed_data, state);
54
-
55
- return ruby_string_from_vec_u8(state->buffer);
56
-
57
- // TODO: This will be used for libdatadog 17
58
- /*ddog_prof_Result_ByteSlice raw_bytes = ddog_prof_EncodedProfile_bytes(state);
59
- if (raw_bytes.tag == DDOG_PROF_RESULT_BYTE_SLICE_ERR_BYTE_SLICE) {
60
- rb_raise(rb_eRuntimeError, "Failed to get bytes from profile: %"PRIsVALUE, get_error_details_and_drop(&raw_bytes.err));
61
- }
62
-
63
- return rb_str_new((const char *) raw_bytes.ok.ptr, raw_bytes.ok.len);*/
72
+ ddog_ByteSlice bytes = get_bytes(internal_to_ddog_prof_EncodedProfile(self));
73
+ return rb_str_new((const char *) bytes.ptr, bytes.len);
64
74
  }
65
75
 
66
76
  VALUE enforce_encoded_profile_instance(VALUE object) {
@@ -5,3 +5,4 @@
5
5
 
6
6
  VALUE from_ddog_prof_EncodedProfile(ddog_prof_EncodedProfile profile);
7
7
  VALUE enforce_encoded_profile_instance(VALUE object);
8
+ ddog_prof_EncodedProfile *to_ddog_prof_EncodedProfile(VALUE object);
@@ -131,6 +131,9 @@ end
131
131
 
132
132
  have_func "malloc_stats"
133
133
 
134
+ # On Ruby 3.5, we can't ask the object_id from IMEMOs (https://github.com/ruby/ruby/pull/13347)
135
+ $defs << "-DNO_IMEMO_OBJECT_ID" unless RUBY_VERSION < "3.5"
136
+
134
137
  # On Ruby 2.5 and 3.3, this symbol was not visible. It is on 2.6 to 3.2, as well as 3.4+
135
138
  $defs << "-DNO_RB_OBJ_INFO" if RUBY_VERSION.start_with?("2.5", "3.3")
136
139
 
@@ -314,7 +314,14 @@ void start_heap_allocation_recording(heap_recorder *heap_recorder, VALUE new_obj
314
314
  rb_raise(rb_eRuntimeError, "Detected consecutive heap allocation recording starts without end.");
315
315
  }
316
316
 
317
- if (++heap_recorder->num_recordings_skipped < heap_recorder->sample_rate) {
317
+ if (++heap_recorder->num_recordings_skipped < heap_recorder->sample_rate ||
318
+ #ifdef NO_IMEMO_OBJECT_ID
319
+ // On Ruby 3.5, we can't ask the object_id from IMEMOs (https://github.com/ruby/ruby/pull/13347)
320
+ RB_BUILTIN_TYPE(new_obj) == RUBY_T_IMEMO
321
+ #else
322
+ false
323
+ #endif
324
+ ) {
318
325
  heap_recorder->active_recording = &SKIPPED_RECORD;
319
326
  return;
320
327
  }
@@ -15,26 +15,22 @@ static VALUE error_symbol = Qnil; // :error in Ruby
15
15
  static VALUE library_version_string = Qnil;
16
16
 
17
17
  typedef struct {
18
- ddog_prof_Exporter *exporter;
19
- ddog_prof_Exporter_Request_BuildResult *build_result;
18
+ ddog_prof_ProfileExporter *exporter;
19
+ ddog_prof_Request_Result *build_result;
20
20
  ddog_CancellationToken *cancel_token;
21
- ddog_prof_Exporter_SendResult result;
21
+ ddog_prof_Result_HttpStatus result;
22
22
  bool send_ran;
23
23
  } call_exporter_without_gvl_arguments;
24
24
 
25
25
  static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string);
26
26
  static VALUE _native_validate_exporter(VALUE self, VALUE exporter_configuration);
27
- static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration, VALUE tags_as_array);
28
- 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);
29
29
  static VALUE _native_do_export(
30
30
  VALUE self,
31
31
  VALUE exporter_configuration,
32
32
  VALUE upload_timeout_milliseconds,
33
- VALUE flush,
34
- VALUE start_timespec_seconds,
35
- VALUE start_timespec_nanoseconds,
36
- VALUE finish_timespec_seconds,
37
- VALUE finish_timespec_nanoseconds
33
+ VALUE flush
38
34
  );
39
35
  static void *call_exporter_without_gvl(void *call_args);
40
36
  static void interrupt_exporter_call(void *cancel_token);
@@ -43,7 +39,7 @@ void http_transport_init(VALUE profiling_module) {
43
39
  VALUE http_transport_class = rb_define_class_under(profiling_module, "HttpTransport", rb_cObject);
44
40
 
45
41
  rb_define_singleton_method(http_transport_class, "_native_validate_exporter", _native_validate_exporter, 1);
46
- rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export, 7);
42
+ rb_define_singleton_method(http_transport_class, "_native_do_export", _native_do_export, 3);
47
43
 
48
44
  ok_symbol = ID2SYM(rb_intern_const("ok"));
49
45
  error_symbol = ID2SYM(rb_intern_const("error"));
@@ -60,14 +56,14 @@ static inline ddog_ByteSlice byte_slice_from_ruby_string(VALUE string) {
60
56
 
61
57
  static VALUE _native_validate_exporter(DDTRACE_UNUSED VALUE _self, VALUE exporter_configuration) {
62
58
  ENFORCE_TYPE(exporter_configuration, T_ARRAY);
63
- 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());
64
60
 
65
61
  VALUE failure_tuple = handle_exporter_failure(exporter_result);
66
62
  if (!NIL_P(failure_tuple)) return failure_tuple;
67
63
 
68
64
  // We don't actually need the exporter for now -- we just wanted to validate that we could create it with the
69
65
  // settings we were given
70
- ddog_prof_Exporter_drop(exporter_result.ok);
66
+ ddog_prof_Exporter_drop(&exporter_result.ok);
71
67
 
72
68
  return rb_ary_new_from_args(2, ok_symbol, Qnil);
73
69
  }
@@ -93,7 +89,7 @@ static ddog_prof_Endpoint endpoint_from(VALUE exporter_configuration) {
93
89
  }
94
90
  }
95
91
 
96
- 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) {
97
93
  ENFORCE_TYPE(exporter_configuration, T_ARRAY);
98
94
  ENFORCE_TYPE(tags_as_array, T_ARRAY);
99
95
 
@@ -107,7 +103,7 @@ static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration
107
103
  ddog_CharSlice library_version = char_slice_from_ruby_string(library_version_string);
108
104
  ddog_CharSlice profiling_family = DDOG_CHARSLICE_C("ruby");
109
105
 
110
- ddog_prof_Exporter_NewResult exporter_result =
106
+ ddog_prof_ProfileExporter_Result exporter_result =
111
107
  ddog_prof_Exporter_new(library_name, library_version, profiling_family, &tags, endpoint);
112
108
 
113
109
  ddog_Vec_Tag_drop(tags);
@@ -115,8 +111,12 @@ static ddog_prof_Exporter_NewResult create_exporter(VALUE exporter_configuration
115
111
  return exporter_result;
116
112
  }
117
113
 
118
- static VALUE handle_exporter_failure(ddog_prof_Exporter_NewResult exporter_result) {
119
- 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 ?
120
120
  Qnil :
121
121
  rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&exporter_result.err));
122
122
  }
@@ -124,38 +124,37 @@ static VALUE handle_exporter_failure(ddog_prof_Exporter_NewResult exporter_resul
124
124
  // Note: This function handles a bunch of libdatadog dynamically-allocated objects, so it MUST not use any Ruby APIs
125
125
  // which can raise exceptions, otherwise the objects will be leaked.
126
126
  static VALUE perform_export(
127
- ddog_prof_Exporter *exporter,
128
- ddog_Timespec start,
129
- ddog_Timespec finish,
127
+ ddog_prof_ProfileExporter *exporter,
128
+ ddog_prof_EncodedProfile *profile,
130
129
  ddog_prof_Exporter_Slice_File files_to_compress_and_export,
131
- ddog_prof_Exporter_Slice_File files_to_export_unmodified,
132
130
  ddog_CharSlice internal_metadata,
133
131
  ddog_CharSlice info
134
132
  ) {
135
- ddog_prof_ProfiledEndpointsStats *endpoints_stats = NULL; // Not in use yet
136
- ddog_prof_Exporter_Request_BuildResult build_result = ddog_prof_Exporter_Request_build(
133
+ ddog_prof_Request_Result build_result = ddog_prof_Exporter_Request_build(
137
134
  exporter,
138
- start,
139
- finish,
135
+ profile,
140
136
  files_to_compress_and_export,
141
- files_to_export_unmodified,
137
+ /* files_to_export_unmodified: */ ddog_prof_Exporter_Slice_File_empty(),
142
138
  /* optional_additional_tags: */ NULL,
143
- endpoints_stats,
144
139
  &internal_metadata,
145
140
  &info
146
141
  );
147
142
 
148
- if (build_result.tag == DDOG_PROF_EXPORTER_REQUEST_BUILD_RESULT_ERR) {
143
+ if (build_result.tag == DDOG_PROF_REQUEST_RESULT_ERR_HANDLE_REQUEST) {
149
144
  ddog_prof_Exporter_drop(exporter);
150
145
  return rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&build_result.err));
151
146
  }
152
147
 
153
- 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__);
154
153
 
155
154
  // We'll release the Global VM Lock while we're calling send, so that the Ruby VM can continue to work while this
156
155
  // is pending
157
156
  call_exporter_without_gvl_arguments args =
158
- {.exporter = exporter, .build_result = &build_result, .cancel_token = cancel_token, .send_ran = false};
157
+ {.exporter = exporter, .build_result = &build_result, .cancel_token = &cancel_token_request, .send_ran = false};
159
158
 
160
159
  // We use rb_thread_call_without_gvl2 instead of rb_thread_call_without_gvl as the gvl2 variant never raises any
161
160
  // exceptions.
@@ -172,14 +171,15 @@ static VALUE perform_export(
172
171
  int pending_exception = 0;
173
172
 
174
173
  while (!args.send_ran && !pending_exception) {
175
- 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);
176
175
 
177
176
  // To make sure we don't leak memory, we never check for pending exceptions if send ran
178
177
  if (!args.send_ran) pending_exception = check_if_pending_exception();
179
178
  }
180
179
 
181
180
  // Cleanup exporter and token, no longer needed
182
- ddog_CancellationToken_drop(cancel_token);
181
+ ddog_CancellationToken_drop(&cancel_token_request);
182
+ ddog_CancellationToken_drop(&cancel_token_interrupt);
183
183
  ddog_prof_Exporter_drop(exporter);
184
184
 
185
185
  if (pending_exception) {
@@ -192,10 +192,10 @@ static VALUE perform_export(
192
192
 
193
193
  // The request itself does not need to be freed as libdatadog takes ownership of it as part of sending.
194
194
 
195
- ddog_prof_Exporter_SendResult result = args.result;
195
+ ddog_prof_Result_HttpStatus result = args.result;
196
196
 
197
- return result.tag == DDOG_PROF_EXPORTER_SEND_RESULT_HTTP_RESPONSE ?
198
- 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)) :
199
199
  rb_ary_new_from_args(2, error_symbol, get_error_details_and_drop(&result.err));
200
200
  }
201
201
 
@@ -203,11 +203,7 @@ static VALUE _native_do_export(
203
203
  DDTRACE_UNUSED VALUE _self,
204
204
  VALUE exporter_configuration,
205
205
  VALUE upload_timeout_milliseconds,
206
- VALUE flush,
207
- VALUE start_timespec_seconds,
208
- VALUE start_timespec_nanoseconds,
209
- VALUE finish_timespec_seconds,
210
- VALUE finish_timespec_nanoseconds
206
+ VALUE flush
211
207
  ) {
212
208
  VALUE encoded_profile = rb_funcall(flush, rb_intern("encoded_profile"), 0);
213
209
  VALUE code_provenance_file_name = rb_funcall(flush, rb_intern("code_provenance_file_name"), 0);
@@ -217,10 +213,6 @@ static VALUE _native_do_export(
217
213
  VALUE info_json = rb_funcall(flush, rb_intern("info_json"), 0);
218
214
 
219
215
  ENFORCE_TYPE(upload_timeout_milliseconds, T_FIXNUM);
220
- ENFORCE_TYPE(start_timespec_seconds, T_FIXNUM);
221
- ENFORCE_TYPE(start_timespec_nanoseconds, T_FIXNUM);
222
- ENFORCE_TYPE(finish_timespec_seconds, T_FIXNUM);
223
- ENFORCE_TYPE(finish_timespec_nanoseconds, T_FIXNUM);
224
216
  enforce_encoded_profile_instance(encoded_profile);
225
217
  ENFORCE_TYPE(code_provenance_file_name, T_STRING);
226
218
  ENFORCE_TYPE(tags_as_array, T_ARRAY);
@@ -233,28 +225,9 @@ static VALUE _native_do_export(
233
225
 
234
226
  uint64_t timeout_milliseconds = NUM2ULONG(upload_timeout_milliseconds);
235
227
 
236
- ddog_Timespec start =
237
- {.seconds = NUM2LONG(start_timespec_seconds), .nanoseconds = NUM2UINT(start_timespec_nanoseconds)};
238
- ddog_Timespec finish =
239
- {.seconds = NUM2LONG(finish_timespec_seconds), .nanoseconds = NUM2UINT(finish_timespec_nanoseconds)};
240
-
241
228
  int to_compress_length = have_code_provenance ? 1 : 0;
242
229
  ddog_prof_Exporter_File to_compress[to_compress_length];
243
- int already_compressed_length = 1; // pprof
244
- ddog_prof_Exporter_File already_compressed[already_compressed_length];
245
-
246
230
  ddog_prof_Exporter_Slice_File files_to_compress_and_export = {.ptr = to_compress, .len = to_compress_length};
247
- ddog_prof_Exporter_Slice_File files_to_export_unmodified = {.ptr = already_compressed, .len = already_compressed_length};
248
-
249
- // TODO: Hardcoding the file name will go away with libdatadog 17
250
- VALUE pprof_file_name = rb_str_new_cstr("rubyprofile.pprof");
251
- VALUE pprof_data = rb_funcall(encoded_profile, rb_intern("_native_bytes"), 0);
252
- ENFORCE_TYPE(pprof_data, T_STRING);
253
-
254
- already_compressed[0] = (ddog_prof_Exporter_File) {
255
- .name = char_slice_from_ruby_string(pprof_file_name),
256
- .file = byte_slice_from_ruby_string(pprof_data),
257
- };
258
231
 
259
232
  if (have_code_provenance) {
260
233
  to_compress[0] = (ddog_prof_Exporter_File) {
@@ -266,27 +239,25 @@ static VALUE _native_do_export(
266
239
  ddog_CharSlice internal_metadata = char_slice_from_ruby_string(internal_metadata_json);
267
240
  ddog_CharSlice info = char_slice_from_ruby_string(info_json);
268
241
 
269
- 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);
270
243
  // Note: Do not add anything that can raise exceptions after this line, as otherwise the exporter memory will leak
271
244
 
272
245
  VALUE failure_tuple = handle_exporter_failure(exporter_result);
273
246
  if (!NIL_P(failure_tuple)) return failure_tuple;
274
247
 
275
- ddog_prof_MaybeError timeout_result = ddog_prof_Exporter_set_timeout(exporter_result.ok, timeout_milliseconds);
276
- 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) {
277
250
  // NOTE: Seems a bit harsh to fail the upload if we can't set a timeout. OTOH, this is only expected to fail
278
251
  // if the exporter is not well built. Because such a situation should already be caught above I think it's
279
252
  // preferable to leave this here as a virtually unreachable exception rather than ignoring it.
280
- ddog_prof_Exporter_drop(exporter_result.ok);
281
- 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));
282
255
  }
283
256
 
284
257
  return perform_export(
285
- exporter_result.ok,
286
- start,
287
- finish,
258
+ &exporter_result.ok,
259
+ to_ddog_prof_EncodedProfile(encoded_profile),
288
260
  files_to_compress_and_export,
289
- files_to_export_unmodified,
290
261
  internal_metadata,
291
262
  info
292
263
  );
@@ -303,5 +274,7 @@ static void *call_exporter_without_gvl(void *call_args) {
303
274
 
304
275
  // Called by Ruby when it wants to interrupt call_exporter_without_gvl above, e.g. when the app wants to exit cleanly
305
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...
306
279
  ddog_CancellationToken_cancel((ddog_CancellationToken *) cancel_token);
307
280
  }
@@ -363,7 +363,7 @@ static void initialize_profiles(stack_recorder_state *state, ddog_prof_Slice_Val
363
363
  ddog_Timespec start_timestamp = system_epoch_now_timespec();
364
364
 
365
365
  ddog_prof_Profile_NewResult slot_one_profile_result =
366
- ddog_prof_Profile_new(sample_types, NULL /* period is optional */, &start_timestamp);
366
+ ddog_prof_Profile_new(sample_types, NULL /* period is optional */);
367
367
 
368
368
  if (slot_one_profile_result.tag == DDOG_PROF_PROFILE_NEW_RESULT_ERR) {
369
369
  rb_raise(rb_eRuntimeError, "Failed to initialize slot one profile: %"PRIsVALUE, get_error_details_and_drop(&slot_one_profile_result.err));
@@ -372,7 +372,7 @@ static void initialize_profiles(stack_recorder_state *state, ddog_prof_Slice_Val
372
372
  state->profile_slot_one = (profile_slot) { .profile = slot_one_profile_result.ok, .start_timestamp = start_timestamp };
373
373
 
374
374
  ddog_prof_Profile_NewResult slot_two_profile_result =
375
- ddog_prof_Profile_new(sample_types, NULL /* period is optional */, &start_timestamp);
375
+ ddog_prof_Profile_new(sample_types, NULL /* period is optional */);
376
376
 
377
377
  if (slot_two_profile_result.tag == DDOG_PROF_PROFILE_NEW_RESULT_ERR) {
378
378
  // Note: No need to take any special care of slot one, it'll get cleaned up by stack_recorder_typed_data_free
@@ -763,7 +763,6 @@ static void *call_serialize_without_gvl(void *call_args) {
763
763
  long serialize_no_gvl_start_time_ns = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE);
764
764
 
765
765
  profile_slot *slot_now_inactive = serializer_flip_active_and_inactive_slots(args->state);
766
-
767
766
  args->slot = slot_now_inactive;
768
767
 
769
768
  // Now that we have the inactive profile with all but heap samples, lets fill it with heap data
@@ -772,7 +771,7 @@ static void *call_serialize_without_gvl(void *call_args) {
772
771
  args->heap_profile_build_time_ns = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE) - serialize_no_gvl_start_time_ns;
773
772
 
774
773
  // Note: The profile gets reset by the serialize call
775
- args->result = ddog_prof_Profile_serialize(&args->slot->profile, &args->finish_timestamp, NULL /* duration_nanos is optional */, NULL /* start_time is optional */);
774
+ args->result = ddog_prof_Profile_serialize(&args->slot->profile, &args->slot->start_timestamp, &args->finish_timestamp);
776
775
  args->serialize_ran = true;
777
776
  args->serialize_no_gvl_time_ns = monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE) - serialize_no_gvl_start_time_ns;
778
777
 
@@ -949,7 +948,7 @@ static VALUE _native_check_heap_hashes(DDTRACE_UNUSED VALUE _self, VALUE locatio
949
948
  }
950
949
 
951
950
  static void reset_profile_slot(profile_slot *slot, ddog_Timespec start_timestamp) {
952
- ddog_prof_Profile_Result reset_result = ddog_prof_Profile_reset(&slot->profile, &start_timestamp);
951
+ ddog_prof_Profile_Result reset_result = ddog_prof_Profile_reset(&slot->profile);
953
952
  if (reset_result.tag == DDOG_PROF_PROFILE_RESULT_ERR) {
954
953
  rb_raise(rb_eRuntimeError, "Failed to reset profile: %"PRIsVALUE, get_error_details_and_drop(&reset_result.err));
955
954
  }
@@ -5,20 +5,14 @@
5
5
 
6
6
  static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self);
7
7
  static VALUE _native_stop(DDTRACE_UNUSED VALUE _self);
8
- static void crashtracker_init(VALUE crashtracking_module);
8
+
9
+ static bool first_init = true;
9
10
 
10
11
  // Used to report Ruby VM crashes.
11
12
  // Once initialized, segfaults will be reported automatically using libdatadog.
12
13
 
13
- void DDTRACE_EXPORT Init_libdatadog_api(void) {
14
- VALUE datadog_module = rb_define_module("Datadog");
15
- VALUE core_module = rb_define_module_under(datadog_module, "Core");
14
+ void crashtracker_init(VALUE core_module) {
16
15
  VALUE crashtracking_module = rb_define_module_under(core_module, "Crashtracking");
17
-
18
- crashtracker_init(crashtracking_module);
19
- }
20
-
21
- void crashtracker_init(VALUE crashtracking_module) {
22
16
  VALUE crashtracker_class = rb_define_class_under(crashtracking_module, "Component", rb_cObject);
23
17
 
24
18
  rb_define_singleton_method(crashtracker_class, "_native_start_or_update_on_fork", _native_start_or_update_on_fork, -1);
@@ -70,7 +64,7 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
70
64
  // "Process.kill('SEGV', Process.pid)" gets run.
71
65
  //
72
66
  // This actually changed in libdatadog 14, so I could see no issues with `create_alt_stack = true`, but not
73
- // overridding what Ruby set up seems a saner default to keep anyway.
67
+ // overriding what Ruby set up seems a saner default to keep anyway.
74
68
  .create_alt_stack = false,
75
69
  .use_alt_stack = true,
76
70
  .endpoint = endpoint,
@@ -100,9 +94,14 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
100
94
 
101
95
  ddog_VoidResult result =
102
96
  action == start_action ?
103
- ddog_crasht_init(config, receiver_config, metadata) :
97
+ (first_init ?
98
+ ddog_crasht_init(config, receiver_config, metadata) :
99
+ ddog_crasht_reconfigure(config, receiver_config, metadata)
100
+ ) :
104
101
  ddog_crasht_update_on_fork(config, receiver_config, metadata);
105
102
 
103
+ first_init = false;
104
+
106
105
  // Clean up before potentially raising any exceptions
107
106
  ddog_Vec_Tag_drop(tags);
108
107
  ddog_endpoint_drop(endpoint);
@@ -116,7 +115,7 @@ static VALUE _native_start_or_update_on_fork(int argc, VALUE *argv, DDTRACE_UNUS
116
115
  }
117
116
 
118
117
  static VALUE _native_stop(DDTRACE_UNUSED VALUE _self) {
119
- ddog_VoidResult result = ddog_crasht_shutdown();
118
+ ddog_VoidResult result = ddog_crasht_disable();
120
119
 
121
120
  if (result.tag == DDOG_VOID_RESULT_ERR) {
122
121
  rb_raise(rb_eRuntimeError, "Failed to stop the crash tracker: %"PRIsVALUE, get_error_details_and_drop(&result.err));
@@ -0,0 +1,5 @@
1
+ #pragma once
2
+
3
+ #include "datadog_ruby_common.h"
4
+
5
+ void crashtracker_init(VALUE core_module);
@@ -29,10 +29,7 @@ VALUE datadog_gem_version(void) {
29
29
  }
30
30
 
31
31
  static VALUE log_failure_to_process_tag(VALUE err_details) {
32
- VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
33
- VALUE logger = rb_funcall(datadog_module, rb_intern("logger"), 0);
34
-
35
- return rb_funcall(logger, rb_intern("warn"), 1, rb_sprintf("Failed to convert tag: %"PRIsVALUE, err_details));
32
+ return log_warning(rb_sprintf("Failed to convert tag: %"PRIsVALUE, err_details));
36
33
  }
37
34
 
38
35
  __attribute__((warn_unused_result))
@@ -41,6 +41,13 @@ static inline ddog_CharSlice char_slice_from_ruby_string(VALUE string) {
41
41
  return char_slice;
42
42
  }
43
43
 
44
+ static inline VALUE log_warning(VALUE warning) {
45
+ VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
46
+ VALUE logger = rb_funcall(datadog_module, rb_intern("logger"), 0);
47
+
48
+ return rb_funcall(logger, rb_intern("warn"), 1, warning);
49
+ }
50
+
44
51
  __attribute__((warn_unused_result))
45
52
  ddog_Vec_Tag convert_tags(VALUE tags_as_array);
46
53