datadog 2.7.1 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +69 -1
  3. data/ext/datadog_profiling_native_extension/clock_id.h +2 -2
  4. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +64 -54
  5. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
  6. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
  7. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +16 -16
  8. data/ext/datadog_profiling_native_extension/collectors_stack.c +7 -7
  9. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +259 -132
  10. data/ext/datadog_profiling_native_extension/extconf.rb +0 -8
  11. data/ext/datadog_profiling_native_extension/heap_recorder.c +11 -89
  12. data/ext/datadog_profiling_native_extension/heap_recorder.h +1 -1
  13. data/ext/datadog_profiling_native_extension/http_transport.c +4 -4
  14. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +4 -1
  15. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +3 -1
  16. data/ext/datadog_profiling_native_extension/profiling.c +10 -8
  17. data/ext/datadog_profiling_native_extension/ruby_helpers.c +8 -8
  18. data/ext/datadog_profiling_native_extension/stack_recorder.c +54 -88
  19. data/ext/datadog_profiling_native_extension/stack_recorder.h +1 -1
  20. data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
  21. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
  22. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
  23. data/ext/libdatadog_api/crashtracker.c +3 -0
  24. data/ext/libdatadog_extconf_helpers.rb +1 -1
  25. data/lib/datadog/appsec/assets/waf_rules/recommended.json +355 -157
  26. data/lib/datadog/appsec/assets/waf_rules/strict.json +62 -32
  27. data/lib/datadog/appsec/component.rb +1 -8
  28. data/lib/datadog/appsec/context.rb +54 -0
  29. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +73 -0
  30. data/lib/datadog/appsec/contrib/active_record/integration.rb +41 -0
  31. data/lib/datadog/appsec/contrib/active_record/patcher.rb +53 -0
  32. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +6 -6
  33. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +4 -4
  34. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +19 -28
  35. data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +5 -5
  36. data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
  37. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +64 -96
  38. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +10 -10
  39. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +5 -5
  40. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +6 -6
  41. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
  42. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +43 -49
  43. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +21 -32
  44. data/lib/datadog/appsec/contrib/rails/patcher.rb +1 -1
  45. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +6 -6
  46. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +41 -63
  47. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +2 -2
  48. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +5 -5
  49. data/lib/datadog/appsec/event.rb +6 -6
  50. data/lib/datadog/appsec/ext.rb +3 -1
  51. data/lib/datadog/appsec/monitor/gateway/watcher.rb +22 -32
  52. data/lib/datadog/appsec/monitor/reactive/set_user.rb +5 -5
  53. data/lib/datadog/appsec/processor/context.rb +2 -2
  54. data/lib/datadog/appsec/processor/rule_loader.rb +0 -3
  55. data/lib/datadog/appsec/remote.rb +1 -3
  56. data/lib/datadog/appsec/response.rb +7 -11
  57. data/lib/datadog/appsec.rb +6 -5
  58. data/lib/datadog/auto_instrument.rb +3 -0
  59. data/lib/datadog/core/configuration/agent_settings_resolver.rb +39 -11
  60. data/lib/datadog/core/configuration/components.rb +20 -2
  61. data/lib/datadog/core/configuration/settings.rb +10 -0
  62. data/lib/datadog/core/configuration.rb +10 -2
  63. data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
  64. data/lib/datadog/core/crashtracking/component.rb +1 -3
  65. data/lib/datadog/core/remote/client/capabilities.rb +6 -0
  66. data/lib/datadog/core/remote/client.rb +65 -59
  67. data/lib/datadog/core/telemetry/component.rb +9 -3
  68. data/lib/datadog/core/telemetry/event.rb +87 -3
  69. data/lib/datadog/core/telemetry/ext.rb +1 -0
  70. data/lib/datadog/core/telemetry/logging.rb +2 -2
  71. data/lib/datadog/core/telemetry/metric.rb +22 -0
  72. data/lib/datadog/core/telemetry/worker.rb +33 -0
  73. data/lib/datadog/di/base.rb +115 -0
  74. data/lib/datadog/di/code_tracker.rb +11 -7
  75. data/lib/datadog/di/component.rb +21 -11
  76. data/lib/datadog/di/configuration/settings.rb +11 -1
  77. data/lib/datadog/di/contrib/active_record.rb +1 -0
  78. data/lib/datadog/di/contrib/railtie.rb +15 -0
  79. data/lib/datadog/di/contrib.rb +26 -0
  80. data/lib/datadog/di/error.rb +5 -0
  81. data/lib/datadog/di/instrumenter.rb +111 -20
  82. data/lib/datadog/di/preload.rb +18 -0
  83. data/lib/datadog/di/probe.rb +11 -1
  84. data/lib/datadog/di/probe_builder.rb +1 -0
  85. data/lib/datadog/di/probe_manager.rb +8 -5
  86. data/lib/datadog/di/probe_notification_builder.rb +27 -7
  87. data/lib/datadog/di/probe_notifier_worker.rb +5 -6
  88. data/lib/datadog/di/remote.rb +124 -0
  89. data/lib/datadog/di/serializer.rb +14 -7
  90. data/lib/datadog/di/transport.rb +3 -5
  91. data/lib/datadog/di/utils.rb +7 -0
  92. data/lib/datadog/di.rb +23 -62
  93. data/lib/datadog/kit/appsec/events.rb +3 -3
  94. data/lib/datadog/kit/identity.rb +4 -4
  95. data/lib/datadog/profiling/component.rb +59 -69
  96. data/lib/datadog/profiling/http_transport.rb +1 -26
  97. data/lib/datadog/tracing/configuration/settings.rb +4 -8
  98. data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
  99. data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
  100. data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
  101. data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
  102. data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
  103. data/lib/datadog/tracing/contrib/active_record/integration.rb +6 -2
  104. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +3 -1
  105. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +3 -1
  106. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +16 -4
  107. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
  108. data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
  109. data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
  110. data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
  111. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
  112. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +4 -0
  113. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
  114. data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
  115. data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
  116. data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
  117. data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
  118. data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
  119. data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
  120. data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
  121. data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
  122. data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
  123. data/lib/datadog/tracing/span.rb +12 -4
  124. data/lib/datadog/tracing/span_event.rb +123 -3
  125. data/lib/datadog/tracing/span_operation.rb +6 -0
  126. data/lib/datadog/tracing/transport/serializable_trace.rb +24 -6
  127. data/lib/datadog/version.rb +2 -2
  128. data/lib/datadog.rb +3 -0
  129. metadata +30 -17
  130. data/lib/datadog/appsec/processor/actions.rb +0 -49
  131. data/lib/datadog/appsec/reactive/operation.rb +0 -68
  132. data/lib/datadog/appsec/scope.rb +0 -58
  133. 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
