datadog 2.41.0 → 2.43.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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +57 -1
  3. data/README.md +3 -0
  4. data/ext/datadog_profiling_native_extension/NativeExtensionDesign.md +12 -24
  5. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +120 -61
  6. data/ext/datadog_profiling_native_extension/collectors_stack.c +11 -3
  7. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +156 -108
  8. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +7 -3
  9. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +0 -10
  10. data/ext/datadog_profiling_native_extension/extconf.rb +52 -93
  11. data/ext/datadog_profiling_native_extension/heap_recorder.c +351 -255
  12. data/ext/datadog_profiling_native_extension/heap_recorder.h +50 -31
  13. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +0 -24
  14. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +518 -442
  15. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +15 -3
  16. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  17. data/ext/datadog_profiling_native_extension/ruby_helpers.c +1 -79
  18. data/ext/datadog_profiling_native_extension/ruby_helpers.h +0 -7
  19. data/ext/datadog_profiling_native_extension/stack_recorder.c +106 -61
  20. data/ext/datadog_profiling_native_extension/stack_recorder.h +12 -4
  21. data/ext/datadog_profiling_native_extension/time_helpers.h +2 -1
  22. data/ext/libdatadog_api/datadog_ruby_common.h +0 -10
  23. data/ext/libdatadog_api/di.c +10 -0
  24. data/ext/libdatadog_api/extconf.rb +3 -0
  25. data/ext/libdatadog_api/init.c +2 -0
  26. data/ext/libdatadog_api/otel_thread_context.c +247 -0
  27. data/ext/libdatadog_api/otel_thread_context.h +5 -0
  28. data/ext/libdatadog_api/trace_exporter.c +642 -22
  29. data/ext/libdatadog_extconf_helpers.rb +1 -1
  30. data/lib/datadog/appsec/assets/blocked.html +1 -108
  31. data/lib/datadog/core/configuration/components.rb +1 -0
  32. data/lib/datadog/core/crashtracking/component.rb +5 -1
  33. data/lib/datadog/data_streams/pathway_context.rb +20 -22
  34. data/lib/datadog/data_streams/processor.rb +31 -0
  35. data/lib/datadog/di/instrumenter.rb +41 -1
  36. data/lib/datadog/di/logger.rb +2 -2
  37. data/lib/datadog/di/probe.rb +9 -1
  38. data/lib/datadog/di/probe_notification_builder.rb +1 -0
  39. data/lib/datadog/di/remote.rb +3 -3
  40. data/lib/datadog/open_feature/evaluation_engine.rb +29 -3
  41. data/lib/datadog/open_feature/exposures/event.rb +10 -3
  42. data/lib/datadog/open_feature/ext.rb +19 -0
  43. data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +236 -80
  44. data/lib/datadog/open_feature/flag_evaluation/writer.rb +179 -68
  45. data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +24 -21
  46. data/lib/datadog/open_feature/native_evaluator.rb +33 -6
  47. data/lib/datadog/open_feature/noop_evaluator.rb +5 -0
  48. data/lib/datadog/open_feature/provider.rb +11 -2
  49. data/lib/datadog/open_feature/transport.rb +5 -0
  50. data/lib/datadog/opentelemetry/sdk/propagator.rb +1 -1
  51. data/lib/datadog/opentelemetry/trace.rb +3 -0
  52. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +3 -0
  53. data/lib/datadog/profiling/collectors/info.rb +2 -6
  54. data/lib/datadog/profiling/collectors/thread_context.rb +0 -4
  55. data/lib/datadog/profiling/component.rb +8 -16
  56. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +1 -0
  57. data/lib/datadog/tracing/contrib/sequel/jdbc_connection_string.rb +140 -0
  58. data/lib/datadog/tracing/contrib/sequel/utils.rb +49 -62
  59. data/lib/datadog/tracing/distributed/baggage.rb +0 -1
  60. data/lib/datadog/tracing/distributed/datadog.rb +3 -3
  61. data/lib/datadog/tracing/distributed/propagation.rb +3 -0
  62. data/lib/datadog/tracing/distributed/trace_context.rb +14 -271
  63. data/lib/datadog/tracing/distributed/trace_state/datadog.rb +233 -0
  64. data/lib/datadog/tracing/distributed/trace_state/ext.rb +44 -0
  65. data/lib/datadog/tracing/distributed/trace_state/open_telemetry.rb +156 -0
  66. data/lib/datadog/tracing/distributed/trace_state.rb +121 -0
  67. data/lib/datadog/tracing/otel_thread_context.rb +34 -0
  68. data/lib/datadog/tracing/remote.rb +195 -27
  69. data/lib/datadog/tracing/sampling/rule_sampler.rb +2 -0
  70. data/lib/datadog/tracing/trace_digest.rb +22 -4
  71. data/lib/datadog/tracing/trace_operation.rb +22 -10
  72. data/lib/datadog/tracing/tracer.rb +5 -5
  73. data/lib/datadog/tracing/transport/native.rb +17 -25
  74. data/lib/datadog/tracing/transport/span_events_negotiation.rb +41 -0
  75. data/lib/datadog/tracing/transport/traces.rb +2 -22
  76. data/lib/datadog/version.rb +1 -1
  77. metadata +16 -8
  78. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +0 -69
