datadog 2.7.1 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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