ddtrace 1.19.0 → 1.20.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 (125) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -1
  3. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +38 -23
  4. data/ext/ddtrace_profiling_native_extension/collectors_discrete_dynamic_sampler.c +349 -0
  5. data/ext/ddtrace_profiling_native_extension/collectors_discrete_dynamic_sampler.h +89 -0
  6. data/ext/ddtrace_profiling_native_extension/extconf.rb +3 -0
  7. data/ext/ddtrace_profiling_native_extension/helpers.h +4 -0
  8. data/ext/ddtrace_profiling_native_extension/profiling.c +16 -0
  9. data/ext/ddtrace_profiling_native_extension/time_helpers.h +2 -0
  10. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +2 -1
  11. data/lib/datadog/core/configuration/settings.rb +22 -7
  12. data/lib/datadog/core/environment/class_count.rb +6 -6
  13. data/lib/datadog/core/remote/component.rb +25 -12
  14. data/lib/datadog/core/remote/ext.rb +1 -0
  15. data/lib/datadog/core/remote/tie/tracing.rb +39 -0
  16. data/lib/datadog/core/remote/tie.rb +27 -0
  17. data/lib/datadog/opentelemetry/sdk/propagator.rb +3 -2
  18. data/lib/datadog/opentelemetry.rb +3 -0
  19. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +0 -2
  20. data/lib/datadog/profiling/component.rb +3 -17
  21. data/lib/datadog/tracing/configuration/ext.rb +0 -1
  22. data/lib/datadog/tracing/configuration/settings.rb +2 -1
  23. data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +1 -0
  24. data/lib/datadog/tracing/contrib/action_cable/ext.rb +1 -0
  25. data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +1 -0
  26. data/lib/datadog/tracing/contrib/action_mailer/ext.rb +1 -0
  27. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +1 -0
  28. data/lib/datadog/tracing/contrib/action_pack/ext.rb +1 -0
  29. data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +1 -0
  30. data/lib/datadog/tracing/contrib/action_view/ext.rb +1 -0
  31. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +1 -0
  32. data/lib/datadog/tracing/contrib/active_job/ext.rb +1 -0
  33. data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +1 -0
  34. data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +1 -0
  35. data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +1 -0
  36. data/lib/datadog/tracing/contrib/active_record/ext.rb +1 -0
  37. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +1 -0
  38. data/lib/datadog/tracing/contrib/active_support/ext.rb +1 -0
  39. data/lib/datadog/tracing/contrib/analytics.rb +0 -1
  40. data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +1 -0
  41. data/lib/datadog/tracing/contrib/aws/ext.rb +1 -0
  42. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +1 -0
  43. data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
  44. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +1 -0
  45. data/lib/datadog/tracing/contrib/delayed_job/ext.rb +1 -0
  46. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +1 -0
  47. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +1 -0
  48. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +1 -0
  49. data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
  50. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +1 -0
  51. data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
  52. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +7 -0
  53. data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
  54. data/lib/datadog/tracing/contrib/faraday/middleware.rb +1 -1
  55. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +1 -0
  56. data/lib/datadog/tracing/contrib/grape/ext.rb +1 -0
  57. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +1 -0
  58. data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
  59. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +1 -0
  60. data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
  61. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +1 -0
  62. data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +2 -2
  63. data/lib/datadog/tracing/contrib/http/ext.rb +1 -0
  64. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +1 -0
  65. data/lib/datadog/tracing/contrib/httpclient/ext.rb +1 -0
  66. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +1 -0
  67. data/lib/datadog/tracing/contrib/httprb/ext.rb +1 -0
  68. data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +1 -0
  69. data/lib/datadog/tracing/contrib/kafka/ext.rb +1 -0
  70. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +1 -0
  71. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  72. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +1 -0
  73. data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
  74. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +1 -0
  75. data/lib/datadog/tracing/contrib/opensearch/ext.rb +1 -0
  76. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +1 -0
  77. data/lib/datadog/tracing/contrib/pg/ext.rb +1 -0
  78. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +1 -0
  79. data/lib/datadog/tracing/contrib/presto/ext.rb +1 -0
  80. data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +1 -0
  81. data/lib/datadog/tracing/contrib/qless/ext.rb +1 -0
  82. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +1 -0
  83. data/lib/datadog/tracing/contrib/que/ext.rb +1 -0
  84. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +1 -0
  85. data/lib/datadog/tracing/contrib/racecar/ext.rb +1 -0
  86. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +1 -0
  87. data/lib/datadog/tracing/contrib/rack/ext.rb +1 -0
  88. data/lib/datadog/tracing/contrib/rack/middlewares.rb +9 -2
  89. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +1 -0
  90. data/lib/datadog/tracing/contrib/rails/ext.rb +1 -0
  91. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +1 -0
  92. data/lib/datadog/tracing/contrib/rake/ext.rb +1 -0
  93. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +1 -0
  94. data/lib/datadog/tracing/contrib/redis/ext.rb +1 -0
  95. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +2 -2
  96. data/lib/datadog/tracing/contrib/redis/patcher.rb +34 -21
  97. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +1 -0
  98. data/lib/datadog/tracing/contrib/resque/ext.rb +1 -0
  99. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +1 -0
  100. data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -0
  101. data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +1 -0
  102. data/lib/datadog/tracing/contrib/roda/ext.rb +1 -0
  103. data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +1 -0
  104. data/lib/datadog/tracing/contrib/sequel/ext.rb +1 -0
  105. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +1 -0
  106. data/lib/datadog/tracing/contrib/shoryuken/ext.rb +1 -0
  107. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +1 -0
  108. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
  109. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +1 -0
  110. data/lib/datadog/tracing/contrib/sinatra/ext.rb +1 -0
  111. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +1 -0
  112. data/lib/datadog/tracing/contrib/sneakers/ext.rb +1 -0
  113. data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +1 -0
  114. data/lib/datadog/tracing/contrib/stripe/ext.rb +1 -0
  115. data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +1 -0
  116. data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +1 -0
  117. data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +58 -0
  118. data/lib/datadog/tracing/contrib/trilogy/ext.rb +27 -0
  119. data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +94 -0
  120. data/lib/datadog/tracing/contrib/trilogy/integration.rb +43 -0
  121. data/lib/datadog/tracing/contrib/trilogy/patcher.rb +31 -0
  122. data/lib/datadog/tracing/contrib.rb +1 -0
  123. data/lib/datadog/tracing.rb +8 -2
  124. data/lib/ddtrace/version.rb +1 -1
  125. metadata +14 -5
