datadog 2.15.0 → 2.16.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 (121) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -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/extconf.rb +3 -0
  6. data/ext/datadog_profiling_native_extension/heap_recorder.c +8 -1
  7. data/ext/libdatadog_api/crashtracker.c +1 -9
  8. data/ext/libdatadog_api/crashtracker.h +5 -0
  9. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  10. data/ext/libdatadog_api/datadog_ruby_common.h +7 -0
  11. data/ext/libdatadog_api/init.c +15 -0
  12. data/ext/libdatadog_api/library_config.c +122 -0
  13. data/ext/libdatadog_api/library_config.h +19 -0
  14. data/ext/libdatadog_api/process_discovery.c +117 -0
  15. data/ext/libdatadog_api/process_discovery.h +5 -0
  16. data/lib/datadog/appsec/actions_handler.rb +3 -2
  17. data/lib/datadog/appsec/assets/waf_rules/recommended.json +1344 -0
  18. data/lib/datadog/appsec/assets/waf_rules/strict.json +1344 -0
  19. data/lib/datadog/appsec/autoload.rb +1 -1
  20. data/lib/datadog/appsec/component.rb +11 -4
  21. data/lib/datadog/appsec/configuration/settings.rb +31 -18
  22. data/lib/datadog/appsec/context.rb +1 -1
  23. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +10 -12
  24. data/lib/datadog/appsec/contrib/active_record/integration.rb +1 -1
  25. data/lib/datadog/appsec/contrib/active_record/patcher.rb +22 -22
  26. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +2 -3
  27. data/lib/datadog/appsec/contrib/devise/ext.rb +1 -0
  28. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -1
  29. data/lib/datadog/appsec/contrib/devise/patcher.rb +3 -5
  30. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +17 -4
  31. data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
  32. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +9 -10
  33. data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
  34. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +8 -9
  35. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +8 -9
  36. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  37. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +22 -32
  38. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  39. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +16 -16
  40. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +11 -13
  41. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  42. data/lib/datadog/appsec/contrib/rails/patcher.rb +21 -21
  43. data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
  44. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +10 -11
  45. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -23
  46. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  47. data/lib/datadog/appsec/event.rb +85 -95
  48. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +5 -2
  49. data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
  50. data/lib/datadog/appsec/monitor/gateway/watcher.rb +42 -12
  51. data/lib/datadog/appsec/processor/rule_loader.rb +26 -28
  52. data/lib/datadog/appsec/processor/rule_merger.rb +5 -5
  53. data/lib/datadog/appsec/processor.rb +1 -1
  54. data/lib/datadog/appsec/remote.rb +14 -13
  55. data/lib/datadog/appsec/response.rb +6 -6
  56. data/lib/datadog/appsec/security_engine/runner.rb +1 -1
  57. data/lib/datadog/appsec/security_event.rb +39 -0
  58. data/lib/datadog/appsec.rb +1 -1
  59. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  60. data/lib/datadog/core/configuration/components.rb +19 -10
  61. data/lib/datadog/core/configuration/option.rb +61 -25
  62. data/lib/datadog/core/configuration/settings.rb +10 -0
  63. data/lib/datadog/core/configuration/stable_config.rb +23 -0
  64. data/lib/datadog/core/configuration.rb +24 -0
  65. data/lib/datadog/core/crashtracking/component.rb +1 -9
  66. data/lib/datadog/core/environment/git.rb +1 -0
  67. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  68. data/lib/datadog/core/metrics/client.rb +8 -7
  69. data/lib/datadog/core/process_discovery.rb +32 -0
  70. data/lib/datadog/core/remote/client.rb +7 -0
  71. data/lib/datadog/core/runtime/metrics.rb +1 -1
  72. data/lib/datadog/core/telemetry/component.rb +60 -50
  73. data/lib/datadog/core/telemetry/emitter.rb +17 -11
  74. data/lib/datadog/core/telemetry/event.rb +7 -4
  75. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  76. data/lib/datadog/core/telemetry/request.rb +3 -3
  77. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  78. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  79. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  80. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  81. data/lib/datadog/core/telemetry/transport/telemetry.rb +52 -0
  82. data/lib/datadog/core/telemetry/worker.rb +45 -0
  83. data/lib/datadog/core/utils/time.rb +12 -0
  84. data/lib/datadog/core/workers/async.rb +20 -2
  85. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  86. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  87. data/lib/datadog/core.rb +8 -0
  88. data/lib/datadog/di/boot.rb +34 -0
  89. data/lib/datadog/di/remote.rb +2 -0
  90. data/lib/datadog/di.rb +5 -32
  91. data/lib/datadog/error_tracking/collector.rb +87 -0
  92. data/lib/datadog/error_tracking/component.rb +167 -0
  93. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  94. data/lib/datadog/error_tracking/configuration.rb +11 -0
  95. data/lib/datadog/error_tracking/ext.rb +18 -0
  96. data/lib/datadog/error_tracking/extensions.rb +16 -0
  97. data/lib/datadog/error_tracking/filters.rb +77 -0
  98. data/lib/datadog/error_tracking.rb +18 -0
  99. data/lib/datadog/kit/identity.rb +1 -1
  100. data/lib/datadog/profiling/exporter.rb +1 -1
  101. data/lib/datadog/tracing/analytics.rb +1 -1
  102. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +2 -0
  103. data/lib/datadog/tracing/contrib/karafka/monitor.rb +1 -1
  104. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  105. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  106. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  107. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  108. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  109. data/lib/datadog/tracing/distributed/datadog.rb +2 -2
  110. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  111. data/lib/datadog/tracing/span_operation.rb +38 -14
  112. data/lib/datadog/tracing/trace_operation.rb +15 -7
  113. data/lib/datadog/tracing/tracer.rb +7 -3
  114. data/lib/datadog/tracing/utils.rb +1 -1
  115. data/lib/datadog/version.rb +1 -1
  116. data/lib/datadog.rb +2 -3
  117. metadata +34 -8
  118. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  119. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  120. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  121. 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: da587b7c67d38c9ec9730e62603ffecf699d3841978676a06f0fe99506614a3d
