ddtrace 1.18.0 → 1.20.0

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