datadog 2.7.1 → 2.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +69 -1
- data/ext/datadog_profiling_native_extension/clock_id.h +2 -2
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +64 -54
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +16 -16
- data/ext/datadog_profiling_native_extension/collectors_stack.c +7 -7
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +259 -132
- data/ext/datadog_profiling_native_extension/extconf.rb +0 -8
- data/ext/datadog_profiling_native_extension/heap_recorder.c +11 -89
- data/ext/datadog_profiling_native_extension/heap_recorder.h +1 -1
- data/ext/datadog_profiling_native_extension/http_transport.c +4 -4
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +4 -1
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +3 -1
- data/ext/datadog_profiling_native_extension/profiling.c +10 -8
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +8 -8
- data/ext/datadog_profiling_native_extension/stack_recorder.c +54 -88
- data/ext/datadog_profiling_native_extension/stack_recorder.h +1 -1
- data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
- data/ext/libdatadog_api/crashtracker.c +3 -0
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +355 -157
- data/lib/datadog/appsec/assets/waf_rules/strict.json +62 -32
- data/lib/datadog/appsec/component.rb +1 -8
- data/lib/datadog/appsec/context.rb +54 -0
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +73 -0
- data/lib/datadog/appsec/contrib/active_record/integration.rb +41 -0
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +53 -0
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +6 -6
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +4 -4
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +19 -28
- data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +5 -5
- data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +64 -96
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +10 -10
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +5 -5
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +6 -6
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +43 -49
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +21 -32
- data/lib/datadog/appsec/contrib/rails/patcher.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +6 -6
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +41 -63
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +2 -2
- data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +5 -5
- data/lib/datadog/appsec/event.rb +6 -6
- data/lib/datadog/appsec/ext.rb +3 -1
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +22 -32
- data/lib/datadog/appsec/monitor/reactive/set_user.rb +5 -5
- data/lib/datadog/appsec/processor/context.rb +2 -2
- data/lib/datadog/appsec/processor/rule_loader.rb +0 -3
- data/lib/datadog/appsec/remote.rb +1 -3
- data/lib/datadog/appsec/response.rb +7 -11
- data/lib/datadog/appsec.rb +6 -5
- data/lib/datadog/auto_instrument.rb +3 -0
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +39 -11
- data/lib/datadog/core/configuration/components.rb +20 -2
- data/lib/datadog/core/configuration/settings.rb +10 -0
- data/lib/datadog/core/configuration.rb +10 -2
- data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
- data/lib/datadog/core/crashtracking/component.rb +1 -3
- data/lib/datadog/core/remote/client/capabilities.rb +6 -0
- data/lib/datadog/core/remote/client.rb +65 -59
- data/lib/datadog/core/telemetry/component.rb +9 -3
- data/lib/datadog/core/telemetry/event.rb +87 -3
- data/lib/datadog/core/telemetry/ext.rb +1 -0
- data/lib/datadog/core/telemetry/logging.rb +2 -2
- data/lib/datadog/core/telemetry/metric.rb +22 -0
- data/lib/datadog/core/telemetry/worker.rb +33 -0
- data/lib/datadog/di/base.rb +115 -0
- data/lib/datadog/di/code_tracker.rb +11 -7
- data/lib/datadog/di/component.rb +21 -11
- data/lib/datadog/di/configuration/settings.rb +11 -1
- data/lib/datadog/di/contrib/active_record.rb +1 -0
- data/lib/datadog/di/contrib/railtie.rb +15 -0
- data/lib/datadog/di/contrib.rb +26 -0
- data/lib/datadog/di/error.rb +5 -0
- data/lib/datadog/di/instrumenter.rb +111 -20
- data/lib/datadog/di/preload.rb +18 -0
- data/lib/datadog/di/probe.rb +11 -1
- data/lib/datadog/di/probe_builder.rb +1 -0
- data/lib/datadog/di/probe_manager.rb +8 -5
- data/lib/datadog/di/probe_notification_builder.rb +27 -7
- data/lib/datadog/di/probe_notifier_worker.rb +5 -6
- data/lib/datadog/di/remote.rb +124 -0
- data/lib/datadog/di/serializer.rb +14 -7
- data/lib/datadog/di/transport.rb +3 -5
- data/lib/datadog/di/utils.rb +7 -0
- data/lib/datadog/di.rb +23 -62
- data/lib/datadog/kit/appsec/events.rb +3 -3
- data/lib/datadog/kit/identity.rb +4 -4
- data/lib/datadog/profiling/component.rb +59 -69
- data/lib/datadog/profiling/http_transport.rb +1 -26
- data/lib/datadog/tracing/configuration/settings.rb +4 -8
- data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
- data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/active_record/integration.rb +6 -2
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +3 -1
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +3 -1
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +16 -4
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
- data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +4 -0
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
- data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
- data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
- data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
- data/lib/datadog/tracing/span.rb +12 -4
- data/lib/datadog/tracing/span_event.rb +123 -3
- data/lib/datadog/tracing/span_operation.rb +6 -0
- data/lib/datadog/tracing/transport/serializable_trace.rb +24 -6
- data/lib/datadog/version.rb +2 -2
- data/lib/datadog.rb +3 -0
- metadata +30 -17
- data/lib/datadog/appsec/processor/actions.rb +0 -49
- data/lib/datadog/appsec/reactive/operation.rb +0 -68
- data/lib/datadog/appsec/scope.rb +0 -58
- data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
@@ -4,10 +4,13 @@ module Datadog
|
|
4
4
|
module Profiling
|
5
5
|
# Responsible for wiring up the Profiler for execution
|
6
6
|
module Component
|
7
|
+
ALLOCATION_WITH_RACTORS_ONLY_ONCE = Datadog::Core::Utils::OnlyOnce.new
|
8
|
+
private_constant :ALLOCATION_WITH_RACTORS_ONLY_ONCE
|
9
|
+
|
7
10
|
# Passing in a `nil` tracer is supported and will disable the following profiling features:
|
8
|
-
# *
|
11
|
+
# * Profiling in the trace viewer, as well as scoping a profile down to a span
|
9
12
|
# * Endpoint aggregation in the profiler UX, including normalization (resource per endpoint call)
|
10
|
-
def self.build_profiler_component(settings:, agent_settings:, optional_tracer:) # rubocop:disable Metrics/MethodLength
|
13
|
+
def self.build_profiler_component(settings:, agent_settings:, optional_tracer:, logger:) # rubocop:disable Metrics/MethodLength
|
11
14
|
return [nil, {profiling_enabled: false}] unless settings.profiling.enabled
|
12
15
|
|
13
16
|
# Workaround for weird dependency direction: the Core::Configuration::Components class currently has a
|
@@ -36,14 +39,14 @@ module Datadog
|
|
36
39
|
|
37
40
|
# NOTE: Please update the Initialization section of ProfilingDevelopment.md with any changes to this method
|
38
41
|
|
39
|
-
no_signals_workaround_enabled = no_signals_workaround_enabled?(settings)
|
42
|
+
no_signals_workaround_enabled = no_signals_workaround_enabled?(settings, logger)
|
40
43
|
timeline_enabled = settings.profiling.advanced.timeline_enabled
|
41
|
-
allocation_profiling_enabled = enable_allocation_profiling?(settings)
|
44
|
+
allocation_profiling_enabled = enable_allocation_profiling?(settings, logger)
|
42
45
|
heap_sample_every = get_heap_sample_every(settings)
|
43
|
-
heap_profiling_enabled = enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_every)
|
44
|
-
heap_size_profiling_enabled = enable_heap_size_profiling?(settings, heap_profiling_enabled)
|
46
|
+
heap_profiling_enabled = enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_every, logger)
|
47
|
+
heap_size_profiling_enabled = enable_heap_size_profiling?(settings, heap_profiling_enabled, logger)
|
45
48
|
|
46
|
-
overhead_target_percentage = valid_overhead_target(settings.profiling.advanced.overhead_target_percentage)
|
49
|
+
overhead_target_percentage = valid_overhead_target(settings.profiling.advanced.overhead_target_percentage, logger)
|
47
50
|
upload_period_seconds = [60, settings.profiling.advanced.upload_period_seconds].max
|
48
51
|
|
49
52
|
recorder = Datadog::Profiling::StackRecorder.new(
|
@@ -57,13 +60,13 @@ module Datadog
|
|
57
60
|
)
|
58
61
|
thread_context_collector = build_thread_context_collector(settings, recorder, optional_tracer, timeline_enabled)
|
59
62
|
worker = Datadog::Profiling::Collectors::CpuAndWallTimeWorker.new(
|
60
|
-
gc_profiling_enabled: enable_gc_profiling?(settings),
|
63
|
+
gc_profiling_enabled: enable_gc_profiling?(settings, logger),
|
61
64
|
no_signals_workaround_enabled: no_signals_workaround_enabled,
|
62
65
|
thread_context_collector: thread_context_collector,
|
63
66
|
dynamic_sampling_rate_overhead_target_percentage: overhead_target_percentage,
|
64
67
|
allocation_profiling_enabled: allocation_profiling_enabled,
|
65
68
|
allocation_counting_enabled: settings.profiling.advanced.allocation_counting_enabled,
|
66
|
-
gvl_profiling_enabled: enable_gvl_profiling?(settings),
|
69
|
+
gvl_profiling_enabled: enable_gvl_profiling?(settings, logger),
|
67
70
|
)
|
68
71
|
|
69
72
|
internal_metadata = {
|
@@ -120,7 +123,7 @@ module Datadog
|
|
120
123
|
)
|
121
124
|
end
|
122
125
|
|
123
|
-
private_class_method def self.enable_gc_profiling?(settings)
|
126
|
+
private_class_method def self.enable_gc_profiling?(settings, logger)
|
124
127
|
return false unless settings.profiling.advanced.gc_enabled
|
125
128
|
|
126
129
|
# SEVERE - Only with Ractors
|
@@ -131,14 +134,14 @@ module Datadog
|
|
131
134
|
if RUBY_VERSION.start_with?("3.0.") ||
|
132
135
|
(RUBY_VERSION.start_with?("3.1.") && RUBY_VERSION < "3.1.4") ||
|
133
136
|
(RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3")
|
134
|
-
|
137
|
+
logger.warn(
|
135
138
|
"Current Ruby version (#{RUBY_VERSION}) has a VM bug where enabling GC profiling would cause " \
|
136
139
|
"crashes (https://bugs.ruby-lang.org/issues/18464). GC profiling has been disabled."
|
137
140
|
)
|
138
141
|
return false
|
139
142
|
elsif RUBY_VERSION.start_with?("3.")
|
140
|
-
|
141
|
-
"
|
143
|
+
logger.debug(
|
144
|
+
"Using Ractors may result in GC profiling unexpectedly " \
|
142
145
|
"stopping (https://bugs.ruby-lang.org/issues/19112). Note that this stop has no impact in your " \
|
143
146
|
"application stability or performance. This does not happen if Ractors are not used."
|
144
147
|
)
|
@@ -155,7 +158,7 @@ module Datadog
|
|
155
158
|
heap_sample_rate
|
156
159
|
end
|
157
160
|
|
158
|
-
private_class_method def self.enable_allocation_profiling?(settings)
|
161
|
+
private_class_method def self.enable_allocation_profiling?(settings, logger)
|
159
162
|
return false unless settings.profiling.allocation_enabled
|
160
163
|
|
161
164
|
# Allocation sampling is safe and supported on Ruby 2.x, but has a few caveats on Ruby 3.x.
|
@@ -165,7 +168,7 @@ module Datadog
|
|
165
168
|
# https://github.com/ruby/ruby/pull/7464) that makes this crash in any configuration. This bug is
|
166
169
|
# fixed on Ruby versions 3.2.3 and 3.3.0.
|
167
170
|
if RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3"
|
168
|
-
|
171
|
+
logger.warn(
|
169
172
|
"Allocation profiling is not supported in Ruby versions 3.2.0, 3.2.1 and 3.2.2 and will be forcibly " \
|
170
173
|
"disabled. This is due to a VM bug that can lead to crashes (https://bugs.ruby-lang.org/issues/19482). " \
|
171
174
|
"Other Ruby versions do not suffer from this issue."
|
@@ -181,7 +184,7 @@ module Datadog
|
|
181
184
|
if RUBY_VERSION.start_with?("3.0.") ||
|
182
185
|
(RUBY_VERSION.start_with?("3.1.") && RUBY_VERSION < "3.1.4") ||
|
183
186
|
(RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3")
|
184
|
-
|
187
|
+
logger.warn(
|
185
188
|
"Current Ruby version (#{RUBY_VERSION}) has a VM bug where enabling allocation profiling while using " \
|
186
189
|
"Ractors may cause unexpected issues, including crashes (https://bugs.ruby-lang.org/issues/18464). " \
|
187
190
|
"This does not happen if Ractors are not used."
|
@@ -190,48 +193,38 @@ module Datadog
|
|
190
193
|
# On all known versions of Ruby 3.x, due to https://bugs.ruby-lang.org/issues/19112, when a ractor gets
|
191
194
|
# garbage collected, Ruby will disable all active tracepoints, which this feature internally relies on.
|
192
195
|
elsif RUBY_VERSION.start_with?("3.")
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
196
|
+
ALLOCATION_WITH_RACTORS_ONLY_ONCE.run do
|
197
|
+
logger.info(
|
198
|
+
"Using Ractors may result in allocation profiling " \
|
199
|
+
"stopping (https://bugs.ruby-lang.org/issues/19112). Note that this stop has no impact in your " \
|
200
|
+
"application stability or performance. This does not happen if Ractors are not used."
|
201
|
+
)
|
202
|
+
end
|
198
203
|
end
|
199
204
|
|
200
|
-
|
205
|
+
logger.debug("Enabled allocation profiling")
|
201
206
|
|
202
207
|
true
|
203
208
|
end
|
204
209
|
|
205
|
-
private_class_method def self.enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_rate)
|
210
|
+
private_class_method def self.enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_rate, logger)
|
206
211
|
heap_profiling_enabled = settings.profiling.advanced.experimental_heap_enabled
|
207
212
|
|
208
213
|
return false unless heap_profiling_enabled
|
209
214
|
|
210
|
-
if RUBY_VERSION.start_with?("2.") && RUBY_VERSION < "2.7"
|
211
|
-
Datadog.logger.warn(
|
212
|
-
"Heap profiling currently relies on features introduced in Ruby 2.7 and will be forcibly disabled. " \
|
213
|
-
"Please upgrade to Ruby >= 2.7 in order to use this feature."
|
214
|
-
)
|
215
|
-
return false
|
216
|
-
end
|
217
|
-
|
218
215
|
if RUBY_VERSION < "3.1"
|
219
|
-
|
220
|
-
"Current Ruby version (#{RUBY_VERSION})
|
221
|
-
"
|
222
|
-
"the SEEN_OBJ_ID flag on objects that should have it but don't. Full details can be found in " \
|
223
|
-
"https://github.com/DataDog/dd-trace-rb/pull/3360. This workaround should be safe but can be " \
|
224
|
-
"bypassed by disabling the heap profiler or upgrading to Ruby >= 3.1 where forced object recycling " \
|
225
|
-
"was completely removed (https://bugs.ruby-lang.org/issues/18290)."
|
216
|
+
logger.warn(
|
217
|
+
"Current Ruby version (#{RUBY_VERSION}) cannot support heap profiling due to VM limitations. " \
|
218
|
+
"Please upgrade to Ruby >= 3.1 in order to use this feature. Heap profiling has been disabled."
|
226
219
|
)
|
220
|
+
return false
|
227
221
|
end
|
228
222
|
|
229
223
|
unless allocation_profiling_enabled
|
230
|
-
raise ArgumentError,
|
231
|
-
"Heap profiling requires allocation profiling to be enabled"
|
224
|
+
raise ArgumentError, "Heap profiling requires allocation profiling to be enabled"
|
232
225
|
end
|
233
226
|
|
234
|
-
|
227
|
+
logger.warn(
|
235
228
|
"Enabled experimental heap profiling: heap_sample_rate=#{heap_sample_rate}. This is experimental, not " \
|
236
229
|
"recommended, and will increase overhead!"
|
237
230
|
)
|
@@ -239,25 +232,23 @@ module Datadog
|
|
239
232
|
true
|
240
233
|
end
|
241
234
|
|
242
|
-
private_class_method def self.enable_heap_size_profiling?(settings, heap_profiling_enabled)
|
235
|
+
private_class_method def self.enable_heap_size_profiling?(settings, heap_profiling_enabled, logger)
|
243
236
|
heap_size_profiling_enabled = settings.profiling.advanced.experimental_heap_size_enabled
|
244
237
|
|
245
238
|
return false unless heap_profiling_enabled && heap_size_profiling_enabled
|
246
239
|
|
247
|
-
|
240
|
+
logger.warn(
|
248
241
|
"Enabled experimental heap size profiling. This is experimental, not recommended, and will increase overhead!"
|
249
242
|
)
|
250
243
|
|
251
244
|
true
|
252
245
|
end
|
253
246
|
|
254
|
-
private_class_method def self.no_signals_workaround_enabled?(settings) # rubocop:disable Metrics/MethodLength
|
247
|
+
private_class_method def self.no_signals_workaround_enabled?(settings, logger) # rubocop:disable Metrics/MethodLength
|
255
248
|
setting_value = settings.profiling.advanced.no_signals_workaround_enabled
|
256
|
-
legacy_ruby_that_should_use_workaround = RUBY_VERSION.start_with?("2.5.")
|
257
249
|
|
258
250
|
unless [true, false, :auto].include?(setting_value)
|
259
|
-
|
260
|
-
Datadog.logger.error(
|
251
|
+
logger.warn(
|
261
252
|
"Ignoring invalid value for profiling no_signals_workaround_enabled setting: #{setting_value.inspect}. " \
|
262
253
|
"Valid options are `true`, `false` or (default) `:auto`."
|
263
254
|
)
|
@@ -266,23 +257,23 @@ module Datadog
|
|
266
257
|
end
|
267
258
|
|
268
259
|
if setting_value == false
|
269
|
-
if
|
270
|
-
|
271
|
-
'The profiling "no signals" workaround has been disabled via configuration on
|
272
|
-
"
|
273
|
-
"in production environments, as due to limitations in Ruby APIs, we suspect it may lead to crashes " \
|
274
|
-
"
|
260
|
+
if RUBY_VERSION.start_with?("2.5.")
|
261
|
+
logger.warn(
|
262
|
+
'The profiling "no signals" workaround has been disabled via configuration on Ruby 2.5. ' \
|
263
|
+
"This is not recommended " \
|
264
|
+
"in production environments, as due to limitations in Ruby APIs, we suspect it may lead to rare crashes " \
|
265
|
+
"Please report any issues you run into to Datadog support or " \
|
275
266
|
"via <https://github.com/datadog/dd-trace-rb/issues/new>!"
|
276
267
|
)
|
277
268
|
else
|
278
|
-
|
269
|
+
logger.warn('Profiling "no signals" workaround disabled via configuration')
|
279
270
|
end
|
280
271
|
|
281
272
|
return false
|
282
273
|
end
|
283
274
|
|
284
275
|
if setting_value == true
|
285
|
-
|
276
|
+
logger.warn(
|
286
277
|
'Profiling "no signals" workaround enabled via configuration. Profiling data will have lower quality.'
|
287
278
|
)
|
288
279
|
|
@@ -292,10 +283,10 @@ module Datadog
|
|
292
283
|
# Setting is in auto mode. Let's probe to see if we should enable it:
|
293
284
|
|
294
285
|
# We don't warn users in this situation because "upgrade your Ruby" is not a great warning
|
295
|
-
return true if
|
286
|
+
return true if RUBY_VERSION.start_with?("2.5.")
|
296
287
|
|
297
|
-
if Gem.loaded_specs["mysql2"] && incompatible_libmysqlclient_version?(settings)
|
298
|
-
|
288
|
+
if Gem.loaded_specs["mysql2"] && incompatible_libmysqlclient_version?(settings, logger)
|
289
|
+
logger.warn(
|
299
290
|
'Enabling the profiling "no signals" workaround because an incompatible version of the mysql2 gem is ' \
|
300
291
|
"installed. Profiling data will have lower quality. " \
|
301
292
|
"To fix this, upgrade the libmysqlclient in your OS image to version 8.0.0 or above."
|
@@ -304,7 +295,7 @@ module Datadog
|
|
304
295
|
end
|
305
296
|
|
306
297
|
if Gem.loaded_specs["rugged"]
|
307
|
-
|
298
|
+
logger.warn(
|
308
299
|
'Enabling the profiling "no signals" workaround because the rugged gem is installed. ' \
|
309
300
|
"This is needed because some operations on this gem are currently incompatible with the normal working mode " \
|
310
301
|
"of the profiler, as detailed in <https://github.com/datadog/dd-trace-rb/issues/2721>. " \
|
@@ -314,7 +305,7 @@ module Datadog
|
|
314
305
|
end
|
315
306
|
|
316
307
|
if (defined?(::PhusionPassenger) || Gem.loaded_specs["passenger"]) && incompatible_passenger_version?
|
317
|
-
|
308
|
+
logger.warn(
|
318
309
|
'Enabling the profiling "no signals" workaround because an incompatible version of the passenger gem is ' \
|
319
310
|
"installed. Profiling data will have lower quality." \
|
320
311
|
"To fix this, upgrade the passenger gem to version 6.0.19 or above."
|
@@ -334,10 +325,10 @@ module Datadog
|
|
334
325
|
#
|
335
326
|
# The `mysql2` gem's `info` method can be used to determine which `libmysqlclient` version is in use, and thus to
|
336
327
|
# detect if it's safe for the profiler to use signals or if we need to employ a fallback.
|
337
|
-
private_class_method def self.incompatible_libmysqlclient_version?(settings)
|
328
|
+
private_class_method def self.incompatible_libmysqlclient_version?(settings, logger)
|
338
329
|
return true if settings.profiling.advanced.skip_mysql2_check
|
339
330
|
|
340
|
-
|
331
|
+
logger.debug(
|
341
332
|
"Requiring `mysql2` to check if the `libmysqlclient` version it uses is compatible with profiling"
|
342
333
|
)
|
343
334
|
|
@@ -366,14 +357,14 @@ module Datadog
|
|
366
357
|
libmysqlclient_version >= Gem::Version.new("8.0.0") ||
|
367
358
|
looks_like_mariadb?(info, libmysqlclient_version)
|
368
359
|
|
369
|
-
|
360
|
+
logger.debug(
|
370
361
|
"The `mysql2` gem is using #{compatible ? "a compatible" : "an incompatible"} version of " \
|
371
362
|
"the `libmysqlclient` library (#{libmysqlclient_version})"
|
372
363
|
)
|
373
364
|
|
374
365
|
!compatible
|
375
366
|
rescue StandardError, LoadError => e
|
376
|
-
|
367
|
+
logger.warn(
|
377
368
|
"Failed to probe `mysql2` gem information. " \
|
378
369
|
"Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
|
379
370
|
)
|
@@ -395,12 +386,11 @@ module Datadog
|
|
395
386
|
end
|
396
387
|
end
|
397
388
|
|
398
|
-
private_class_method def self.valid_overhead_target(overhead_target_percentage)
|
389
|
+
private_class_method def self.valid_overhead_target(overhead_target_percentage, logger)
|
399
390
|
if overhead_target_percentage > 0 && overhead_target_percentage <= 20
|
400
391
|
overhead_target_percentage
|
401
392
|
else
|
402
|
-
|
403
|
-
Datadog.logger.error(
|
393
|
+
logger.warn(
|
404
394
|
"Ignoring invalid value for profiling overhead_target_percentage setting: " \
|
405
395
|
"#{overhead_target_percentage.inspect}. Falling back to default value."
|
406
396
|
)
|
@@ -444,10 +434,10 @@ module Datadog
|
|
444
434
|
settings.profiling.advanced.dir_interruption_workaround_enabled
|
445
435
|
end
|
446
436
|
|
447
|
-
private_class_method def self.enable_gvl_profiling?(settings)
|
437
|
+
private_class_method def self.enable_gvl_profiling?(settings, logger)
|
448
438
|
if RUBY_VERSION < "3.2"
|
449
439
|
if settings.profiling.advanced.preview_gvl_enabled
|
450
|
-
|
440
|
+
logger.warn("GVL profiling is currently not supported in Ruby < 3.2 and will not be enabled.")
|
451
441
|
end
|
452
442
|
|
453
443
|
return false
|
@@ -13,13 +13,11 @@ module Datadog
|
|
13
13
|
def initialize(agent_settings:, site:, api_key:, upload_timeout_seconds:)
|
14
14
|
@upload_timeout_milliseconds = (upload_timeout_seconds * 1_000).to_i
|
15
15
|
|
16
|
-
validate_agent_settings(agent_settings)
|
17
|
-
|
18
16
|
@exporter_configuration =
|
19
17
|
if agentless?(site, api_key)
|
20
18
|
[:agentless, site, api_key].freeze
|
21
19
|
else
|
22
|
-
[:agent,
|
20
|
+
[:agent, agent_settings.url].freeze
|
23
21
|
end
|
24
22
|
|
25
23
|
status, result = validate_exporter(exporter_configuration)
|
@@ -75,29 +73,6 @@ module Datadog
|
|
75
73
|
|
76
74
|
private
|
77
75
|
|
78
|
-
def base_url_from(agent_settings)
|
79
|
-
case agent_settings.adapter
|
80
|
-
when Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
81
|
-
"#{agent_settings.ssl ? "https" : "http"}://#{agent_settings.hostname}:#{agent_settings.port}/"
|
82
|
-
when Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER
|
83
|
-
"unix://#{agent_settings.uds_path}"
|
84
|
-
else
|
85
|
-
raise ArgumentError, "Unexpected adapter: #{agent_settings.adapter}"
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def validate_agent_settings(agent_settings)
|
90
|
-
supported_adapters = [
|
91
|
-
Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER,
|
92
|
-
Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
93
|
-
]
|
94
|
-
unless supported_adapters.include?(agent_settings.adapter)
|
95
|
-
raise ArgumentError,
|
96
|
-
"Unsupported transport configuration for profiling: Adapter #{agent_settings.adapter} " \
|
97
|
-
" is not supported"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
76
|
def agentless?(site, api_key)
|
102
77
|
site && api_key && Core::Environment::VariableHelpers.env_to_bool(Profiling::Ext::ENV_AGENTLESS, false)
|
103
78
|
end
|
@@ -368,22 +368,18 @@ module Datadog
|
|
368
368
|
end
|
369
369
|
end
|
370
370
|
|
371
|
-
#
|
371
|
+
# This is only for internal Datadog use via https://github.com/DataDog/datadog-ci-rb . It should not be
|
372
|
+
# used directly.
|
373
|
+
#
|
374
|
+
# DEV-3.0: Make this a non-public API in the next release.
|
372
375
|
# @public_api
|
373
376
|
settings :test_mode do
|
374
|
-
# Enable test mode. This allows the tracer to collect spans from test runs.
|
375
|
-
#
|
376
|
-
# It also prevents the tracer from collecting spans in a production environment. Only use in a test environment.
|
377
|
-
#
|
378
|
-
# @default `DD_TRACE_TEST_MODE_ENABLED` environment variable, otherwise `false`
|
379
|
-
# @return [Boolean]
|
380
377
|
option :enabled do |o|
|
381
378
|
o.type :bool
|
382
379
|
o.default false
|
383
380
|
o.env Tracing::Configuration::Ext::Test::ENV_MODE_ENABLED
|
384
381
|
end
|
385
382
|
|
386
|
-
# Use async writer in test mode
|
387
383
|
option :async do |o|
|
388
384
|
o.type :bool
|
389
385
|
o.default false
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative '../integration'
|
4
4
|
require_relative 'configuration/settings'
|
5
5
|
require_relative 'patcher'
|
6
|
-
require_relative '
|
6
|
+
require_relative '../../../core/contrib/rails/utils'
|
7
7
|
|
8
8
|
module Datadog
|
9
9
|
module Tracing
|
@@ -17,6 +17,9 @@ module Datadog
|
|
17
17
|
|
18
18
|
# @public_api Changing the integration name or integration options can cause breaking changes
|
19
19
|
register_as :action_cable, auto_patch: false
|
20
|
+
def self.gem_name
|
21
|
+
'actioncable'
|
22
|
+
end
|
20
23
|
|
21
24
|
def self.version
|
22
25
|
Gem.loaded_specs['actioncable'] && Gem.loaded_specs['actioncable'].version
|
@@ -33,7 +36,7 @@ module Datadog
|
|
33
36
|
# enabled by rails integration so should only auto instrument
|
34
37
|
# if detected that it is being used without rails
|
35
38
|
def auto_instrument?
|
36
|
-
!Contrib::Rails::Utils.railtie_supported?
|
39
|
+
!Core::Contrib::Rails::Utils.railtie_supported?
|
37
40
|
end
|
38
41
|
|
39
42
|
def new_configuration
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative 'configuration/settings'
|
4
4
|
require_relative 'patcher'
|
5
5
|
require_relative '../integration'
|
6
|
-
require_relative '
|
6
|
+
require_relative '../../../core/contrib/rails/utils'
|
7
7
|
|
8
8
|
module Datadog
|
9
9
|
module Tracing
|
@@ -18,6 +18,10 @@ module Datadog
|
|
18
18
|
# @public_api Changing the integration name or integration options can cause breaking changes
|
19
19
|
register_as :action_mailer, auto_patch: false
|
20
20
|
|
21
|
+
def self.gem_name
|
22
|
+
'actionmailer'
|
23
|
+
end
|
24
|
+
|
21
25
|
def self.version
|
22
26
|
Gem.loaded_specs['actionmailer'] && Gem.loaded_specs['actionmailer'].version
|
23
27
|
end
|
@@ -33,7 +37,7 @@ module Datadog
|
|
33
37
|
# enabled by rails integration so should only auto instrument
|
34
38
|
# if detected that it is being used without rails
|
35
39
|
def auto_instrument?
|
36
|
-
!Contrib::Rails::Utils.railtie_supported?
|
40
|
+
!Core::Contrib::Rails::Utils.railtie_supported?
|
37
41
|
end
|
38
42
|
|
39
43
|
def new_configuration
|
@@ -4,7 +4,7 @@ require_relative 'configuration/settings'
|
|
4
4
|
require_relative 'patcher'
|
5
5
|
require_relative '../integration'
|
6
6
|
require_relative '../rails/ext'
|
7
|
-
require_relative '
|
7
|
+
require_relative '../../../core/contrib/rails/utils'
|
8
8
|
|
9
9
|
module Datadog
|
10
10
|
module Tracing
|
@@ -18,6 +18,9 @@ module Datadog
|
|
18
18
|
|
19
19
|
# @public_api Changing the integration name or integration options can cause breaking changes
|
20
20
|
register_as :action_pack, auto_patch: false
|
21
|
+
def self.gem_name
|
22
|
+
'actionpack'
|
23
|
+
end
|
21
24
|
|
22
25
|
def self.version
|
23
26
|
Gem.loaded_specs['actionpack'] && Gem.loaded_specs['actionpack'].version
|
@@ -34,7 +37,7 @@ module Datadog
|
|
34
37
|
# enabled by rails integration so should only auto instrument
|
35
38
|
# if detected that it is being used without rails
|
36
39
|
def auto_instrument?
|
37
|
-
!Contrib::Rails::Utils.railtie_supported?
|
40
|
+
!Core::Contrib::Rails::Utils.railtie_supported?
|
38
41
|
end
|
39
42
|
|
40
43
|
def new_configuration
|
@@ -4,7 +4,7 @@ require_relative 'configuration/settings'
|
|
4
4
|
require_relative 'patcher'
|
5
5
|
require_relative '../integration'
|
6
6
|
require_relative '../rails/ext'
|
7
|
-
require_relative '
|
7
|
+
require_relative '../../../core/contrib/rails/utils'
|
8
8
|
|
9
9
|
module Datadog
|
10
10
|
module Tracing
|
@@ -18,6 +18,9 @@ module Datadog
|
|
18
18
|
|
19
19
|
# @public_api Changing the integration name or integration options can cause breaking changes
|
20
20
|
register_as :action_view, auto_patch: false
|
21
|
+
def self.gem_name
|
22
|
+
'actionview'
|
23
|
+
end
|
21
24
|
|
22
25
|
def self.version
|
23
26
|
# ActionView is its own gem in Rails 4.1+
|
@@ -41,7 +44,7 @@ module Datadog
|
|
41
44
|
# enabled by rails integration so should only auto instrument
|
42
45
|
# if detected that it is being used without rails
|
43
46
|
def auto_instrument?
|
44
|
-
!Contrib::Rails::Utils.railtie_supported?
|
47
|
+
!Core::Contrib::Rails::Utils.railtie_supported?
|
45
48
|
end
|
46
49
|
|
47
50
|
def new_configuration
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative 'configuration/settings'
|
4
4
|
require_relative 'patcher'
|
5
5
|
require_relative '../integration'
|
6
|
-
require_relative '
|
6
|
+
require_relative '../../../core/contrib/rails/utils'
|
7
7
|
|
8
8
|
module Datadog
|
9
9
|
module Tracing
|
@@ -17,6 +17,9 @@ module Datadog
|
|
17
17
|
|
18
18
|
# @public_api Changing the integration name or integration options can cause breaking changes
|
19
19
|
register_as :active_job, auto_patch: false
|
20
|
+
def self.gem_name
|
21
|
+
'activejob'
|
22
|
+
end
|
20
23
|
|
21
24
|
def self.version
|
22
25
|
Gem.loaded_specs['activejob'] && Gem.loaded_specs['activejob'].version
|
@@ -33,7 +36,7 @@ module Datadog
|
|
33
36
|
# enabled by rails integration so should only auto instrument
|
34
37
|
# if detected that it is being used without rails
|
35
38
|
def auto_instrument?
|
36
|
-
!Contrib::Rails::Utils.railtie_supported?
|
39
|
+
!Core::Contrib::Rails::Utils.railtie_supported?
|
37
40
|
end
|
38
41
|
|
39
42
|
def new_configuration
|
@@ -7,7 +7,7 @@ require_relative 'patcher'
|
|
7
7
|
require_relative '../component'
|
8
8
|
require_relative '../integration'
|
9
9
|
require_relative '../rails/ext'
|
10
|
-
require_relative '
|
10
|
+
require_relative '../../../core/contrib/rails/utils'
|
11
11
|
|
12
12
|
module Datadog
|
13
13
|
module Tracing
|
@@ -22,6 +22,10 @@ module Datadog
|
|
22
22
|
# @public_api Changing the integration name or integration options can cause breaking changes
|
23
23
|
register_as :active_record, auto_patch: false
|
24
24
|
|
25
|
+
def self.gem_name
|
26
|
+
'activerecord'
|
27
|
+
end
|
28
|
+
|
25
29
|
def self.version
|
26
30
|
Gem.loaded_specs['activerecord'] && Gem.loaded_specs['activerecord'].version
|
27
31
|
end
|
@@ -37,7 +41,7 @@ module Datadog
|
|
37
41
|
# enabled by rails integration so should only auto instrument
|
38
42
|
# if detected that it is being used without rails
|
39
43
|
def auto_instrument?
|
40
|
-
!Contrib::Rails::Utils.railtie_supported?
|
44
|
+
!Core::Contrib::Rails::Utils.railtie_supported?
|
41
45
|
end
|
42
46
|
|
43
47
|
def new_configuration
|
@@ -81,7 +81,9 @@ module Datadog
|
|
81
81
|
|
82
82
|
span.set_tag('EVENT', event)
|
83
83
|
|
84
|
-
|
84
|
+
if Datadog.configuration.tracing[:active_support][:cache_key].enabled
|
85
|
+
set_cache_key(span, key, mapping[:multi_key])
|
86
|
+
end
|
85
87
|
rescue StandardError => e
|
86
88
|
Datadog.logger.error(e.message)
|
87
89
|
Datadog::Core::Telemetry::Logger.report(e)
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require_relative '../../../../core/utils'
|
4
4
|
require_relative '../../../metadata/ext'
|
5
5
|
require_relative '../ext'
|
6
|
+
require_relative 'event'
|
6
7
|
|
7
8
|
module Datadog
|
8
9
|
module Tracing
|
@@ -58,7 +59,8 @@ module Datadog
|
|
58
59
|
end
|
59
60
|
|
60
61
|
span.set_tag(Ext::TAG_CACHE_BACKEND, store) if store
|
61
|
-
|
62
|
+
|
63
|
+
set_cache_key(span, key, multi_key) if Datadog.configuration.tracing[:active_support][:cache_key].enabled
|
62
64
|
|
63
65
|
yield
|
64
66
|
end
|
@@ -22,17 +22,29 @@ module Datadog
|
|
22
22
|
# For Rails >= 5.2 w/o redis-activesupport...
|
23
23
|
# ActiveSupport includes a Redis cache store internally, and does not require these overrides.
|
24
24
|
# https://github.com/rails/rails/blob/master/activesupport/lib/active_support/cache/redis_cache_store.rb
|
25
|
-
def
|
25
|
+
def patch_redis_store?(meth)
|
26
26
|
!Gem.loaded_specs['redis-activesupport'].nil? \
|
27
27
|
&& defined?(::ActiveSupport::Cache::RedisStore) \
|
28
28
|
&& ::ActiveSupport::Cache::RedisStore.instance_methods(false).include?(meth)
|
29
29
|
end
|
30
30
|
|
31
|
+
# Patches the Rails built-in Redis cache backend `redis_cache_store`, added in Rails 5.2.
|
32
|
+
# We avoid loading the RedisCacheStore class, as it invokes the statement `gem "redis", ">= 4.0.1"` which
|
33
|
+
# fails if the application is using an old version of Redis, or not using Redis at all.
|
34
|
+
# @see https://github.com/rails/rails/blob/d0dcb8fa6073a0c4d42600c15e82e3bb386b27d3/activesupport/lib/active_support/cache/redis_cache_store.rb#L4
|
35
|
+
def patch_redis_cache_store?(meth)
|
36
|
+
Gem.loaded_specs['redis'] &&
|
37
|
+
# Autoload constants return `constant` for `defined?`, but that doesn't mean they are loaded...
|
38
|
+
defined?(::ActiveSupport::Cache::RedisCacheStore) &&
|
39
|
+
# ... to check that we need to call `autoload?` and check if it returns `nil`, meaning it's loaded.
|
40
|
+
::ActiveSupport::Cache.autoload?(:RedisCacheStore).nil? &&
|
41
|
+
::ActiveSupport::Cache::RedisCacheStore.instance_methods(false).include?(meth)
|
42
|
+
end
|
43
|
+
|
31
44
|
def cache_store_class(meth)
|
32
|
-
if
|
45
|
+
if patch_redis_store?(meth)
|
33
46
|
[::ActiveSupport::Cache::RedisStore, ::ActiveSupport::Cache::Store]
|
34
|
-
elsif
|
35
|
-
&& ::ActiveSupport::Cache::RedisCacheStore.instance_methods(false).include?(meth)
|
47
|
+
elsif patch_redis_cache_store?(meth)
|
36
48
|
[::ActiveSupport::Cache::RedisCacheStore, ::ActiveSupport::Cache::Store]
|
37
49
|
else
|
38
50
|
super
|
@@ -39,6 +39,16 @@ module Datadog
|
|
39
39
|
)
|
40
40
|
end
|
41
41
|
end
|
42
|
+
|
43
|
+
# grouped "cache_key.*" settings
|
44
|
+
settings :cache_key do
|
45
|
+
# enable or disabling the inclusion of the cache_key in the span
|
46
|
+
option :enabled do |o|
|
47
|
+
# cache_key.enabled
|
48
|
+
o.type :bool
|
49
|
+
o.default true
|
50
|
+
end
|
51
|
+
end
|
42
52
|
end
|
43
53
|
end
|
44
54
|
end
|