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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -1
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +38 -23
- data/ext/ddtrace_profiling_native_extension/collectors_discrete_dynamic_sampler.c +349 -0
- data/ext/ddtrace_profiling_native_extension/collectors_discrete_dynamic_sampler.h +89 -0
- data/ext/ddtrace_profiling_native_extension/extconf.rb +3 -0
- data/ext/ddtrace_profiling_native_extension/helpers.h +4 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +16 -0
- data/ext/ddtrace_profiling_native_extension/time_helpers.h +2 -0
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +2 -1
- data/lib/datadog/core/configuration/settings.rb +22 -7
- data/lib/datadog/core/environment/class_count.rb +6 -6
- data/lib/datadog/core/remote/component.rb +25 -12
- data/lib/datadog/core/remote/ext.rb +1 -0
- data/lib/datadog/core/remote/tie/tracing.rb +39 -0
- data/lib/datadog/core/remote/tie.rb +27 -0
- data/lib/datadog/opentelemetry/sdk/propagator.rb +3 -2
- data/lib/datadog/opentelemetry.rb +3 -0
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +0 -2
- data/lib/datadog/profiling/component.rb +3 -17
- data/lib/datadog/tracing/configuration/ext.rb +0 -1
- data/lib/datadog/tracing/configuration/settings.rb +2 -1
- data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/action_cable/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/action_mailer/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/action_pack/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/action_view/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/active_job/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/active_record/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/active_support/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/analytics.rb +0 -1
- data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/aws/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/delayed_job/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +7 -0
- data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +1 -1
- data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/grape/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +2 -2
- data/lib/datadog/tracing/contrib/http/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/httpclient/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/httprb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/kafka/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/pg/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/presto/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/qless/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/que/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/que/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/racecar/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/rack/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +9 -2
- data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/rails/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/rake/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/redis/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/redis/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/redis/patcher.rb +34 -21
- data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/resque/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/roda/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/sequel/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/shoryuken/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/sinatra/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/sneakers/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/stripe/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +58 -0
- data/lib/datadog/tracing/contrib/trilogy/ext.rb +27 -0
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +94 -0
- data/lib/datadog/tracing/contrib/trilogy/integration.rb +43 -0
- data/lib/datadog/tracing/contrib/trilogy/patcher.rb +31 -0
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing.rb +8 -2
- data/lib/ddtrace/version.rb +1 -1
- 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
|
+
}
|
|
@@ -26,7 +26,8 @@ module Datadog
|
|
|
26
26
|
def call(env)
|
|
27
27
|
return @app.call(env) unless Datadog::AppSec.enabled?
|
|
28
28
|
|
|
29
|
-
|
|
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
|
-
#
|
|
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.
|
|
378
|
-
|
|
379
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
def value
|
|
8
|
+
def self.value
|
|
11
9
|
::ObjectSpace.count_objects[:T_CLASS]
|
|
12
10
|
end
|
|
13
11
|
|
|
14
|
-
def available?
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
#
|
|
116
|
-
|
|
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
|
|
@@ -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
|
-
|
|
32
|
+
if getter != ::OpenTelemetry::Context::Propagation.text_map_getter &&
|
|
33
|
+
getter != ::OpenTelemetry::Common::Propagation.rack_env_getter
|
|
33
34
|
Datadog.logger.error(
|
|
34
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
@@ -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
|
-
#
|
|
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
|
|
@@ -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'
|
|
@@ -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'
|
|
@@ -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'
|
|
@@ -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'
|
|
@@ -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
|
|