@@ -0,0 +1,89 @@
1
+ #pragma once
2
+
3
+ #include <stdbool.h>
4
+ #include <stddef.h>
5
+
6
+ // A sampler that will sample discrete events based on the overhead of their
7
+ // sampling.
8
+ //
9
+ // NOTE: For performance reasons, this sampler does systematic sampling via
10
+ // sampling intervals/skips that are dynamically adjusted over time.
11
+ // It will not perform truly random sampling by "throwing a coin" at
12
+ // every event and is thus, in theory, susceptible to some pattern
13
+ // biases. In practice, the dynamic readjustment of sampling interval
14
+ // and randomized starting point should help with avoiding heavy biases.
15
+ typedef struct discrete_dynamic_sampler {
16
+ // --- Config ---
17
+ // Name of this sampler for debug logs.
18
+ const char *debug_name;
19
+ // Value in the range ]0, 100] representing the % of time we're willing to dedicate
20
+ // to sampling.
21
+ double target_overhead;
22
+
23
+ // -- Reference State ---
24
+ // Moving average of how many events per ns we saw over the recent past.
25
+ double events_per_ns;
26
+ // Moving average of the sampling time of each individual event.
27
+ long sampling_time_ns;
28
+ // Sampling probability being applied by this sampler.
29
+ double sampling_probability;
30
+ // Sampling interval/skip that drives the systematic sampling done by this sampler.
31
+ // NOTE: This is an inverted view of the probability.
32
+ // NOTE: A value of 0 works as +inf, effectively disabling sampling (to align with probability=0)
33
+ unsigned long sampling_interval;
34
+
35
+ // -- Sampling State --
36
+ // How many events have we seen since we last decided to sample.
37
+ unsigned long events_since_last_sample;
38
+ // Captures the time at which the last true-returning call to should_sample happened.
39
+ // This is used in after_sample to understand the total sample time.
40
+ long sample_start_time_ns;
41
+
42
+ // -- Adjustment State --
43
+ // Has this sampler already ran for at least one complete adjustment window?
44
+ bool has_completed_full_adjustment_window;
45
+ // Time at which we last readjust our sampling parameters.
46
+ long last_readjust_time_ns;
47
+ // How many events have we seen since the last readjustment.
48
+ unsigned long events_since_last_readjustment;
49
+ // How many samples have we seen since the last readjustment.
50
+ unsigned long samples_since_last_readjustment;
51
+ // How much time have we spent sampling since the last readjustment.
52
+ unsigned long sampling_time_since_last_readjustment_ns;
53
+ // A negative number that we add to target_overhead to serve as extra padding to
54
+ // try and mitigate observed overshooting of max sampling time.
55
+ double target_overhead_adjustment;
56
+ } discrete_dynamic_sampler;
57
+
58
+
59
+ // Init a new sampler with sane defaults.
60
+ void discrete_dynamic_sampler_init(discrete_dynamic_sampler *sampler, const char *debug_name);
61
+
62
+ // Reset a sampler, clearing all stored state.
63
+ void discrete_dynamic_sampler_reset(discrete_dynamic_sampler *sampler);
64
+
65
+ // Sets a new target_overhead for the provided sampler, resetting it in the process.
66
+ // @param target_overhead A double representing the percentage of total time we are
67
+ // willing to use as overhead for the resulting sampling. Values are expected
68
+ // to be in the range ]0.0, 100.0].
69
+ void discrete_dynamic_sampler_set_overhead_target_percentage(discrete_dynamic_sampler *sampler, double target_overhead);
70
+
71
+ // Make a sampling decision.
72
+ //
73
+ // @return True if the event associated with this decision should be sampled, false
74
+ // otherwise.
75
+ //
76
+ // NOTE: If true is returned we implicitly assume the start of a sampling operation
77
+ // and it is expected that a follow-up after_sample call is issued.
78
+ bool discrete_dynamic_sampler_should_sample(discrete_dynamic_sampler *sampler);
79
+
80
+ // Signal the end of a sampling operation.
81
+ //
82
+ // @return Sampling time in nanoseconds for the sample operation we just finished.
83
+ long discrete_dynamic_sampler_after_sample(discrete_dynamic_sampler *sampler);
84
+
85
+ // Retrieve the current sampling probability ([0.0, 100.0]) being applied by this sampler.
86
+ double discrete_dynamic_sampler_probability(discrete_dynamic_sampler *sampler);
87
+
88
+ // Retrieve the current number of events seen since last sample.
89
+ unsigned long discrete_dynamic_sampler_events_since_last_sample(discrete_dynamic_sampler *sampler);
@@ -115,6 +115,7 @@ add_compiler_flag '-Wall'
115
115
  add_compiler_flag '-Wextra'