- # * Code Hotspots panel in the trace viewer, as well as scoping a profile down to a span
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
- Datadog.logger.warn(
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
- Datadog.logger.debug(
141
- "In all known versions of Ruby 3.x, using Ractors may result in GC profiling unexpectedly " \
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
- Datadog.logger.warn(
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
- Datadog.logger.warn(
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
- Datadog.logger.warn(
194
- "In all known versions of Ruby 3.x, using Ractors may result in allocation profiling unexpectedly " \
195
- "stopping (https://bugs.ruby-lang.org/issues/19112). Note that this stop has no impact in your " \
196
- "application stability or performance. This does not happen if Ractors are not used."
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
- Datadog.logger.debug("Enabled allocation profiling")
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
- Datadog.logger.debug(
220
- "Current Ruby version (#{RUBY_VERSION}) supports forced object recycling which has a bug that the " \
221
- "heap profiler is forced to work around to remain accurate. This workaround requires force-setting " \
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
- Datadog.logger.warn(
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
- Datadog.logger.warn(
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
- # TODO: Replace with a warning instead.
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 legacy_ruby_that_should_use_workaround
270
- Datadog.logger.warn(
271
- 'The profiling "no signals" workaround has been disabled via configuration on a legacy Ruby version ' \
272
- "(< 2.6). This is not recommended " \
273
- "in production environments, as due to limitations in Ruby APIs, we suspect it may lead to crashes " \
274
- "in very rare situations. Please report any issues you run into to Datadog support or " \
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
- Datadog.logger.warn('Profiling "no signals" workaround disabled via configuration')
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
- Datadog.logger.warn(
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 legacy_ruby_that_should_use_workaround
286
+ return true if RUBY_VERSION.start_with?("2.5.")
296
287
 
297
- if Gem.loaded_specs["mysql2"] && incompatible_libmysqlclient_version?(settings)
298
- Datadog.logger.warn(
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
- Datadog.logger.warn(
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
- Datadog.logger.warn(
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
- Datadog.logger.debug(
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
- Datadog.logger.debug(
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
- Datadog.logger.warn(
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
- # TODO: Replace with a warning instead.
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
- Datadog.logger.warn("GVL profiling is currently not supported in Ruby < 3.2 and will not be enabled.")
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, base_url_from(agent_settings)].freeze
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
- # [Continuous Integration Visibility](https://docs.datadoghq.com/continuous_integration/) configuration.
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 '../rails/utils'
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 '../rails/utils'
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 '../rails/utils'
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 '../rails/utils'
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 '../rails/utils'
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 '../rails/utils'
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
- set_cache_key(span, key, mapping[:multi_key])
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
- set_cache_key(span, key, multi_key)
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 patch_redis?(meth)
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 patch_redis?(meth)
45
+ if patch_redis_store?(meth)
33
46
  [::ActiveSupport::Cache::RedisStore, ::ActiveSupport::Cache::Store]
34
- elsif Gem.loaded_specs['redis'] && defined?(::ActiveSupport::Cache::RedisCacheStore) \
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