@@ -6,15 +6,19 @@
6
6
 
7
7
  #include "gvl_profiling_helper.h"
8
8
 
9
- void thread_context_collector_sample(
9
+ // Returns true if `thread_context_collector_resolve_otel_span_key_may_lose_gvl` needs to be called (which the caller
10
+ // must only do once the sample is over)
11
+ __attribute__((warn_unused_result)) bool thread_context_collector_sample(
10
12
  VALUE self_instance,
11
13
  long current_monotonic_wall_time_ns
12
14
  );
13
15
  __attribute__((warn_unused_result)) bool thread_context_collector_prepare_sample_inside_signal_handler(void);
14
16
  __attribute__((warn_unused_result)) bool thread_context_collector_sample_allocation(VALUE self_instance, per_thread_context *thread_context, unsigned int sample_weight, VALUE new_object);
15
- void thread_context_collector_after_allocation(VALUE self_instance);
17
+ void thread_context_collector_commit_heap_recordings_may_lose_gvl(VALUE self_instance);
16
18
  void thread_context_collector_sample_skipped_allocation_samples(VALUE self_instance, unsigned int skipped_samples);
17
19
  VALUE thread_context_collector_sample_after_gc(VALUE self_instance);
20
+ VALUE thread_context_collector_heap_update_may_lose_gvl(VALUE self_instance);
21
+ void thread_context_collector_resolve_otel_span_key_may_lose_gvl(VALUE self_instance);
18
22
  void thread_context_collector_on_gc_start(VALUE self_instance);
19
23
  __attribute__((warn_unused_result)) bool thread_context_collector_on_gc_finish(VALUE self_instance);
20
24
  VALUE enforce_thread_context_collector_instance(VALUE object);
@@ -38,7 +42,7 @@ void thread_context_collector_profiler_internal_thread_done(VALUE self_instance)
38
42
  } on_gvl_running_result;
39
43
 
40
44
  void thread_context_collector_on_gvl_waiting(per_thread_context *thread_context);
41
- __attribute__((warn_unused_result)) on_gvl_running_result thread_context_collector_on_gvl_running(VALUE self_instance, VALUE thread, per_thread_context *thread_context);
45
+ __attribute__((warn_unused_result)) on_gvl_running_result thread_context_collector_on_gvl_running(VALUE thread, per_thread_context *thread_context, uint32_t waiting_for_gvl_threshold_ns);
42
46
  VALUE thread_context_collector_sample_after_gvl_running(VALUE self_instance, VALUE current_thread, long current_monotonic_wall_time_ns);
43
47
  void thread_context_collector_on_gvl_released(per_thread_context *thread_context);
44
48
  #endif