116
116
 
117
117
  if ENV['DDTRACE_DEBUG']
118
+ $defs << '-DDD_DEBUG'
118
119
  CONFIG['optflags'] = '-O0'
119
120
  CONFIG['debugflags'] = '-ggdb3'
120
121
  end
@@ -130,6 +131,8 @@ if RUBY_PLATFORM.include?('linux')
130
131
  $defs << '-DHAVE_PTHREAD_GETCPUCLOCKID'
131
132
  end
132
133
 
134
+ have_func 'malloc_stats'
135
+
133
136
  # On older Rubies, rb_postponed_job_preregister/rb_postponed_job_trigger did not exist
134
137
  $defs << '-DNO_POSTPONED_TRIGGER' if RUBY_VERSION < '3.3'
135
138
 
@@ -1,5 +1,7 @@
1
1
  #pragma once
2
2
 
3
+ #include <stdint.h>
4
+
3
5
  // Used to mark symbols to be exported to the outside of the extension.
4
6
  // Consider very carefully before tagging a function with this.
5
7
  #define DDTRACE_EXPORT __attribute__ ((visibility ("default")))
@@ -17,3 +19,5 @@ inline static uint64_t uint64_max_of(uint64_t a, uint64_t b) { return a > b ? a
17
19
  inline static uint64_t uint64_min_of(uint64_t a, uint64_t b) { return a > b ? b : a; }
18
20
  inline static long long_max_of(long a, long b) { return a > b ? a : b; }
19
21
  inline static long long_min_of(long a, long b) { return a > b ? b : a; }
22
+ inline static double double_max_of(double a, double b) { return a > b ? a : b; }
23
+ inline static double double_min_of(double a, double b) { return a > b ? b : a; }
@@ -1,6 +1,9 @@
1
1
  #include <ruby.h>
2
2
  #include <ruby/thread.h>
3
3
  #include <errno.h>
4
+ #ifdef HAVE_MALLOC_STATS
5
+ #include <malloc.h>
6
+ #endif
4
7
 
5
8
  #include "clock_id.h"
6
9
  #include "helpers.h"
@@ -11,6 +14,7 @@
11
14
 
12
15
  // Each class/module here is implemented in their separate file
13
16
  void collectors_cpu_and_wall_time_worker_init(VALUE profiling_module);
17
+ void collectors_discrete_dynamic_sampler_init(VALUE profiling_module);
14
18
  void collectors_dynamic_sampling_rate_init(VALUE profiling_module);
15
19
  void collectors_idle_sampling_helper_init(VALUE profiling_module);
16
20
  void collectors_stack_init(VALUE profiling_module);
@@ -32,6 +36,7 @@ static void holding_the_gvl_signal_handler(DDTRACE_UNUSED int _signal, DDTRACE_U
32
36
  static VALUE _native_trigger_holding_the_gvl_signal_handler_on(DDTRACE_UNUSED VALUE _self, VALUE background_thread);
33
37
  static VALUE _native_enforce_success(DDTRACE_UNUSED VALUE _self, VALUE syserr_errno, VALUE with_gvl);
34
38
  static void *trigger_enforce_success(void *trigger_args);
39
+ static VALUE _native_malloc_stats(DDTRACE_UNUSED VALUE _self);
35
40
 
36
41
  void DDTRACE_EXPORT Init_ddtrace_profiling_native_extension(void) {
37
42
  VALUE datadog_module = rb_define_module("Datadog");
@@ -43,6 +48,7 @@ void DDTRACE_EXPORT Init_ddtrace_profiling_native_extension(void) {
43
48
 
44
49
  ruby_helpers_init();
45
50
  collectors_cpu_and_wall_time_worker_init(profiling_module);
51
+ collectors_discrete_dynamic_sampler_init(profiling_module);
46
52
  collectors_dynamic_sampling_rate_init(profiling_module);
47
53
  collectors_idle_sampling_helper_init(profiling_module);
48
54
  collectors_stack_init(profiling_module);
@@ -65,6 +71,7 @@ void DDTRACE_EXPORT Init_ddtrace_profiling_native_extension(void) {
65
71
  rb_define_singleton_method(testing_module, "_native_install_holding_the_gvl_signal_handler", _native_install_holding_the_gvl_signal_handler, 0);
66
72
  rb_define_singleton_method(testing_module, "_native_trigger_holding_the_gvl_signal_handler_on", _native_trigger_holding_the_gvl_signal_handler_on, 1);
67
73
  rb_define_singleton_method(testing_module, "_native_enforce_success", _native_enforce_success, 2);
74
+ rb_define_singleton_method(testing_module, "_native_malloc_stats", _native_malloc_stats, 0);
68
75
  }
69
76
 
70
77
  static VALUE native_working_p(DDTRACE_UNUSED VALUE _self) {
@@ -249,3 +256,12 @@ static void *trigger_enforce_success(void *trigger_args) {
249
256
  ENFORCE_SUCCESS_NO_GVL(syserr_errno);
250
257
  return NULL;
251
258
  }
259
+
260
+ static VALUE _native_malloc_stats(DDTRACE_UNUSED VALUE _self) {
261
+ #ifdef HAVE_MALLOC_STATS
262
+ malloc_stats();
263
+ return Qtrue;
264
+ #else
265
+ return Qfalse;
266
+ #endif
267
+ }
@@ -1,5 +1,7 @@
1
1
  #pragma once
2
2
 
3
+ #include <stdbool.h>
4
+
3
5
  #define SECONDS_AS_NS(value) (value * 1000 * 1000 * 1000L)
4
6
  #define MILLIS_AS_NS(value) (value * 1000 * 1000L)
5
7
 
@@ -26,7 +26,8 @@ module Datadog
26
26
  def call(env)
27
27
  return @app.call(env) unless Datadog::AppSec.enabled?
28
28
 
29
- Datadog::Core::Remote.active_remote.barrier(:once) unless Datadog::Core::Remote.active_remote.nil?
29
+ boot = Datadog::Core::Remote::Tie.boot
30
+ Datadog::Core::Remote::Tie::Tracing.tag(boot, active_span)
30
31
 
31
32
  processor = nil
32
33
  ready = false
@@ -369,14 +369,16 @@ module Datadog
369
369
 
370
370
  # Can be used to configure the allocation sampling rate: a sample will be collected every x allocations.
371
371
  #
372
- # The lower the value, the more accuracy in allocation and heap tracking but the bigger the overhead. In
373
- # particular, a value of 1 will sample ALL allocations.
374
- #
375
- # @default `DD_PROFILING_EXPERIMENTAL_ALLOCATION_SAMPLE_RATE` environment variable, otherwise `50`.
372
+ # This feature is now controlled via {:overhead_target_percentage}
376
373
  option :experimental_allocation_sample_rate do |o|
377
- o.type :int
378
- o.env 'DD_PROFILING_EXPERIMENTAL_ALLOCATION_SAMPLE_RATE'
379
- o.default 50
374
+ o.after_set do
375
+ Datadog.logger.warn(
376
+ 'The profiling.advanced.experimental_allocation_sample_rate setting has been deprecated for removal ' \
377
+ 'and no longer does anything. Please remove it from your Datadog.configure block. ' \
378
+ 'Allocation sample rate is now handled by a dynamic sampler which will adjust the sampling rate to ' \
379
+ 'keep to the configured `profiling.advanced.overhead_target_percentage`.'
380
+ )
381
+ end
380
382
  end
381
383
 
382
384
  # Can be used to configure the heap sampling rate: a heap sample will be collected for every x allocation
@@ -747,6 +749,19 @@ module Datadog
747
749
  o.default 5.0
748
750
  end
749
751
 
752
+ # Tune remote configuration boot timeout.
753
+ # Early operations such as requests are blocked until RC is ready. In
754
+ # order to not block the application indefinitely a timeout is
755
+ # enforced allowing requests to proceed with the local configuration.
756
+ #
757
+ # @default `DD_REMOTE_CONFIG_BOOT_TIMEOUT` environment variable, otherwise `1.0` seconds.
758
+ # @return [Float]
759
+ option :boot_timeout_seconds do |o|
760
+ o.env Core::Remote::Ext::ENV_BOOT_TIMEOUT_SECONDS
761
+ o.type :float
762
+ o.default 1.0
763
+ end
764
+
750
765
  # Declare service name to bind to remote configuration. Use when
751
766
  # DD_SERVICE does not match the correct integration for which remote
752
767
  # configuration applies.
@@ -5,15 +5,15 @@ module Datadog
5
5
  module Environment
6
6
  # Retrieves number of classes from runtime
7
7
  module ClassCount
8
- module_function
9
-
10
- def value
8
+ def self.value
11
9
  ::ObjectSpace.count_objects[:T_CLASS]
12
10
  end
13
11
 
14
- def available?
15
- ::ObjectSpace.respond_to?(:count_objects) \
16
- && ::ObjectSpace.count_objects.key?(:T_CLASS)
12
+ def self.available?
13
+ return @class_count_available if defined?(@class_count_available)
14
+
15
+ @class_count_available =
16
+ ::ObjectSpace.respond_to?(:count_objects) && ::ObjectSpace.count_objects.key?(:T_CLASS)
17
17
  end
18
18
  end
19
19
  end
@@ -13,9 +13,7 @@ module Datadog
13
13
  # Configures the HTTP transport to communicate with the agent
14
14
  # to fetch and sync the remote configuration
15
15
  class Component
16
- BARRIER_TIMEOUT = 1.0 # second
17
-
18
- attr_reader :client
16
+ attr_reader :client, :healthy
19
17
 
20
18
  def initialize(settings, capabilities, agent_settings)
21
19
  transport_options = {}
@@ -24,14 +22,14 @@ module Datadog
24
22
  negotiation = Negotiation.new(settings, agent_settings)
25
23
  transport_v7 = Datadog::Core::Remote::Transport::HTTP.v7(**transport_options.dup)
26
24
 
27
- @barrier = Barrier.new(BARRIER_TIMEOUT)
25
+ @barrier = Barrier.new(settings.remote.boot_timeout_seconds)
28
26
 
29
27
  @client = Client.new(transport_v7, capabilities)
30
- healthy = false
28
+ @healthy = false
31
29
  Datadog.logger.debug { "new remote configuration client: #{@client.id}" }
32
30
 
33
31
  @worker = Worker.new(interval: settings.remote.poll_interval_seconds) do
34
- unless healthy || negotiation.endpoint?('/v0.7/config')
32
+ unless @healthy || negotiation.endpoint?('/v0.7/config')
35
33
  @barrier.lift
36
34
 
37
35
  next
@@ -39,7 +37,7 @@ module Datadog
39
37
 
40
38
  begin
41
39
  @client.sync
42
- healthy ||= true
40
+ @healthy ||= true
43
41
  rescue Client::SyncError => e
44
42
  Datadog.logger.error do
45
43
  "remote worker client sync error: #{e.message} location: #{Array(e.backtrace).first}. skipping sync"
@@ -57,7 +55,7 @@ module Datadog
57
55
 
58
56
  # client state is unknown, state might be corrupted
59
57
  @client = Client.new(transport_v7, capabilities)
60
- healthy = false
58
+ @healthy = false
61
59
  Datadog.logger.debug { "new remote configuration client: #{@client.id}" }
62
60
 
63
61
  # TODO: bail out if too many errors?
@@ -103,17 +101,32 @@ module Datadog
103
101
  def wait_once(timeout = nil)
104
102
  # TTAS (Test and Test-And-Set) optimisation
105
103
  # Since @once only ever goes from false to true, this is semantically valid
106
- return if @once
104
+ return :pass if @once
107
105
 
108
106
  begin
109
107
  @mutex.lock
110
108
 
111
- return if @once
109
+ return :pass if @once
112
110
 
113
111
  timeout ||= @timeout
114
112
 
115
- # rbs/core has a bug, timeout type is incorrectly ?Integer
116
- @condition.wait(@mutex, _ = timeout)
113
+ # - starting with Ruby 3.2, ConditionVariable#wait returns nil on
114
+ # timeout and an integer otherwise
115
+ # - before Ruby 3.2, ConditionVariable returns itself
116
+ # so we have to rely on @once having been set
117
+ if RUBY_VERSION >= '3.2'
118
+ lifted = @condition.wait(@mutex, timeout)
119
+ else
120
+ @condition.wait(@mutex, timeout)
121
+ lifted = @once
122
+ end
123
+
124
+ if lifted
125
+ :lift
126
+ else
127
+ @once = true
128
+ :timeout
129
+ end
117
130
  ensure
118
131
  @mutex.unlock
119
132
  end
@@ -6,6 +6,7 @@ module Datadog
6
6
  module Ext
7
7
  ENV_ENABLED = 'DD_REMOTE_CONFIGURATION_ENABLED'
8
8
  ENV_POLL_INTERVAL_SECONDS = 'DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS'
9
+ ENV_BOOT_TIMEOUT_SECONDS = 'DD_REMOTE_CONFIG_BOOT_TIMEOUT_SECONDS'
9
10
  end
10
11
  end
11
12
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../tie'
4
+
5
+ module Datadog
6
+ module Core
7
+ module Remote
8
+ module Tie
9
+ # Extend Remote Configuration abilities with Tracing
10
+ module Tracing
11
+ # Tag per-request Remote Configuration metadata using Tracing
12
+ def self.tag(boot, span)
13
+ return if boot.nil?
14
+ return if span.nil?
15
+
16
+ return if Datadog::Core::Remote.active_remote.nil?
17
+
18
+ # TODO: this is not thread-consistent
19
+ ready = Datadog::Core::Remote.active_remote.healthy
20
+ status = ready ? 'ready' : 'disconnected'
21
+
22
+ span.set_tag('_dd.rc.client_id', Datadog::Core::Remote.active_remote.client.id)
23
+ span.set_tag('_dd.rc.status', status)
24
+
25
+ if boot.barrier != :pass
26
+ span.set_tag('_dd.rc.boot.time', boot.time)
27
+
28
+ if boot.barrier == :timeout
29
+ span.set_tag('_dd.rc.boot.timeout', true)
30
+ else
31
+ span.set_tag('_dd.rc.boot.ready', ready)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Core
5
+ module Remote
6
+ # Provide Remote Configuration extensions to other components
7
+ module Tie
8
+ Boot = Struct.new(
9
+ :barrier,
10
+ :time,
11
+ )
12
+
13
+ def self.boot
14
+ return if Datadog::Core::Remote.active_remote.nil?
15
+
16
+ barrier = nil
17
+
18
+ t = Datadog::Core::Utils::Time.measure do
19
+ barrier = Datadog::Core::Remote.active_remote.barrier(:once)
20
+ end
21
+
22
+ Boot.new(barrier, t)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -29,9 +29,10 @@ module Datadog
29
29
  carrier, context: ::OpenTelemetry::Context.current,
30
30
  getter: ::OpenTelemetry::Context::Propagation.text_map_getter
31
31
  )
32
- unless getter == ::OpenTelemetry::Context::Propagation.text_map_getter
32
+ if getter != ::OpenTelemetry::Context::Propagation.text_map_getter &&
33
+ getter != ::OpenTelemetry::Common::Propagation.rack_env_getter
33
34
  Datadog.logger.error(
34
- 'Custom getter is not supported. Please inform the `ddtrace` team at ' \
35
+ "Custom getter #{getter} is not supported. Please inform the `ddtrace` team at " \
35
36
  ' https://github.com/DataDog/dd-trace-rb of your use case so we can best support you. Using the default ' \
36
37
  'OpenTelemetry::Context::Propagation.text_map_getter as a fallback getter.'
37
38
  )
@@ -8,7 +8,10 @@
8
8
  # This file activates the integrations of all OpenTelemetry
9
9
  # components supported by Datadog.
10
10
 
11
+ # Load Tracing
11
12
  require_relative 'tracing'
13
+ require_relative 'tracing/contrib'
14
+
12
15
  require_relative 'opentelemetry/api/context'
13
16
 
14
17
  # DEV: Should this be a Contrib integration, that depends on the `opentelemetry-sdk`
@@ -18,7 +18,6 @@ module Datadog
18
18
  no_signals_workaround_enabled:,
19
19
  thread_context_collector:,
20
20
  dynamic_sampling_rate_overhead_target_percentage:,
21
- allocation_sample_every:,
22
21
  allocation_profiling_enabled:,
23
22
  # **NOTE**: This should only be used for testing; disabling the dynamic sampling rate will increase the
24
23
  # profiler overhead!
@@ -39,7 +38,6 @@ module Datadog
39
38
  no_signals_workaround_enabled,
40
39
  dynamic_sampling_rate_enabled,
41
40
  dynamic_sampling_rate_overhead_target_percentage,
42
- allocation_sample_every,
43
41
  allocation_profiling_enabled,
44
42
  )
45
43
  @worker_thread = nil
@@ -41,8 +41,7 @@ module Datadog
41
41
 
42
42
  no_signals_workaround_enabled = no_signals_workaround_enabled?(settings)
43
43
  timeline_enabled = settings.profiling.advanced.experimental_timeline_enabled
44
- allocation_sample_every = get_allocation_sample_every(settings)
45
- allocation_profiling_enabled = enable_allocation_profiling?(settings, allocation_sample_every)
44
+ allocation_profiling_enabled = enable_allocation_profiling?(settings)
46
45
  heap_sample_every = get_heap_sample_every(settings)
47
46
  heap_profiling_enabled = enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_every)
48
47
  heap_size_profiling_enabled = enable_heap_size_profiling?(settings, heap_profiling_enabled)
@@ -64,14 +63,12 @@ module Datadog
64
63
  no_signals_workaround_enabled: no_signals_workaround_enabled,
65
64
  thread_context_collector: thread_context_collector,
66
65
  dynamic_sampling_rate_overhead_target_percentage: overhead_target_percentage,
67
- allocation_sample_every: allocation_sample_every,
68
66
  allocation_profiling_enabled: allocation_profiling_enabled,
69
67
  )
70
68
 
71
69
  internal_metadata = {
72
70
  no_signals_workaround_enabled: no_signals_workaround_enabled,
73
71
  timeline_enabled: timeline_enabled,
74
- allocation_sample_every: allocation_sample_every,
75
72
  heap_sample_every: heap_sample_every,
76
73
  }.freeze
77
74
 
@@ -129,16 +126,6 @@ module Datadog
129
126
  end
130
127
  end
131
128
 
132
- private_class_method def self.get_allocation_sample_every(settings)
133
- allocation_sample_rate = settings.profiling.advanced.experimental_allocation_sample_rate
134
-
135
- if allocation_sample_rate <= 0
136
- raise ArgumentError, "Allocation sample rate must be a positive integer. Was #{allocation_sample_rate}"
137
- end
138
-
139
- allocation_sample_rate
140
- end
141
-
142
129
  private_class_method def self.get_heap_sample_every(settings)
143
130
  heap_sample_rate = settings.profiling.advanced.experimental_heap_sample_rate
144
131
 
@@ -147,7 +134,7 @@ module Datadog
147
134
  heap_sample_rate
148
135
  end
149
136
 
150
- private_class_method def self.enable_allocation_profiling?(settings, allocation_sample_every)
137
+ private_class_method def self.enable_allocation_profiling?(settings)
151
138
  unless settings.profiling.advanced.experimental_allocation_enabled
152
139
  # Allocation profiling disabled, short-circuit out
153
140
  return false
@@ -193,8 +180,7 @@ module Datadog
193
180
  end
194
181
 
195
182
  Datadog.logger.warn(
196
- "Enabled experimental allocation profiling: allocation_sample_rate=#{allocation_sample_every}. This is " \
197
- 'experimental, not recommended, and will increase overhead!'
183
+ 'Enabled experimental allocation profiling. This is experimental, not recommended, and will increase overhead!'
198
184
  )
199
185
 
200
186
  true
@@ -18,7 +18,6 @@ module Datadog
18
18
  ENV_PEER_SERVICE_MAPPING = 'DD_TRACE_PEER_SERVICE_MAPPING'
19
19
  end
20
20
 
21
- # @public_api
22
21
  module Analytics
23
22
  ENV_TRACE_ANALYTICS_ENABLED = 'DD_TRACE_ANALYTICS_ENABLED'
24
23
  end
@@ -23,10 +23,11 @@ module Datadog
23
23
  # @configure_with {Datadog::Tracing}
24
24
  # @deprecated Use [Trace Retention and Ingestion](https://docs.datadoghq.com/tracing/trace_retention_and_ingestion/)
25
25
  # controls.
26
- # @public_api
26
+ # @!visibility private
27
27
  settings :analytics do
28
28
  # @default `DD_TRACE_ANALYTICS_ENABLED` environment variable, otherwise `nil`
29
29
  # @return [Boolean,nil]
30
+ # @!visibility private
30
31
  option :enabled do |o|
31
32
  o.type :bool, nilable: true
32
33
  o.env Tracing::Configuration::Ext::Analytics::ENV_TRACE_ANALYTICS_ENABLED
@@ -17,6 +17,7 @@ module Datadog
17
17
  o.default true
18
18
  end
19
19
 
20
+ # @!visibility private
20
21
  option :analytics_enabled do |o|
21
22
  o.type :bool
22
23
  o.env Ext::ENV_ANALYTICS_ENABLED
@@ -8,6 +8,7 @@ module Datadog
8
8
  # @public_api Changing resource names, tag names, or environment variables creates breaking changes.
9
9
  module Ext
10
10
  ENV_ENABLED = 'DD_TRACE_ACTION_CABLE_ENABLED'
11
+ # @!visibility private
11
12
  ENV_ANALYTICS_ENABLED = 'DD_TRACE_ACTION_CABLE_ANALYTICS_ENABLED'
12
13
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_ACTION_CABLE_ANALYTICS_SAMPLE_RATE'
13
14
  SPAN_ACTION = 'action_cable.action'
@@ -17,6 +17,7 @@ module Datadog
17
17
  o.default true
18
18
  end
19
19
 
20
+ # @!visibility private
20
21
  option :analytics_enabled do |o|
21
22
  o.type :bool
22
23
  o.env Ext::ENV_ANALYTICS_ENABLED
@@ -8,6 +8,7 @@ module Datadog
8
8
  # @public_api Changing resource names, tag names, or environment variables creates breaking changes.
9
9
  module Ext
10
10
  ENV_ENABLED = 'DD_TRACE_ACTION_MAILER_ENABLED'
11
+ # @!visibility private
11
12
  ENV_ANALYTICS_ENABLED = 'DD_TRACE_ACTION_MAILER_ANALYTICS_ENABLED'
12
13
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_ACTION_MAILER_ANALYTICS_SAMPLE_RATE'
13
14
  SPAN_PROCESS = 'action_mailer.process'
@@ -17,6 +17,7 @@ module Datadog
17
17
  o.default true
18
18
  end
19
19
 
20
+ # @!visibility private
20
21
  option :analytics_enabled do |o|
21
22
  o.type :bool, nilable: true
22
23
  o.env Ext::ENV_ANALYTICS_ENABLED
@@ -8,6 +8,7 @@ module Datadog
8
8
  # @public_api Changing resource names, tag names, or environment variables creates breaking changes.
9
9
  module Ext
10
10
  ENV_ENABLED = 'DD_TRACE_ACTION_PACK_ENABLED'
11
+ # @!visibility private
11
12
  ENV_ANALYTICS_ENABLED = 'DD_TRACE_ACTION_PACK_ANALYTICS_ENABLED'
12
13
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_ACTION_PACK_ANALYTICS_SAMPLE_RATE'
13
14
  SPAN_ACTION_CONTROLLER = 'rails.action_controller'
@@ -15,6 +15,7 @@ module Datadog
15
15
  o.default true
16
16
  end
17
17
 
18
+ # @!visibility private
18
19
  option :analytics_enabled do |o|
19
20
  o.type :bool
20
21
  o.env Ext::ENV_ANALYTICS_ENABLED
@@ -8,6 +8,7 @@ module Datadog
8
8
  # @public_api Changing resource names, tag names, or environment variables creates breaking changes.
9
9
  module Ext
10
10
  ENV_ENABLED = 'DD_TRACE_ACTION_VIEW_ENABLED'
11
+ # @!visibility private
11
12
  ENV_ANALYTICS_ENABLED = 'DD_TRACE_ACTION_VIEW_ANALYTICS_ENABLED'
12
13
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_ACTION_VIEW_ANALYTICS_SAMPLE_RATE'
13
14
  SPAN_RENDER_PARTIAL = 'rails.render_partial'
@@ -18,6 +18,7 @@ module Datadog
18
18
  o.default true
19
19
  end
20
20
 
21
+ # @!visibility private
21
22
  option :analytics_enabled do |o|
22
23
  o.type :bool
23
24
  o.env Ext::ENV_ANALYTICS_ENABLED
@@ -7,6 +7,7 @@ module Datadog
7
7
  # @public_api Changing resource names, tag names, or environment variables creates breaking changes.
8
8
  module Ext
9
9
  ENV_ENABLED = 'DD_TRACE_ACTIVE_JOB_ENABLED'
10
+ # @!visibility private
10
11
  ENV_ANALYTICS_ENABLED = 'DD_TRACE_ACTIVE_JOB_ANALYTICS_ENABLED'
11
12
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_ACTIVE_JOB_ANALYTICS_SAMPLE_RATE'
12
13
 
@@ -17,6 +17,7 @@ module Datadog
17
17
  o.default true
18
18
  end
19
19
 
20
+ # @!visibility private
20
21
  option :analytics_enabled do |o|
21
22
  o.type :bool
22
23
  o.env Ext::ENV_ANALYTICS_ENABLED