ddtrace 1.18.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 +82 -1
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +96 -66
- 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/collectors_dynamic_sampling_rate.c +22 -14
- data/ext/ddtrace_profiling_native_extension/collectors_dynamic_sampling_rate.h +4 -0
- data/ext/ddtrace_profiling_native_extension/collectors_gc_profiling_helper.c +156 -0
- data/ext/ddtrace_profiling_native_extension/collectors_gc_profiling_helper.h +5 -0
- data/ext/ddtrace_profiling_native_extension/collectors_stack.c +43 -102
- data/ext/ddtrace_profiling_native_extension/collectors_stack.h +10 -3
- data/ext/ddtrace_profiling_native_extension/collectors_thread_context.c +159 -124
- data/ext/ddtrace_profiling_native_extension/collectors_thread_context.h +2 -1
- data/ext/ddtrace_profiling_native_extension/extconf.rb +19 -0
- data/ext/ddtrace_profiling_native_extension/heap_recorder.c +970 -0
- data/ext/ddtrace_profiling_native_extension/heap_recorder.h +155 -0
- data/ext/ddtrace_profiling_native_extension/helpers.h +6 -0
- data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.c +20 -0
- data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +11 -0
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +5 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +17 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +147 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +28 -0
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +329 -10
- data/ext/ddtrace_profiling_native_extension/stack_recorder.h +3 -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 +153 -21
- 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/core/telemetry/collector.rb +10 -0
- data/lib/datadog/core/telemetry/event.rb +2 -1
- data/lib/datadog/core/telemetry/ext.rb +3 -0
- data/lib/datadog/core/telemetry/v1/app_event.rb +8 -1
- data/lib/datadog/core/telemetry/v1/install_signature.rb +38 -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 +5 -12
- data/lib/datadog/profiling/component.rb +183 -13
- data/lib/datadog/profiling/scheduler.rb +4 -6
- data/lib/datadog/profiling/stack_recorder.rb +13 -2
- 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 +5 -0
- data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +2 -1
- 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/auto_instrument_railtie.rb +0 -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 +20 -6
|
@@ -7,7 +7,7 @@ module Datadog
|
|
|
7
7
|
# Passing in a `nil` tracer is supported and will disable the following profiling features:
|
|
8
8
|
# * Code Hotspots panel in the trace viewer, as well as scoping a profile down to a span
|
|
9
9
|
# * Endpoint aggregation in the profiler UX, including normalization (resource per endpoint call)
|
|
10
|
-
def self.build_profiler_component(settings:, agent_settings:, optional_tracer:)
|
|
10
|
+
def self.build_profiler_component(settings:, agent_settings:, optional_tracer:) # rubocop:disable Metrics/MethodLength
|
|
11
11
|
require_relative '../profiling/diagnostics/environment_logger'
|
|
12
12
|
|
|
13
13
|
Profiling::Diagnostics::EnvironmentLogger.collect_and_log!
|
|
@@ -41,38 +41,54 @@ 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_profiling_enabled = enable_allocation_profiling?(settings)
|
|
45
|
+
heap_sample_every = get_heap_sample_every(settings)
|
|
46
|
+
heap_profiling_enabled = enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_every)
|
|
47
|
+
heap_size_profiling_enabled = enable_heap_size_profiling?(settings, heap_profiling_enabled)
|
|
48
|
+
|
|
49
|
+
overhead_target_percentage = valid_overhead_target(settings.profiling.advanced.overhead_target_percentage)
|
|
50
|
+
upload_period_seconds = [60, settings.profiling.advanced.upload_period_seconds].max
|
|
44
51
|
|
|
45
52
|
recorder = Datadog::Profiling::StackRecorder.new(
|
|
46
53
|
cpu_time_enabled: RUBY_PLATFORM.include?('linux'), # Only supported on Linux currently
|
|
47
|
-
alloc_samples_enabled:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
max_frames: settings.profiling.advanced.max_frames,
|
|
52
|
-
tracer: optional_tracer,
|
|
53
|
-
endpoint_collection_enabled: settings.profiling.advanced.endpoint.collection.enabled,
|
|
54
|
+
alloc_samples_enabled: allocation_profiling_enabled,
|
|
55
|
+
heap_samples_enabled: heap_profiling_enabled,
|
|
56
|
+
heap_size_enabled: heap_size_profiling_enabled,
|
|
57
|
+
heap_sample_every: heap_sample_every,
|
|
54
58
|
timeline_enabled: timeline_enabled,
|
|
55
59
|
)
|
|
60
|
+
thread_context_collector = build_thread_context_collector(settings, recorder, optional_tracer, timeline_enabled)
|
|
56
61
|
worker = Datadog::Profiling::Collectors::CpuAndWallTimeWorker.new(
|
|
57
62
|
gc_profiling_enabled: enable_gc_profiling?(settings),
|
|
58
|
-
allocation_counting_enabled: settings.profiling.advanced.allocation_counting_enabled,
|
|
59
63
|
no_signals_workaround_enabled: no_signals_workaround_enabled,
|
|
60
64
|
thread_context_collector: thread_context_collector,
|
|
61
|
-
|
|
65
|
+
dynamic_sampling_rate_overhead_target_percentage: overhead_target_percentage,
|
|
66
|
+
allocation_profiling_enabled: allocation_profiling_enabled,
|
|
62
67
|
)
|
|
63
68
|
|
|
64
69
|
internal_metadata = {
|
|
65
70
|
no_signals_workaround_enabled: no_signals_workaround_enabled,
|
|
66
71
|
timeline_enabled: timeline_enabled,
|
|
72
|
+
heap_sample_every: heap_sample_every,
|
|
67
73
|
}.freeze
|
|
68
74
|
|
|
69
75
|
exporter = build_profiler_exporter(settings, recorder, internal_metadata: internal_metadata)
|
|
70
76
|
transport = build_profiler_transport(settings, agent_settings)
|
|
71
|
-
scheduler = Profiling::Scheduler.new(exporter: exporter, transport: transport)
|
|
77
|
+
scheduler = Profiling::Scheduler.new(exporter: exporter, transport: transport, interval: upload_period_seconds)
|
|
72
78
|
|
|
73
79
|
Profiling::Profiler.new(worker: worker, scheduler: scheduler)
|
|
74
80
|
end
|
|
75
81
|
|
|
82
|
+
private_class_method def self.build_thread_context_collector(settings, recorder, optional_tracer, timeline_enabled)
|
|
83
|
+
Datadog::Profiling::Collectors::ThreadContext.new(
|
|
84
|
+
recorder: recorder,
|
|
85
|
+
max_frames: settings.profiling.advanced.max_frames,
|
|
86
|
+
tracer: optional_tracer,
|
|
87
|
+
endpoint_collection_enabled: settings.profiling.advanced.endpoint.collection.enabled,
|
|
88
|
+
timeline_enabled: timeline_enabled,
|
|
89
|
+
)
|
|
90
|
+
end
|
|
91
|
+
|
|
76
92
|
private_class_method def self.build_profiler_exporter(settings, recorder, internal_metadata:)
|
|
77
93
|
code_provenance_collector =
|
|
78
94
|
(Profiling::Collectors::CodeProvenance.new if settings.profiling.advanced.code_provenance_enabled)
|
|
@@ -110,6 +126,115 @@ module Datadog
|
|
|
110
126
|
end
|
|
111
127
|
end
|
|
112
128
|
|
|
129
|
+
private_class_method def self.get_heap_sample_every(settings)
|
|
130
|
+
heap_sample_rate = settings.profiling.advanced.experimental_heap_sample_rate
|
|
131
|
+
|
|
132
|
+
raise ArgumentError, "Heap sample rate must be a positive integer. Was #{heap_sample_rate}" if heap_sample_rate <= 0
|
|
133
|
+
|
|
134
|
+
heap_sample_rate
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
private_class_method def self.enable_allocation_profiling?(settings)
|
|
138
|
+
unless settings.profiling.advanced.experimental_allocation_enabled
|
|
139
|
+
# Allocation profiling disabled, short-circuit out
|
|
140
|
+
return false
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Allocation sampling is safe and supported on Ruby 2.x, but has a few caveats on Ruby 3.x.
|
|
144
|
+
|
|
145
|
+
# SEVERE - All configurations
|
|
146
|
+
# Ruby 3.2.0 to 3.2.2 have a bug in the newobj tracepoint (https://bugs.ruby-lang.org/issues/19482,
|
|
147
|
+
# https://github.com/ruby/ruby/pull/7464) that makes this crash in any configuration. This bug is
|
|
148
|
+
# fixed on Ruby versions 3.2.3 and 3.3.0.
|
|
149
|
+
if RUBY_VERSION.start_with?('3.2.') && RUBY_VERSION < '3.2.3'
|
|
150
|
+
Datadog.logger.warn(
|
|
151
|
+
'Allocation profiling is not supported in Ruby versions 3.2.0, 3.2.1 and 3.2.2 and will be forcibly '\
|
|
152
|
+
'disabled. This is due to a VM bug that can lead to crashes (https://bugs.ruby-lang.org/issues/19482). '\
|
|
153
|
+
'Other Ruby versions do not suffer from this issue.'
|
|
154
|
+
)
|
|
155
|
+
return false
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# SEVERE - Only with Ractors
|
|
159
|
+
# On Ruby versions 3.0 (all), 3.1.0 to 3.1.3, and 3.2.0 to 3.2.2 allocation profiling can trigger a VM bug
|
|
160
|
+
# that causes a segmentation fault during garbage collection of Ractors
|
|
161
|
+
# (https://bugs.ruby-lang.org/issues/18464). We don't recommend using this feature on such Rubies.
|
|
162
|
+
# This bug is fixed on Ruby versions 3.1.4, 3.2.3 and 3.3.0.
|
|
163
|
+
if RUBY_VERSION.start_with?('3.0.') ||
|
|
164
|
+
(RUBY_VERSION.start_with?('3.1.') && RUBY_VERSION < '3.1.4') ||
|
|
165
|
+
(RUBY_VERSION.start_with?('3.2.') && RUBY_VERSION < '3.2.3')
|
|
166
|
+
Datadog.logger.warn(
|
|
167
|
+
"Current Ruby version (#{RUBY_VERSION}) has a VM bug where enabling allocation profiling while using "\
|
|
168
|
+
'Ractors may cause unexpected issues, including crashes (https://bugs.ruby-lang.org/issues/18464). '\
|
|
169
|
+
'This does not happen if Ractors are not used.'
|
|
170
|
+
)
|
|
171
|
+
# ANNOYANCE - Only with Ractors
|
|
172
|
+
# On all known versions of Ruby 3.x, due to https://bugs.ruby-lang.org/issues/19112, when a ractor gets
|
|
173
|
+
# garbage collected, Ruby will disable all active tracepoints, which this feature internally relies on.
|
|
174
|
+
elsif RUBY_VERSION.start_with?('3.')
|
|
175
|
+
Datadog.logger.warn(
|
|
176
|
+
'In all known versions of Ruby 3.x, using Ractors may result in allocation profiling unexpectedly ' \
|
|
177
|
+
'stopping (https://bugs.ruby-lang.org/issues/19112). Note that this stop has no impact in your ' \
|
|
178
|
+
'application stability or performance. This does not happen if Ractors are not used.'
|
|
179
|
+
)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
Datadog.logger.warn(
|
|
183
|
+
'Enabled experimental allocation profiling. This is experimental, not recommended, and will increase overhead!'
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
true
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
private_class_method def self.enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_rate)
|
|
190
|
+
heap_profiling_enabled = settings.profiling.advanced.experimental_heap_enabled
|
|
191
|
+
|
|
192
|
+
return false unless heap_profiling_enabled
|
|
193
|
+
|
|
194
|
+
if RUBY_VERSION.start_with?('2.') && RUBY_VERSION < '2.7'
|
|
195
|
+
Datadog.logger.warn(
|
|
196
|
+
'Heap profiling currently relies on features introduced in Ruby 2.7 and will be forcibly disabled. '\
|
|
197
|
+
'Please upgrade to Ruby >= 2.7 in order to use this feature.'
|
|
198
|
+
)
|
|
199
|
+
return false
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
if RUBY_VERSION < '3.1'
|
|
203
|
+
Datadog.logger.debug(
|
|
204
|
+
"Current Ruby version (#{RUBY_VERSION}) supports forced object recycling which has a bug that the " \
|
|
205
|
+
'heap profiler is forced to work around to remain accurate. This workaround requires force-setting '\
|
|
206
|
+
"the SEEN_OBJ_ID flag on objects that should have it but don't. Full details can be found in " \
|
|
207
|
+
'https://github.com/DataDog/dd-trace-rb/pull/3360. This workaround should be safe but can be ' \
|
|
208
|
+
'bypassed by disabling the heap profiler or upgrading to Ruby >= 3.1 where forced object recycling ' \
|
|
209
|
+
'was completely removed (https://bugs.ruby-lang.org/issues/18290).'
|
|
210
|
+
)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
unless allocation_profiling_enabled
|
|
214
|
+
raise ArgumentError,
|
|
215
|
+
'Heap profiling requires allocation profiling to be enabled'
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
Datadog.logger.warn(
|
|
219
|
+
"Enabled experimental heap profiling: heap_sample_rate=#{heap_sample_rate}. This is experimental, not " \
|
|
220
|
+
'recommended, and will increase overhead!'
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
true
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
private_class_method def self.enable_heap_size_profiling?(settings, heap_profiling_enabled)
|
|
227
|
+
heap_size_profiling_enabled = settings.profiling.advanced.experimental_heap_size_enabled
|
|
228
|
+
|
|
229
|
+
return false unless heap_profiling_enabled && heap_size_profiling_enabled
|
|
230
|
+
|
|
231
|
+
Datadog.logger.warn(
|
|
232
|
+
'Enabled experimental heap size profiling. This is experimental, not recommended, and will increase overhead!'
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
true
|
|
236
|
+
end
|
|
237
|
+
|
|
113
238
|
private_class_method def self.no_signals_workaround_enabled?(settings) # rubocop:disable Metrics/MethodLength
|
|
114
239
|
setting_value = settings.profiling.advanced.no_signals_workaround_enabled
|
|
115
240
|
legacy_ruby_that_should_use_workaround = RUBY_VERSION.start_with?('2.3.', '2.4.', '2.5.')
|
|
@@ -217,9 +342,12 @@ module Datadog
|
|
|
217
342
|
|
|
218
343
|
return true unless mysql2_client_class && mysql2_client_class.respond_to?(:info)
|
|
219
344
|
|
|
220
|
-
|
|
345
|
+
info = mysql2_client_class.info
|
|
346
|
+
libmysqlclient_version = Gem::Version.new(info[:version])
|
|
221
347
|
|
|
222
|
-
compatible =
|
|
348
|
+
compatible =
|
|
349
|
+
libmysqlclient_version >= Gem::Version.new('8.0.0') ||
|
|
350
|
+
looks_like_mariadb?(info, libmysqlclient_version)
|
|
223
351
|
|
|
224
352
|
Datadog.logger.debug(
|
|
225
353
|
"The `mysql2` gem is using #{compatible ? 'a compatible' : 'an incompatible'} version of " \
|
|
@@ -245,6 +373,48 @@ module Datadog
|
|
|
245
373
|
true
|
|
246
374
|
end
|
|
247
375
|
end
|
|
376
|
+
|
|
377
|
+
private_class_method def self.valid_overhead_target(overhead_target_percentage)
|
|
378
|
+
if overhead_target_percentage > 0 && overhead_target_percentage <= 20
|
|
379
|
+
overhead_target_percentage
|
|
380
|
+
else
|
|
381
|
+
Datadog.logger.error(
|
|
382
|
+
'Ignoring invalid value for profiling overhead_target_percentage setting: ' \
|
|
383
|
+
"#{overhead_target_percentage.inspect}. Falling back to default value."
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
2.0
|
|
387
|
+
end
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
# To add just a bit more complexity to our detection code, in https://github.com/DataDog/dd-trace-rb/issues/3334
|
|
391
|
+
# a user reported that our code was incorrectly flagging the mariadb variant of libmysqlclient as being
|
|
392
|
+
# incompatible. In fact we have no reports of the mariadb variant needing the "no signals" workaround,
|
|
393
|
+
# so we flag it as compatible when it's in use.
|
|
394
|
+
#
|
|
395
|
+
# A problem is that there doesn't seem to be an obvious way to query the mysql2 gem on which kind of
|
|
396
|
+
# libmysqlclient it's using, so we detect it by looking at the version.
|
|
397
|
+
#
|
|
398
|
+
# The info method for mysql2 with mariadb looks something like this:
|
|
399
|
+
# `{:id=>30308, :version=>"3.3.8", :header_version=>"11.2.2"}`
|
|
400
|
+
#
|
|
401
|
+
# * The version seems to come from https://github.com/mariadb-corporation/mariadb-connector-c and the latest
|
|
402
|
+
# one is 3.x.
|
|
403
|
+
# * The header_version is what people usually see as the "mariadb version"
|
|
404
|
+
#
|
|
405
|
+
# As a comparison, for libmysql the info looks like:
|
|
406
|
+
# * `{:id=>80035, :version=>"8.0.35", :header_version=>"8.0.35"}`
|
|
407
|
+
#
|
|
408
|
+
# Thus our detection is version 4 or older, because libmysqlclient 4 is almost 20 years old so it's most probably
|
|
409
|
+
# not that one + header_version being 10 or newer, since according to https://endoflife.date/mariadb that's a
|
|
410
|
+
# sane range for modern mariadb releases.
|
|
411
|
+
private_class_method def self.looks_like_mariadb?(info, libmysqlclient_version)
|
|
412
|
+
header_version = Gem::Version.new(info[:header_version]) if info[:header_version]
|
|
413
|
+
|
|
414
|
+
!!(header_version &&
|
|
415
|
+
libmysqlclient_version < Gem::Version.new('5.0.0') &&
|
|
416
|
+
header_version >= Gem::Version.new('10.0.0'))
|
|
417
|
+
end
|
|
248
418
|
end
|
|
249
419
|
end
|
|
250
420
|
end
|
|
@@ -5,12 +5,11 @@ require_relative '../core/workers/polling'
|
|
|
5
5
|
|
|
6
6
|
module Datadog
|
|
7
7
|
module Profiling
|
|
8
|
-
# Periodically (every
|
|
8
|
+
# Periodically (every interval, 60 seconds by default) takes a profile from the `Exporter` and reports it using the
|
|
9
9
|
# configured transport. Runs on its own background thread.
|
|
10
10
|
class Scheduler < Core::Worker
|
|
11
11
|
include Core::Workers::Polling
|
|
12
12
|
|
|
13
|
-
DEFAULT_INTERVAL_SECONDS = 60
|
|
14
13
|
MINIMUM_INTERVAL_SECONDS = 0
|
|
15
14
|
|
|
16
15
|
# We sleep for at most this duration seconds before reporting data to avoid multi-process applications all
|
|
@@ -28,8 +27,7 @@ module Datadog
|
|
|
28
27
|
def initialize(
|
|
29
28
|
exporter:,
|
|
30
29
|
transport:,
|
|
31
|
-
fork_policy: Core::Workers::Async::Thread::FORK_POLICY_RESTART, # Restart in forks by default
|
|
32
|
-
interval: DEFAULT_INTERVAL_SECONDS,
|
|
30
|
+
interval:, fork_policy: Core::Workers::Async::Thread::FORK_POLICY_RESTART, # Restart in forks by default, # seconds
|
|
33
31
|
enabled: true
|
|
34
32
|
)
|
|
35
33
|
@exporter = exporter
|
|
@@ -115,8 +113,8 @@ module Datadog
|
|
|
115
113
|
#
|
|
116
114
|
# During PR review (https://github.com/DataDog/dd-trace-rb/pull/1807) we discussed the possible alternative of
|
|
117
115
|
# just sleeping before starting the scheduler loop. We ended up not going with that option to avoid the first
|
|
118
|
-
# profile containing up to
|
|
119
|
-
# usual
|
|
116
|
+
# profile containing up to interval + DEFAULT_FLUSH_JITTER_MAXIMUM_SECONDS instead of the
|
|
117
|
+
# usual interval seconds.
|
|
120
118
|
if run_loop?
|
|
121
119
|
jitter_seconds = rand * DEFAULT_FLUSH_JITTER_MAXIMUM_SECONDS # floating point number between (0.0...maximum)
|
|
122
120
|
sleep(jitter_seconds)
|
|
@@ -4,7 +4,10 @@ module Datadog
|
|
|
4
4
|
# Note that `record_sample` is only accessible from native code.
|
|
5
5
|
# Methods prefixed with _native_ are implemented in `stack_recorder.c`
|
|
6
6
|
class StackRecorder
|
|
7
|
-
def initialize(
|
|
7
|
+
def initialize(
|
|
8
|
+
cpu_time_enabled:, alloc_samples_enabled:, heap_samples_enabled:, heap_size_enabled:,
|
|
9
|
+
heap_sample_every:, timeline_enabled:
|
|
10
|
+
)
|
|
8
11
|
# This mutex works in addition to the fancy C-level mutexes we have in the native side (see the docs there).
|
|
9
12
|
# It prevents multiple Ruby threads calling serialize at the same time -- something like
|
|
10
13
|
# `10.times { Thread.new { stack_recorder.serialize } }`.
|
|
@@ -13,7 +16,15 @@ module Datadog
|
|
|
13
16
|
# accidentally happening.
|
|
14
17
|
@no_concurrent_synchronize_mutex = Mutex.new
|
|
15
18
|
|
|
16
|
-
self.class._native_initialize(
|
|
19
|
+
self.class._native_initialize(
|
|
20
|
+
self,
|
|
21
|
+
cpu_time_enabled,
|
|
22
|
+
alloc_samples_enabled,
|
|
23
|
+
heap_samples_enabled,
|
|
24
|
+
heap_size_enabled,
|
|
25
|
+
heap_sample_every,
|
|
26
|
+
timeline_enabled,
|
|
27
|
+
)
|
|
17
28
|
end
|
|
18
29
|
|
|
19
30
|
def serialize
|
|
@@ -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
|
|
|
@@ -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_ACTIVE_MODEL_SERIALIZERS_ENABLED'
|
|
11
|
+
# @!visibility private
|
|
11
12
|
ENV_ANALYTICS_ENABLED = 'DD_TRACE_ACTIVE_MODEL_SERIALIZERS_ANALYTICS_ENABLED'
|
|
12
13
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_ACTIVE_MODEL_SERIALIZERS_ANALYTICS_SAMPLE_RATE'
|
|
13
14
|
SPAN_RENDER = 'active_model_serializers.render'
|
|
@@ -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_ACTIVE_RECORD_ENABLED'
|
|
11
|
+
# @!visibility private
|
|
11
12
|
ENV_ANALYTICS_ENABLED = 'DD_TRACE_ACTIVE_RECORD_ANALYTICS_ENABLED'
|
|
12
13
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_ACTIVE_RECORD_ANALYTICS_SAMPLE_RATE'
|
|
13
14
|
SERVICE_NAME = 'active_record'
|
|
@@ -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_ACTIVE_SUPPORT_ENABLED'
|
|
11
|
+
# @!visibility private
|
|
11
12
|
ENV_ANALYTICS_ENABLED = 'DD_TRACE_ACTIVE_SUPPORT_ANALYTICS_ENABLED'
|
|
12
13
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_ACTIVE_SUPPORT_ANALYTICS_SAMPLE_RATE'
|
|
13
14
|
QUANTIZE_CACHE_MAX_KEY_SIZE = 300
|
|
@@ -10,6 +10,7 @@ module Datadog
|
|
|
10
10
|
ENV_ENABLED = 'DD_TRACE_AWS_ENABLED'
|
|
11
11
|
ENV_SERVICE_NAME = 'DD_TRACE_AWS_SERVICE_NAME'
|
|
12
12
|
ENV_PEER_SERVICE = 'DD_TRACE_AWS_PEER_SERVICE'
|
|
13
|
+
# @!visibility private
|
|
13
14
|
ENV_ANALYTICS_ENABLED = 'DD_TRACE_AWS_ANALYTICS_ENABLED'
|
|
14
15
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_AWS_ANALYTICS_SAMPLE_RATE'
|
|
15
16
|
DEFAULT_PEER_SERVICE_NAME = 'aws'
|
|
@@ -12,6 +12,7 @@ module Datadog
|
|
|
12
12
|
# DEV: If add support for the `memcached` gem (not popular as of 2023), we'll have issues with span naming
|
|
13
13
|
# DEV: conflicts.
|
|
14
14
|
ENV_ENABLED = 'DD_TRACE_DALLI_ENABLED'
|
|
15
|
+
# @!visibility private
|
|
15
16
|
ENV_ANALYTICS_ENABLED = 'DD_TRACE_DALLI_ANALYTICS_ENABLED'
|
|
16
17
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_DALLI_ANALYTICS_SAMPLE_RATE'
|
|
17
18
|
# DEV: This is named `*_MEMCACHED_*` because the spans it refer to are `memcached.*` and this variable
|
|
@@ -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_DELAYED_JOB_ENABLED'
|
|
11
|
+
# @!visibility private
|
|
11
12
|
ENV_ANALYTICS_ENABLED = 'DD_TRACE_DELAYED_JOB_ANALYTICS_ENABLED'
|
|
12
13
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_DELAYED_JOB_ANALYTICS_SAMPLE_RATE'
|
|
13
14
|
SPAN_JOB = 'delayed_job'
|
|
@@ -10,6 +10,7 @@ module Datadog
|
|
|
10
10
|
ENV_ENABLED = 'DD_TRACE_ELASTICSEARCH_ENABLED'
|
|
11
11
|
ENV_SERVICE_NAME = 'DD_TRACE_ELASTICSEARCH_SERVICE_NAME'
|
|
12
12
|
ENV_PEER_SERVICE = 'DD_TRACE_ELASTICSEARCH_PEER_SERVICE'
|
|
13
|
+
# @!visibility private
|
|
13
14
|
ENV_ANALYTICS_ENABLED = 'DD_TRACE_ELASTICSEARCH_ANALYTICS_ENABLED'
|
|
14
15
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_ELASTICSEARCH_ANALYTICS_SAMPLE_RATE'
|
|
15
16
|
DEFAULT_PEER_SERVICE_NAME = 'elasticsearch'
|
|
@@ -11,6 +11,7 @@ module Datadog
|
|
|
11
11
|
ENV_SERVICE_NAME = 'DD_TRACE_ETHON_SERVICE_NAME'
|
|
12
12
|
ENV_PEER_SERVICE = 'DD_TRACE_ETHON_PEER_SERVICE'
|
|
13
13
|
|
|
14
|
+
# @!visibility private
|
|
14
15
|
ENV_ANALYTICS_ENABLED = 'DD_TRACE_ETHON_ANALYTICS_ENABLED'
|
|
15
16
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_ETHON_ANALYTICS_SAMPLE_RATE'
|
|
16
17
|
DEFAULT_PEER_SERVICE_NAME = 'ethon'
|
|
@@ -11,6 +11,7 @@ module Datadog
|
|
|
11
11
|
ENV_SERVICE_NAME = 'DD_TRACE_EXCON_SERVICE_NAME'
|
|
12
12
|
ENV_PEER_SERVICE = 'DD_TRACE_EXCON_PEER_SERVICE'
|
|
13
13
|
|
|
14
|
+
# @!visibility private
|
|
14
15
|
ENV_ANALYTICS_ENABLED = 'DD_TRACE_EXCON_ANALYTICS_ENABLED'
|
|
15
16
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_EXCON_ANALYTICS_SAMPLE_RATE'
|
|
16
17
|
DEFAULT_PEER_SERVICE_NAME = 'excon'
|
|
@@ -21,6 +21,7 @@ module Datadog
|
|
|
21
21
|
o.default true
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
# @!visibility private
|
|
24
25
|
option :analytics_enabled do |o|
|
|
25
26
|
o.type :bool
|
|
26
27
|
o.env Ext::ENV_ANALYTICS_ENABLED
|
|
@@ -34,10 +35,16 @@ module Datadog
|
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
option :distributed_tracing, default: true, type: :bool
|
|
38
|
+
|
|
37
39
|
option :error_handler do |o|
|
|
38
40
|
o.type :proc
|
|
39
41
|
o.default_proc(&DEFAULT_ERROR_HANDLER)
|
|
40
42
|
end
|
|
43
|
+
|
|
44
|
+
option :on_error do |o|
|
|
45
|
+
o.type :proc, nilable: true
|
|
46
|
+
end
|
|
47
|
+
|
|
41
48
|
option :split_by_domain, default: false, type: :bool
|
|
42
49
|
|
|
43
50
|
option :service_name do |o|
|
|
@@ -11,6 +11,7 @@ module Datadog
|
|
|
11
11
|
ENV_SERVICE_NAME = 'DD_TRACE_FARADAY_SERVICE_NAME'
|
|
12
12
|
ENV_PEER_SERVICE = 'DD_TRACE_FARADAY_PEER_SERVICE'
|
|
13
13
|
|
|
14
|
+
# @!visibility private
|
|
14
15
|
ENV_ANALYTICS_ENABLED = 'DD_TRACE_FARADAY_ANALYTICS_ENABLED'
|
|
15
16
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_FARADAY_ANALYTICS_SAMPLE_RATE'
|
|
16
17
|
DEFAULT_PEER_SERVICE_NAME = 'faraday'
|