@@ -97,13 +97,3 @@ static inline VALUE get_error_details_and_drop(ddog_Error *error) {
97
97
  // Returns the amount of characters written to string (which are necessarily
98
98
  // bounded by capacity - 1 since the string will be null-terminated).
99
99
  size_t read_ddogerr_string_and_drop(ddog_Error *error, char *string, size_t capacity);
100
-
101
- #define IMEMO_MASK 0x0f
102
-
103
- // Returns the imemo type of an imemo object.
104
- // This mask is the same between Ruby 2.5 and 3.3-preview3. Furthermore, the intention of this method is to be used
105
- // to call `rb_imemo_name` which correctly handles invalid numbers so even if the mask changes in the future, at most
106
- // we'll get incorrect results (and never a VM crash)
107
- static inline int ddtrace_imemo_type(VALUE imemo) {
108
- return (RBASIC(imemo)->flags >> FL_USHIFT) & IMEMO_MASK;
109
- }
@@ -96,7 +96,7 @@ append_cflags "-Wno-error=typedef-redefinition" if ENV["DATADOG_GEM_CI"] == "tru
96
96
  # @ivoanjo: We could probably start using C11/gnu11 for non macOS-too but it's somewhat hard to validate so I chickened out for now
97
97
  append_cflags RUBY_PLATFORM.include?("darwin") ? "-std=gnu11" : "-std=gnu99"
98
98
 
99
- # Gets really noisy when we include the MJIT header, let's omit it (TODO: Use #pragma GCC diagnostic instead?)
99
+ # Gets really noisy when we include the private VM headers, let's omit it (TODO: Use #pragma GCC diagnostic instead?)
100
100
  append_cflags "-Wno-unused-function"
101
101
 
102
102
  # Allow defining variables at any point in a function
@@ -142,19 +142,6 @@ have_func "malloc_stats"
142
142
  # On older Rubies, there was no primitive mutex and condition variable implemented in `thread_sync.rb` (internal)
143
143
  $defs << "-DNO_PRIMITIVE_MUTEX_AND_CONDITION_VARIABLE" if RUBY_VERSION < "4"
144
144
 
145
- # On Ruby 4, we can't ask the object_id from IMEMOs (https://github.com/ruby/ruby/pull/13347)
146
- $defs << "-DNO_IMEMO_OBJECT_ID" unless RUBY_VERSION < "4"
147
-
148
- # On Ruby 4, we need to defer calling rb_obj_id during heap allocation recording
149
- # because it's not safe to mutate objects during the newobj tracepoint
150
- # (see https://bugs.ruby-lang.org/issues/21710)
151
- $defs << "-DUSE_DEFERRED_HEAP_ALLOCATION_RECORDING" unless RUBY_VERSION < "4"
152
-
153
- # On Ruby 4.0, we've seen crashes when computing the memsize of a class/module/iclass:
154
- # rb_obj_memsize_of walks the per-namespace class extensions (classext_memsize), which seem to sometimes be in an inconsistent state
155
- # (see https://github.com/DataDog/dd-trace-rb/issues/5936)
156
- $defs << "-DNO_SAFE_CLASS_MEMSIZE" unless RUBY_VERSION < "4"
157
-
158
145
  # This symbol is exclusively visible on certain Ruby versions: 2.6 to 3.2, as well as 3.4 (but not 4.0+)
159
146
  # It's only used to get extra information about an object when a failure happens, so it's a "very nice to have" but not
160
147
  # actually required for correct behavior of the profiler.
@@ -166,8 +153,8 @@ $defs << "-DNO_POSTPONED_TRIGGER" if RUBY_VERSION < "3.3"
166
153
  # On older Rubies, M:N threads were not available
167
154
  $defs << "-DNO_MN_THREADS_AVAILABLE" if RUBY_VERSION < "3.3"
168
155
 
169
- # On older Rubies, we did not need to include the ractor header (this was built into the MJIT header)
170
- $defs << "-DNO_RACTOR_HEADER_INCLUDE" if RUBY_VERSION < "3.3"
156
+ # On Rubies before 3.0, there were no Ractors, so there's no need to include the ractor header at all
157
+ $defs << "-DNO_RACTOR_HEADER_INCLUDE" if RUBY_VERSION < "3"
171
158
 
172
159
  # On older Rubies, some of the Ractor internal APIs were directly accessible
173
160
  $defs << "-DUSE_RACTOR_INTERNAL_APIS_DIRECTLY" if RUBY_VERSION < "3.3"
@@ -246,85 +233,57 @@ end
246
233
  # When requiring, we need to use the exact same string, including the version and the platform.
247
234
  EXTENSION_NAME = "datadog_profiling_native_extension.#{RUBY_VERSION}_#{RUBY_PLATFORM}".freeze
248
235
 
249
- if Datadog::Profiling::NativeExtensionHelpers::CAN_USE_MJIT_HEADER
250
- mjit_header_file_name = "rb_mjit_min_header-#{RUBY_VERSION}.h"
251
-
252
- # Validate that the mjit header can actually be compiled on this system. We learned via
253
- # https://github.com/DataDog/dd-trace-rb/issues/1799 and https://github.com/DataDog/dd-trace-rb/issues/1792
254
- # that even if the header seems to exist, it may not even compile.
255
- # `have_macro` actually tries to compile a file that mentions the given macro, so if this passes, we should be good to
256
- # use the MJIT header.
257
- # Finally, the `COMMON_HEADERS` conflict with the MJIT header so we need to temporarily disable them for this check.
258
- original_common_headers = MakeMakefile::COMMON_HEADERS
259
- MakeMakefile::COMMON_HEADERS = "".freeze
260
- unless have_macro("RUBY_MJIT_H", mjit_header_file_name)
261
- skip_building_extension!(Datadog::Profiling::NativeExtensionHelpers::Supported::COMPILATION_BROKEN)
262
- end
263
- MakeMakefile::COMMON_HEADERS = original_common_headers
264
-
265
- $defs << "-DRUBY_MJIT_HEADER='\"#{mjit_header_file_name}\"'"
266
-
267
- # NOTE: This needs to come after all changes to $defs
268
- create_header
269
-
270
- # Warn on unused parameters to functions. Use `DDTRACE_UNUSED` to mark things as known-to-not-be-used.
271
- # See the comment on the same flag below for why this is done last.
272
- append_cflags "-Wunused-parameter"
273
-
274
- create_makefile EXTENSION_NAME
275
- else
276
- # The MJIT header was introduced on 2.6 and removed on 3.3; for other Rubies we rely on
277
- # the datadog-ruby_core_source gem to get access to private VM headers.
278
- # This gem ships source code copies of these VM headers for the different Ruby VM versions;
279
- # see https://github.com/DataDog/datadog-ruby_core_source for details
280
-
281
- create_header
282
-
283
- require "datadog/ruby_core_source"
284
- dir_config("ruby") # allow user to pass in non-standard core include directory
285
-
286
- # This is a workaround for a weird issue...
287
- #
288
- # The mkmf tool defines a `with_cppflags` helper that datadog-ruby_core_source uses. This helper temporarily
289
- # replaces `$CPPFLAGS` (aka the C pre-processor [not c++!] flags) with a different set when doing something.
290
- #
291
- # The datadog-ruby_core_source gem uses `with_cppflags` during makefile generation to inject extra headers into the
292
- # path. But because `with_cppflags` replaces `$CPPFLAGS`, well, the default `$CPPFLAGS` are not included in the
293
- # makefile.
294
- #
295
- # This is a problem because the default `$CPPFLAGS` carries configuration that was set when Ruby was being built.
296
- # Thus, if we ignore it, we don't compile the profiler with the exact same configuration as Ruby.
297
- # In practice, this can generate crashes and weird bugs if the Ruby configuration is tweaked in a manner that
298
- # changes some of the internal structures that the profiler relies on. Concretely, setting for instance
299
- # `VM_CHECK_MODE=1` when building Ruby will trigger this issue (because somethings in structures the profiler reads
300
- # are ifdef'd out using this setting).
301
- #
302
- # To workaround this issue, we override `with_cppflags` for datadog-ruby_core_source to still include `$CPPFLAGS`.
303
- Datadog::RubyCoreSource.define_singleton_method(:with_cppflags) do |newflags, &block|
304
- super("#{newflags} #{$CPPFLAGS}", &block)
305
- end
236
+ # We rely on the datadog-ruby_core_source gem to get access to private VM headers.
237
+ # This gem ships source code copies of these VM headers for the different Ruby VM versions;
238
+ # see https://github.com/DataDog/datadog-ruby_core_source for details
306
239
 
307
- Datadog::RubyCoreSource
308
- .create_makefile_with_core(
309
- proc do
310
- headers_available =
311
- have_header("vm_core.h") &&
312
- have_header("iseq.h") &&
313
- (RUBY_VERSION < "3.3" || have_header("ractor_core.h"))
314
-
315
- if headers_available
316
- # Warn on unused parameters to functions. Use `DDTRACE_UNUSED` to mark things as known-to-not-be-used.
317
- # This is added as late as possible because in some Rubies we support (e.g. 3.3), adding this flag before
318
- # checking if internal VM headers are available causes those checks to fail because of this warning (and not
319
- # because the headers are not available.)
320
- append_cflags "-Wunused-parameter"
321
- end
322
-
323
- headers_available
324
- end,
325
- EXTENSION_NAME,
326
- )
240
+ create_header
241
+
242
+ require "datadog/ruby_core_source"
243
+ dir_config("ruby") # allow user to pass in non-standard core include directory
244
+
245
+ # This is a workaround for a weird issue...
246
+ #
247
+ # The mkmf tool defines a `with_cppflags` helper that datadog-ruby_core_source uses. This helper temporarily
248
+ # replaces `$CPPFLAGS` (aka the C pre-processor [not c++!] flags) with a different set when doing something.
249
+ #
250
+ # The datadog-ruby_core_source gem uses `with_cppflags` during makefile generation to inject extra headers into the
251
+ # path. But because `with_cppflags` replaces `$CPPFLAGS`, well, the default `$CPPFLAGS` are not included in the
252
+ # makefile.
253
+ #
254
+ # This is a problem because the default `$CPPFLAGS` carries configuration that was set when Ruby was being built.
255
+ # Thus, if we ignore it, we don't compile the profiler with the exact same configuration as Ruby.
256
+ # In practice, this can generate crashes and weird bugs if the Ruby configuration is tweaked in a manner that
257
+ # changes some of the internal structures that the profiler relies on. Concretely, setting for instance
258
+ # `VM_CHECK_MODE=1` when building Ruby will trigger this issue (because somethings in structures the profiler reads
259
+ # are ifdef'd out using this setting).
260
+ #
261
+ # To workaround this issue, we override `with_cppflags` for datadog-ruby_core_source to still include `$CPPFLAGS`.
262
+ Datadog::RubyCoreSource.define_singleton_method(:with_cppflags) do |newflags, &block|
263
+ super("#{newflags} #{$CPPFLAGS}", &block)
327
264
  end
328
265
 
266
+ Datadog::RubyCoreSource
267
+ .create_makefile_with_core(
268
+ proc do
269
+ headers_available =
270
+ have_header("vm_core.h") &&
271
+ have_header("iseq.h", "vm_core.h") &&
272
+ # These are only used on Ruby 3+
273
+ (RUBY_VERSION < "3" || have_header("ractor_core.h") && have_header("internal/class.h"))
274
+
275
+ if headers_available
276
+ # Warn on unused parameters to functions. Use `DDTRACE_UNUSED` to mark things as known-to-not-be-used.
277
+ # This is added as late as possible because in some Rubies we support (e.g. 3.3), adding this flag before
278
+ # checking if internal VM headers are available causes those checks to fail because of this warning (and not
279
+ # because the headers are not available.)
280
+ append_cflags "-Wunused-parameter"
281
+ end
282
+
283
+ headers_available
284
+ end,
285
+ EXTENSION_NAME,
286
+ )
287
+
329
288
  # rubocop:enable Style/GlobalVars
330
289
  # rubocop:enable Style/StderrPuts