4
+ data.tar.gz: d17d0f78fe1226187aedd815606ce3b450eb6150139c13116ce24082215452dd
5
5
  SHA512:
6
- metadata.gz: ef69c8e13819833ce2b1a0987ec66a674a15ca029bd4ad0a29703a613c7dd263015ca0018433ac366f69e655fa264a74aa949a1d6b12e30753b249fa8b7d62c2
7
- data.tar.gz: 1d44dca02ab71b49b87e371825bbdda696fbd686bc9d24662d5d90c5091c4ddf82226abda23c56da9da8e8274ab06759a90b73fd3eb44cecc081598fd8cc188a
6
+ metadata.gz: 8d40c4f84ca2396f1011bc27eeb5489a1ded2669c47473a838d5b70191c57b3e34beee38abe8c9737d13212bbf07221ec17a0b428023974ec7001465bbfa7745
7
+ data.tar.gz: '0155923613825e859fb952901a98f2a779a5128b1cb02cf4e3c619fb99b1bf9b4a7428b1e56cb8580103d52cc189a354df9a1db697c5b857a8c318d2a383bdba'
data/CHANGELOG.md CHANGED
@@ -2,6 +2,34 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [2.16.0] - 2025-05-19
6
+
7
+ ### Added
8
+
9
+ * Core: Add new configuration precedence value `environment` ([#4610][])
10
+ * Core: Add Source Code Integration (SCI) tags in Telemetry app-started event and in each Remote Config request ([#4653][])
11
+ * Core: Tracing: ErrorTracking: Add automatic reporting of handled errors ([#4604][])
12
+ * AppSec: Integrations: Add session tracking and attacker fingerprinting to `devise` and `rails` ([#4644][], [#4625][])
13
+ * Profiling: Add support for Ruby 3.5.0-preview1 ([#4600][])
14
+ * Tracing: Add warning when `on_error` handler is not a `Proc` ([#4611][])
15
+ * Tracing: Integrations: Add option to serialize MongoDB command as JSON ([#4403][])
16
+ * Tracing: Integrations: Add baggage to `karafka` list of propagation styles ([#4614][])
17
+
18
+ ### Changed
19
+
20
+ * Tracing: Adjust trace sampling formula ([#4616][])
21
+ * Profiling: Replace `JSON.fast_generate` with `JSON.generate` ([#4602][])
22
+
23
+ ### Fixed
24
+
25
+ * Core: Fix Ruby warnings when providing a custom time provider ([#4613][])
26
+ * Core: Fix Telemetry configuration in agentless mode to respect the timeout specified for the Agent ([#4590][])
27
+ * Profiling: Fix profiler compatibility with ruby-head (3.5) ([#4656][])
28
+
29
+ ### Removed
30
+
31
+ * Core: Remove duplicated classes from Telemetry transport ([#4575][])
32
+
5
33
  ## [2.15.0] - 2025-04-17
6
34
 
7
35
  ### Added
@@ -3194,7 +3222,8 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
3194
3222
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3195
3223
 
3196
3224
 
3197
- [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.15.0...master
3225
+ [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.16.0...master
3226
+ [2.16.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.15.0...v2.16.0
3198
3227
  [2.15.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.14.0...v2.15.0
3199
3228
  [2.14.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.13.0...v2.14.0
3200
3229
  [2.13.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.12.2...v2.13.0
@@ -4696,6 +4725,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4696
4725
  [#4391]: https://github.com/DataDog/dd-trace-rb/issues/4391
4697
4726
  [#4398]: https://github.com/DataDog/dd-trace-rb/issues/4398
4698
4727
  [#4399]: https://github.com/DataDog/dd-trace-rb/issues/4399
4728
+ [#4403]: https://github.com/DataDog/dd-trace-rb/issues/4403
4699
4729
  [#4406]: https://github.com/DataDog/dd-trace-rb/issues/4406
4700
4730
  [#4411]: https://github.com/DataDog/dd-trace-rb/issues/4411
4701
4731
  [#4422]: https://github.com/DataDog/dd-trace-rb/issues/4422
@@ -4721,8 +4751,22 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4721
4751
  [#4558]: https://github.com/DataDog/dd-trace-rb/issues/4558
4722
4752
  [#4568]: https://github.com/DataDog/dd-trace-rb/issues/4568
4723
4753
  [#4573]: https://github.com/DataDog/dd-trace-rb/issues/4573
4754
+ [#4575]: https://github.com/DataDog/dd-trace-rb/issues/4575
4724
4755
  [#4580]: https://github.com/DataDog/dd-trace-rb/issues/4580
4725
4756
  [#4581]: https://github.com/DataDog/dd-trace-rb/issues/4581
4757
+ [#4590]: https://github.com/DataDog/dd-trace-rb/issues/4590
4758
+ [#4600]: https://github.com/DataDog/dd-trace-rb/issues/4600
4759
+ [#4602]: https://github.com/DataDog/dd-trace-rb/issues/4602
4760
+ [#4604]: https://github.com/DataDog/dd-trace-rb/issues/4604
4761
+ [#4610]: https://github.com/DataDog/dd-trace-rb/issues/4610
4762
+ [#4611]: https://github.com/DataDog/dd-trace-rb/issues/4611
4763
+ [#4613]: https://github.com/DataDog/dd-trace-rb/issues/4613
4764
+ [#4614]: https://github.com/DataDog/dd-trace-rb/issues/4614
4765
+ [#4616]: https://github.com/DataDog/dd-trace-rb/issues/4616
4766
+ [#4625]: https://github.com/DataDog/dd-trace-rb/issues/4625
4767
+ [#4644]: https://github.com/DataDog/dd-trace-rb/issues/4644
4768
+ [#4653]: https://github.com/DataDog/dd-trace-rb/issues/4653
4769
+ [#4656]: https://github.com/DataDog/dd-trace-rb/issues/4656
4726
4770
  [@AdrianLC]: https://github.com/AdrianLC
4727
4771
  [@Azure7111]: https://github.com/Azure7111
4728
4772
  [@BabyGroot]: https://github.com/BabyGroot
@@ -4874,4 +4918,4 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4874
4918
  [@y-yagi]: https://github.com/y-yagi
4875
4919
  [@yujideveloper]: https://github.com/yujideveloper
4876
4920
  [@yukimurasawa]: https://github.com/yukimurasawa
4877
- [@zachmccormick]: https://github.com/zachmccormick
4921
+ [@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
 
@@ -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
  }
@@ -5,20 +5,12 @@
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);
9
8
 
10
9
  // Used to report Ruby VM crashes.
11
10
  // Once initialized, segfaults will be reported automatically using libdatadog.
12
11
 
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");
12
+ void crashtracker_init(VALUE core_module) {
16
13
  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
14
  VALUE crashtracker_class = rb_define_class_under(crashtracking_module, "Component", rb_cObject);
23
15
 
24
16
  rb_define_singleton_method(crashtracker_class, "_native_start_or_update_on_fork", _native_start_or_update_on_fork, -1);
@@ -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
 
@@ -0,0 +1,15 @@
1
+ #include <ruby.h>
2
+
3
+ #include "datadog_ruby_common.h"
4
+ #include "crashtracker.h"
5
+ #include "process_discovery.h"
6
+ #include "library_config.h"
7
+
8
+ void DDTRACE_EXPORT Init_libdatadog_api(void) {
9
+ VALUE datadog_module = rb_define_module("Datadog");
10
+ VALUE core_module = rb_define_module_under(datadog_module, "Core");
11
+
12
+ crashtracker_init(core_module);
13
+ process_discovery_init(core_module);
14
+ library_config_init(core_module);
15
+ }
@@ -0,0 +1,122 @@
1
+ #include <ruby.h>
2
+ #include <datadog/library-config.h>
3
+
4
+ #include "library_config.h"
5
+ #include "datadog_ruby_common.h"
6
+
7
+ static VALUE _native_configurator_new(VALUE klass);
8
+ static VALUE _native_configurator_get(VALUE self);
9
+
10
+ static VALUE config_vec_class = Qnil;
11
+
12
+ // ddog_Configurator memory management
13
+ static void configurator_free(void *configurator_ptr) {
14
+ ddog_Configurator *configurator = (ddog_Configurator *)configurator_ptr;
15
+
16
+ ddog_library_configurator_drop(configurator);
17
+ }
18
+
19
+ static const rb_data_type_t configurator_typed_data = {
20
+ .wrap_struct_name = "Datadog::Core::Configuration::StableConfig::Configurator",
21
+ .function = {
22
+ .dfree = configurator_free,
23
+ .dsize = NULL,
24
+ },
25
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
26
+ };
27
+
28
+ // ddog_Vec_LibraryConfig memory management
29
+ static void config_vec_free(void *config_vec_ptr) {
30
+ ddog_Vec_LibraryConfig *config_vec = (ddog_Vec_LibraryConfig *)config_vec_ptr;
31
+
32
+ ddog_library_config_drop(*config_vec);
33
+ ruby_xfree(config_vec_ptr);
34
+ }
35
+
36
+ static const rb_data_type_t config_vec_typed_data = {
37
+ .wrap_struct_name = "Datadog::Core::Configuration::StableConfigVec",
38
+ .function = {
39
+ .dfree = config_vec_free,
40
+ .dsize = NULL,
41
+ },
42
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
43
+ };
44
+
45
+ void library_config_init(VALUE core_module) {
46
+ rb_global_variable(&config_vec_class);
47
+ VALUE configuration_module = rb_define_module_under(core_module, "Configuration");
48
+ VALUE stable_config_module = rb_define_module_under(configuration_module, "StableConfig");
49
+ VALUE configurator_class = rb_define_class_under(stable_config_module, "Configurator", rb_cObject);
50
+ config_vec_class = rb_define_class_under(configuration_module, "StableConfigVec", rb_cObject);
51
+
52
+ rb_define_alloc_func(configurator_class, _native_configurator_new);
53
+ rb_define_method(configurator_class, "get", _native_configurator_get, 0);
54
+
55
+ rb_undef_alloc_func(config_vec_class); // It cannot be created from Ruby code and only serves as an intermediate object for the Ruby GC
56
+ }
57
+
58
+ // TODO: After libdatadog 17.1 release, delete rb_raise, uncomment code and change `DDTRACE_UNUSED VALUE _klass` by `VALUE klass`
59
+ static VALUE _native_configurator_new(DDTRACE_UNUSED VALUE _klass) {
60
+ /*
61
+ ddog_Configurator *configurator = ddog_library_configurator_new(false, DDOG_CHARSLICE_C("ruby"));
62
+
63
+ ddog_library_configurator_with_detect_process_info(configurator);
64
+
65
+ return TypedData_Wrap_Struct(klass, &configurator_typed_data, configurator);
66
+ */
67
+
68
+ rb_raise(rb_eNotImpError, "TODO: Not in use yet, waiting for libdatadog 17.1");
69
+ }
70
+
71
+ static VALUE _native_configurator_get(VALUE self) {
72
+ ddog_Configurator *configurator;
73
+ TypedData_Get_Struct(self, ddog_Configurator, &configurator_typed_data, configurator);
74
+
75
+ ddog_Result_VecLibraryConfig configurator_result = ddog_library_configurator_get(configurator);
76
+
77
+ if (configurator_result.tag == DDOG_RESULT_VEC_LIBRARY_CONFIG_ERR_VEC_LIBRARY_CONFIG) {
78
+ ddog_Error err = configurator_result.err;
79
+ VALUE message = get_error_details_and_drop(&err);
80
+ if (is_config_loaded()) {
81
+ log_warning(message);
82
+ } else {
83
+ log_warning_without_config(message);
84
+ }
85
+ return rb_hash_new();
86
+ }
87
+
88
+ // Wrapping config_vec into a Ruby object enables the Ruby GC to manage its memory
89
+ // We need to allocate memory for config_vec because once it is out of scope, it will be freed (at the end of this function)
90
+ // So we cannot reference it with &config_vec
91
+ // We are doing this in case one of the ruby API raises an exception before the end of this function,
92
+ // so the allocated memory will still be freed
93
+ ddog_Vec_LibraryConfig *config_vec = ruby_xmalloc(sizeof(ddog_Vec_LibraryConfig));
94
+ *config_vec = configurator_result.ok;
95
+ VALUE config_vec_rb = TypedData_Wrap_Struct(config_vec_class, &config_vec_typed_data, config_vec);
96
+
97
+ VALUE local_config_hash = rb_hash_new();
98
+ VALUE fleet_config_hash = rb_hash_new();
99
+ // TODO: Uncomment next block after libdatadog 17.1 release
100
+ /*
101
+ for (uintptr_t i = 0; i < config_vec->len; i++) {
102
+ ddog_LibraryConfig config = config_vec->ptr[i];
103
+ VALUE selected_hash;
104
+ if (config.source == DDOG_LIBRARY_CONFIG_SOURCE_LOCAL_STABLE_CONFIG) {
105
+ selected_hash = local_config_hash;
106
+ }
107
+ else {
108
+ selected_hash = fleet_config_hash;
109
+ }
110
+
111
+ ddog_CStr name = ddog_library_config_name_to_env(config.name);
112
+ rb_hash_aset(selected_hash, rb_str_new(name.ptr, name.length), rb_str_new(config.value.ptr, config.value.length));
113
+ }
114
+ */
115
+
116
+ VALUE result = rb_hash_new();
117
+ rb_hash_aset(result, ID2SYM(rb_intern("local")), local_config_hash);
118
+ rb_hash_aset(result, ID2SYM(rb_intern("fleet")), fleet_config_hash);
119
+
120
+ RB_GC_GUARD(config_vec_rb);
121
+ return result;
122
+ }
@@ -0,0 +1,19 @@
1
+ #pragma once
2
+
3
+ #include "datadog_ruby_common.h"
4
+
5
+ void library_config_init(VALUE core_module);
6
+
7
+ static inline bool is_config_loaded(void) {
8
+ VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
9
+ VALUE is_config_loaded = rb_funcall(datadog_module, rb_intern("configuration?"), 0);
10
+
11
+ return is_config_loaded == Qtrue;
12
+ }
13
+
14
+ static inline VALUE log_warning_without_config(VALUE warning) {
15
+ VALUE datadog_module = rb_const_get(rb_cObject, rb_intern("Datadog"));
16
+ VALUE logger = rb_funcall(datadog_module, rb_intern("logger_without_configuration"), 0);
17
+
18
+ return rb_funcall(logger, rb_intern("warn"), 1, warning);
19
+ }
@@ -0,0 +1,117 @@
1
+ #include <errno.h>
2
+ #include <stdlib.h>
3
+ #include <ruby.h>
4
+ #include <datadog/common.h>
5
+
6
+ #include "datadog_ruby_common.h"
7
+
8
+ static VALUE _native_store_tracer_metadata(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self);
9
+ static VALUE _native_to_rb_int(DDTRACE_UNUSED VALUE _self, VALUE tracer_memfd);
10
+ static VALUE _native_close_tracer_memfd(DDTRACE_UNUSED VALUE _self, VALUE tracer_memfd, VALUE logger);
11
+
12
+ static void tracer_memfd_free(void *ptr) {
13
+ int *fd = (int *)ptr;
14
+ if (*fd != -1) {
15
+ close(*fd);
16
+ }
17
+ ruby_xfree(ptr);
18
+ }
19
+
20
+ static const rb_data_type_t tracer_memfd_type = {
21
+ .wrap_struct_name = "Datadog::Core::ProcessDiscovery::TracerMemfd",
22
+ .function = {
23
+ .dfree = tracer_memfd_free,
24
+ .dsize = NULL,
25
+ },
26
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
27
+ };
28
+
29
+ void process_discovery_init(VALUE core_module) {
30
+ VALUE process_discovery_class = rb_define_class_under(core_module, "ProcessDiscovery", rb_cObject);
31
+ VALUE tracer_memfd_class = rb_define_class_under(process_discovery_class, "TracerMemfd", rb_cObject);
32
+ rb_undef_alloc_func(tracer_memfd_class); // Class cannot be instantiated from Ruby
33
+
34
+ rb_define_singleton_method(process_discovery_class, "_native_store_tracer_metadata", _native_store_tracer_metadata, -1);
35
+ rb_define_singleton_method(process_discovery_class, "_native_to_rb_int", _native_to_rb_int, 1);
36
+ rb_define_singleton_method(process_discovery_class, "_native_close_tracer_memfd", _native_close_tracer_memfd, 2);
37
+ }
38
+
39
+ // TODO: Remove DDTRACE_UNUSED and rename _self to self once we have updated libdatadog to 17.1
40
+ static VALUE _native_store_tracer_metadata(int argc, VALUE *argv, DDTRACE_UNUSED VALUE _self) {
41
+ VALUE logger;
42
+ VALUE options;
43
+ rb_scan_args(argc, argv, "1:", &logger, &options);
44
+ if (options == Qnil) options = rb_hash_new();
45
+
46
+ VALUE schema_version = rb_hash_fetch(options, ID2SYM(rb_intern("schema_version")));
47
+ VALUE runtime_id = rb_hash_fetch(options, ID2SYM(rb_intern("runtime_id")));
48
+ VALUE tracer_language = rb_hash_fetch(options, ID2SYM(rb_intern("tracer_language")));
49
+ VALUE tracer_version = rb_hash_fetch(options, ID2SYM(rb_intern("tracer_version")));
50
+ VALUE hostname = rb_hash_fetch(options, ID2SYM(rb_intern("hostname")));
51
+ VALUE service_name = rb_hash_fetch(options, ID2SYM(rb_intern("service_name")));
52
+ VALUE service_env = rb_hash_fetch(options, ID2SYM(rb_intern("service_env")));
53
+ VALUE service_version = rb_hash_fetch(options, ID2SYM(rb_intern("service_version")));
54
+
55
+ ENFORCE_TYPE(schema_version, T_FIXNUM);
56
+ ENFORCE_TYPE(runtime_id, T_STRING);
57
+ ENFORCE_TYPE(tracer_language, T_STRING);
58
+ ENFORCE_TYPE(tracer_version, T_STRING);
59
+ ENFORCE_TYPE(hostname, T_STRING);
60
+ ENFORCE_TYPE(service_name, T_STRING);
61
+ ENFORCE_TYPE(service_env, T_STRING);
62
+ ENFORCE_TYPE(service_version, T_STRING);
63
+
64
+ /*
65
+ ddog_Result_TracerMemfdHandle result = ddog_store_tracer_metadata(
66
+ (uint8_t) NUM2UINT(schema_version),
67
+ char_slice_from_ruby_string(runtime_id),
68
+ char_slice_from_ruby_string(tracer_language),
69
+ char_slice_from_ruby_string(tracer_version),
70
+ char_slice_from_ruby_string(hostname),
71
+ char_slice_from_ruby_string(service_name),
72
+ char_slice_from_ruby_string(service_env),
73
+ char_slice_from_ruby_string(service_version)
74
+ );
75
+
76
+ if (result.tag == DDOG_RESULT_TRACER_MEMFD_HANDLE_ERR_TRACER_MEMFD_HANDLE) {
77
+ rb_funcall(logger, rb_intern("debug"), 1, rb_sprintf("Failed to store the tracer configuration in a memory file descriptor: %"PRIsVALUE, get_error_details_and_drop(&result.err)));
78
+ return Qnil;
79
+ }
80
+
81
+ // &result.ok is a ddog_TracerMemfdHandle, which is a struct only containing int fd, which is a file descriptor
82
+ // We should just return the fd
83
+ int *fd = ruby_xmalloc(sizeof(int));
84
+
85
+ *fd = result.ok.fd;
86
+ VALUE tracer_memfd_class = rb_const_get(self, rb_intern("TracerMemfd"));
87
+ VALUE tracer_memfd = TypedData_Wrap_Struct(tracer_memfd_class, &tracer_memfd_type, fd);
88
+ return tracer_memfd;
89
+ */
90
+
91
+ rb_raise(rb_eNotImpError, "TODO: Not in use yet, waiting for libdatadog 17.1");
92
+ }
93
+
94
+ static VALUE _native_to_rb_int(DDTRACE_UNUSED VALUE _self, VALUE tracer_memfd) {
95
+ int *fd;
96
+ TypedData_Get_Struct(tracer_memfd, int, &tracer_memfd_type, fd);
97
+ return INT2NUM(*fd);
98
+ }
99
+
100
+ static VALUE _native_close_tracer_memfd(DDTRACE_UNUSED VALUE _self, VALUE tracer_memfd, VALUE logger) {
101
+ int *fd;
102
+ TypedData_Get_Struct(tracer_memfd, int, &tracer_memfd_type, fd);
103
+ if (*fd == -1) {
104
+ rb_funcall(logger, rb_intern("debug"), 1, rb_sprintf("The tracer configuration memory file descriptor has already been closed"));
105
+ return Qnil;
106
+ }
107
+
108
+ int close_result = close(*fd);
109
+ *fd = -1;
110
+
111
+ if (close_result == -1) {
112
+ rb_funcall(logger, rb_intern("debug"), 1, rb_sprintf("Failed to close the tracer configuration memory file descriptor: %s", strerror(errno)));
113
+ return Qnil;
114
+ }
115
+
116
+ return Qnil;
117
+ }
@@ -0,0 +1,5 @@
1
+ #pragma once
2
+
3
+ #include "datadog_ruby_common.h"
4
+
5
+ void process_discovery_init(VALUE core_module);
@@ -33,7 +33,7 @@ module Datadog
33
33
  event_category = Ext::EXPLOIT_PREVENTION_EVENT_CATEGORY
34
34
  tag_key = Ext::TAG_METASTRUCT_STACK_TRACE
35
35
 
36
- existing_stack_data = active_span.get_metastruct_tag(tag_key).dup || { event_category => [] }
36
+ existing_stack_data = active_span.get_metastruct_tag(tag_key).dup || {event_category => []}
37
37
  max_stack_traces = Datadog.configuration.appsec.stack_trace.max_stack_traces
38
38
  return if max_stack_traces != 0 && existing_stack_data[event_category].count >= max_stack_traces
39
39
 
@@ -42,7 +42,8 @@ module Datadog
42
42
  active_span.set_metastruct_tag(tag_key, existing_stack_data)
43
43
  end
44
44
 
45
- def generate_schema(_action_params); end
45
+ def generate_schema(_action_params)
46
+ end
46
47
  end
47
48
  end
48
49
  end