datadog 2.36.0 → 2.37.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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -1
  3. data/ext/datadog_profiling_native_extension/clock_id_from_mach.c +5 -12
  4. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +6 -3
  5. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +17 -3
  6. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +219 -98
  7. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +2 -0
  8. data/ext/datadog_profiling_native_extension/extconf.rb +11 -0
  9. data/ext/datadog_profiling_native_extension/ruby_helpers.c +7 -0
  10. data/ext/libdatadog_api/di.c +76 -0
  11. data/ext/libdatadog_api/extconf.rb +6 -0
  12. data/ext/libdatadog_extconf_helpers.rb +1 -1
  13. data/lib/datadog/ai_guard/api_client.rb +6 -4
  14. data/lib/datadog/appsec/api_security/route_extractor.rb +7 -4
  15. data/lib/datadog/appsec/configuration.rb +6 -0
  16. data/lib/datadog/appsec/context.rb +4 -2
  17. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +59 -4
  18. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +59 -5
  19. data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +1 -1
  20. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +4 -0
  21. data/lib/datadog/appsec/contrib/rack/input_peeker.rb +4 -17
  22. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +21 -0
  23. data/lib/datadog/appsec/contrib/rails/gateway/request.rb +2 -1
  24. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +60 -7
  25. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +4 -0
  26. data/lib/datadog/appsec/ext.rb +1 -0
  27. data/lib/datadog/appsec/metrics/collector.rb +18 -1
  28. data/lib/datadog/appsec/metrics/exporter.rb +9 -3
  29. data/lib/datadog/appsec/remote.rb +9 -3
  30. data/lib/datadog/appsec/route_normalizer/rails_route_pattern.rb +176 -0
  31. data/lib/datadog/appsec/route_normalizer/route_pattern.rb +378 -0
  32. data/lib/datadog/appsec/route_normalizer/route_text.rb +57 -0
  33. data/lib/datadog/appsec/route_normalizer.rb +80 -0
  34. data/lib/datadog/appsec/utils/http/body_reader.rb +61 -0
  35. data/lib/datadog/core/configuration/components.rb +82 -2
  36. data/lib/datadog/core/configuration/components_state.rb +6 -1
  37. data/lib/datadog/core/configuration/settings.rb +0 -3
  38. data/lib/datadog/core/configuration/supported_configurations.rb +2 -0
  39. data/lib/datadog/core/evp.rb +11 -0
  40. data/lib/datadog/core/remote/client/capabilities.rb +34 -7
  41. data/lib/datadog/core/telemetry/event/app_started.rb +8 -1
  42. data/lib/datadog/di/base.rb +3 -1
  43. data/lib/datadog/di/code_tracker.rb +5 -2
  44. data/lib/datadog/di/component.rb +110 -36
  45. data/lib/datadog/di/error.rb +10 -0
  46. data/lib/datadog/di/fatal_exceptions.rb +26 -0
  47. data/lib/datadog/di/instrumenter.rb +381 -165
  48. data/lib/datadog/di/probe.rb +14 -0
  49. data/lib/datadog/di/probe_file_loader.rb +8 -3
  50. data/lib/datadog/di/probe_manager.rb +67 -9
  51. data/lib/datadog/di/probe_notification_builder.rb +4 -1
  52. data/lib/datadog/di/probe_notifier_worker.rb +52 -32
  53. data/lib/datadog/di/redactor.rb +16 -1
  54. data/lib/datadog/di/remote.rb +175 -14
  55. data/lib/datadog/di/serializer.rb +12 -5
  56. data/lib/datadog/di/transport/input.rb +8 -4
  57. data/lib/datadog/di.rb +63 -0
  58. data/lib/datadog/kit/appsec/events/v2.rb +60 -2
  59. data/lib/datadog/open_feature/component.rb +29 -6
  60. data/lib/datadog/open_feature/configuration.rb +8 -0
  61. data/lib/datadog/open_feature/ext.rb +2 -0
  62. data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +286 -0
  63. data/lib/datadog/open_feature/flag_evaluation/writer.rb +433 -0
  64. data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +101 -0
  65. data/lib/datadog/open_feature/hooks/{flag_eval_hook.rb → flag_eval_metrics_hook.rb} +1 -1
  66. data/lib/datadog/open_feature/native_evaluator.rb +22 -0
  67. data/lib/datadog/open_feature/provider.rb +59 -27
  68. data/lib/datadog/open_feature/transport.rb +55 -1
  69. data/lib/datadog/opentelemetry/sdk/logs_exporter.rb +5 -12
  70. data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +4 -11
  71. data/lib/datadog/opentelemetry/sdk.rb +19 -0
  72. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +1 -1
  73. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +5 -3
  74. data/lib/datadog/symbol_database/component.rb +164 -47
  75. data/lib/datadog/symbol_database/configuration.rb +12 -4
  76. data/lib/datadog/symbol_database/extensions.rb +19 -0
  77. data/lib/datadog/symbol_database/extractor.rb +124 -87
  78. data/lib/datadog/symbol_database/file_hash.rb +3 -1
  79. data/lib/datadog/symbol_database/remote.rb +8 -3
  80. data/lib/datadog/symbol_database/scope_batcher.rb +7 -3
  81. data/lib/datadog/symbol_database/uploader.rb +9 -2
  82. data/lib/datadog/symbol_database.rb +22 -0
  83. data/lib/datadog/tracing/distributed/baggage.rb +2 -1
  84. data/lib/datadog/tracing/ext.rb +9 -0
  85. data/lib/datadog/tracing/remote.rb +34 -3
  86. data/lib/datadog/version.rb +1 -1
  87. data/lib/datadog.rb +1 -0
  88. metadata +19 -6
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative '../symbol_database'
3
4
  require_relative 'extractor'
4
5
  require_relative 'logger'
5
6
  require_relative 'scope_batcher'
6
7
  require_relative 'uploader'
7
8
  require_relative '../core/utils/time'
9
+ require_relative '../di/fatal_exceptions'
8
10
 
9
11
  module Datadog
10
12
  module SymbolDatabase
@@ -54,21 +56,24 @@ module Datadog
54
56
  MODULE_SINGLETON_CLASS_PRED = Module.instance_method(:singleton_class?)
55
57
  private_constant :MODULE_SINGLETON_CLASS_PRED
56
58
 
57
- # Build a new Component if feature is enabled and dependencies met.
59
+ # Build a new Component if the runtime supports it and dependencies are met.
60
+ # The caller (Core::Configuration::Components) decides whether the feature is
61
+ # enabled and only invokes build when it is, so a disabled component is never
62
+ # constructed. This method gates only on symbol database's own requirements
63
+ # (supported platform, remote config availability).
58
64
  # @param settings [Configuration::Settings] Tracer settings
59
65
  # @param agent_settings [Configuration::AgentSettings] Agent configuration
60
66
  # @param logger [Logger] Logger instance
61
67
  # @param telemetry [Core::Telemetry::Component, nil] Telemetry component for error reporting
62
- # @return [Component, nil] Component instance or nil if not enabled/requirements not met
63
- def self.build(settings, agent_settings, logger, telemetry: nil)
68
+ # @param di_active [Proc, nil] Predicate returning whether Dynamic
69
+ # Instrumentation is currently active (started). Gates remote-config
70
+ # uploads in the nil-default case; nil means "no gate" (standalone
71
+ # force_upload contexts).
72
+ # @return [Component, nil] Component instance or nil if requirements not met
73
+ def self.build(settings, agent_settings, logger, telemetry: nil, di_active: nil)
64
74
  symdb_logger = SymbolDatabase::Logger.new(settings, logger)
65
75
 
66
- unless settings.respond_to?(:symbol_database) && settings.symbol_database.enabled
67
- symdb_logger.debug("symdb: symbol database upload not enabled, skipping")
68
- return
69
- end
70
-
71
- # Symbol database requires MRI Ruby 2.6+.
76
+ # Symbol database requires MRI Ruby 2.7+.
72
77
  # Configuration accessors (settings.symbol_database.*) remain available on all
73
78
  # platforms — only the component (upload) is disabled on unsupported engines/versions.
74
79
  # environment_supported? logs the specific reason (engine or version) internally.
@@ -80,7 +85,7 @@ module Datadog
80
85
  return nil
81
86
  end
82
87
 
83
- new(settings, agent_settings, symdb_logger, telemetry: telemetry).tap do |component|
88
+ new(settings, agent_settings, symdb_logger, telemetry: telemetry, di_active: di_active).tap do |component|
84
89
  # Defer extraction if force upload mode — wait for app boot to complete
85
90
  component.schedule_deferred_upload if settings.symbol_database.internal.force_upload
86
91
  end
@@ -93,11 +98,13 @@ module Datadog
93
98
  # @param agent_settings [Configuration::AgentSettings] Agent configuration
94
99
  # @param logger [Logger] Logger instance
95
100
  # @param telemetry [Core::Telemetry::Component, nil] Telemetry component for error reporting
96
- def initialize(settings, agent_settings, logger, telemetry: nil)
101
+ # @param di_active [Proc, nil] Predicate returning whether Dynamic Instrumentation is currently active
102
+ def initialize(settings, agent_settings, logger, telemetry: nil, di_active: nil)
97
103
  @settings = settings
98
104
  @agent_settings = agent_settings
99
105
  @logger = logger
100
106
  @telemetry = telemetry
107
+ @di_active = di_active
101
108
 
102
109
  @extractor = Extractor.new(logger: logger, settings: settings)
103
110
  @uploader = Uploader.new(settings: settings, agent_settings: agent_settings, logger: logger, telemetry: telemetry)
@@ -136,6 +143,16 @@ module Datadog
136
143
  @hot_load_buffer_mutex = Mutex.new
137
144
  @hot_load_tracepoint = nil
138
145
  @initial_extraction_done = false
146
+
147
+ # Sticky record of "remote config (or force mode) wants symbols
148
+ # uploaded", independent of whether DI is currently active. Set when an
149
+ # upload is requested and either allowed or deferred by the DI gate;
150
+ # cleared only when RC explicitly disables uploads (stop_upload). It
151
+ # survives stop_for_di_disable's scheduler teardown, so
152
+ # resume_pending_upload can restart uploads after a DI disable->re-enable
153
+ # cycle even though RC does not re-dispatch the unchanged symbol-database
154
+ # config.
155
+ @upload_requested = false
139
156
  end
140
157
 
141
158
  # Schedule a deferred upload that waits for app boot to complete.
@@ -182,6 +199,25 @@ module Datadog
182
199
  @scheduler_mutex.synchronize do
183
200
  return if @shutdown
184
201
 
202
+ unless upload_allowed?
203
+ if deferred_by_di_gate?
204
+ # nil-default case: Symbol Database mirrors Dynamic Instrumentation
205
+ # and DI is not active. Record the desire and defer; resume_pending_upload
206
+ # re-attempts when DI is enabled. Without this gate the tracer would
207
+ # extract and upload symbols for applications that never enabled DI.
208
+ @upload_requested = true
209
+ @logger.debug("symdb: upload requested but Dynamic Instrumentation is not active; deferring until DI is enabled")
210
+ else
211
+ # Explicit symbol_database.enabled = false: the feature is disabled,
212
+ # not merely waiting on DI. Clear the desire so resume_pending_upload
213
+ # does not retry a disabled feature.
214
+ @upload_requested = false
215
+ @logger.debug("symdb: upload requested but symbol database upload is disabled; skipping")
216
+ end
217
+ return
218
+ end
219
+ @upload_requested = true
220
+
185
221
  if @owner_pid != Process.pid
186
222
  # Forked child: claim ownership and clear inherited
187
223
  # @upload_in_progress. The inherited flag was the parent's
@@ -198,34 +234,55 @@ module Datadog
198
234
  @scheduler_cv.signal
199
235
  ensure_scheduler_thread
200
236
  end
201
- rescue => e
237
+ rescue Exception => e # standard:disable Lint/RescueException
238
+ Datadog::DI.reraise_if_fatal(e)
202
239
  @logger.debug { "symdb: error scheduling upload: #{e.class}: #{e.message}" }
203
240
  @telemetry&.report(e, description: 'symdb: error scheduling upload')
204
241
  end
205
242
 
206
- # Stop symbol upload (cancel the scheduler) and suppress further hot-load
207
- # extraction. Called when remote config sends upload_symbols: false or
208
- # deletes the config. Disables the TracePoint :class hook so post-stop
209
- # class loads don't re-arm the scheduler, clears the hot-load buffer, and
210
- # resets @initial_extraction_done so a future re-enable performs a fresh
211
- # extract_all instead of draining an empty buffer.
243
+ # Stop symbol upload in response to remote config sending
244
+ # upload_symbols: false or deleting the config: the customer no longer wants
245
+ # uploads, so clear the sticky @upload_requested desire (a later
246
+ # resume_pending_upload must not restart it) and tear down the scheduler and
247
+ # hot-load hook.
212
248
  # Thread-safe: can be called concurrently from multiple remote config updates.
213
- # The TracePoint teardown sits inside the same @scheduler_mutex critical
214
- # section as the @scheduled_at reset, so it is atomic against a concurrent
215
- # start_upload (which installs the TracePoint under @scheduler_mutex). Without
216
- # that, a stop interleaved with a start could leave an enabled TracePoint
217
- # rooted by the VM after stop_upload returned.
218
249
  # @return [void]
219
250
  def stop_upload
220
- @scheduler_mutex.synchronize do
221
- @hot_load_tracepoint&.disable
222
- @hot_load_tracepoint = nil
223
- @scheduled_at = nil
224
- @scheduler_signaled = true
225
- @scheduler_cv.signal
226
- end
227
- @hot_load_buffer_mutex.synchronize { @hot_load_buffer.clear }
228
- @initial_extraction_done = false
251
+ @scheduler_mutex.synchronize { @upload_requested = false }
252
+ suspend_scheduling
253
+ end
254
+
255
+ # Re-attempt a symbol upload that remote config requested but that is not
256
+ # currently running because Dynamic Instrumentation was inactive — either
257
+ # deferred at request time, or suspended by stop_for_di_disable when DI was
258
+ # turned off. Called from the orchestration layer (Tracing::Remote) when DI
259
+ # is enabled via remote configuration (implicit enablement). No-op unless an
260
+ # upload was requested and not since disabled. Mirrors DI's
261
+ # replay_current_probes: RC does not re-dispatch the unchanged
262
+ # symbol-database config on DI re-enable, so the tracer restarts the upload
263
+ # from its own retained desire.
264
+ # @return [void]
265
+ def resume_pending_upload
266
+ requested = @scheduler_mutex.synchronize { @upload_requested }
267
+ start_upload if requested
268
+ nil
269
+ end
270
+
271
+ # Stop uploading when Dynamic Instrumentation is disabled via remote
272
+ # configuration. Only the nil-default (follows-DI) case stops; an explicit
273
+ # symbol_database.enabled = true and force_upload are independent of DI and
274
+ # keep running. Called from the orchestration layer (Tracing::Remote) so
275
+ # Symbol Database's TracePoint and scheduler don't keep uploading after DI
276
+ # is turned off. No-op if uploads were never started.
277
+ # @return [void]
278
+ def stop_for_di_disable
279
+ return if @settings.symbol_database.internal.force_upload
280
+ return unless @settings.symbol_database.enabled.nil?
281
+
282
+ # Suspend, don't stop: preserve @upload_requested so resume_pending_upload
283
+ # restarts the upload when DI is re-enabled and RC never re-sends the
284
+ # (unchanged) symbol-database config.
285
+ suspend_scheduling
229
286
  end
230
287
 
231
288
  # Block until this Component finishes an extract+upload after this call,
@@ -374,23 +431,79 @@ module Datadog
374
431
 
375
432
  private
376
433
 
377
- # Check whether the runtime environment supports symbol database upload.
378
- # Only MRI Ruby 2.6+ is supported. JRuby and TruffleRuby are not supported
379
- # because ObjectSpace iteration and Method#source_location behave differently.
380
- # Configuration accessors remain available on all platforms this only gates
381
- # the component (upload) itself.
434
+ # Tear down the scheduler and hot-load hook without clearing the sticky
435
+ # @upload_requested desire, so resume_pending_upload can restart uploads
436
+ # that RC still wants. Disables the TracePoint :class hook so post-stop
437
+ # class loads don't re-arm the scheduler, clears the hot-load buffer, and
438
+ # resets @initial_extraction_done so a future resume performs a fresh
439
+ # extract_all instead of draining an empty buffer.
440
+ # The TracePoint teardown sits inside the same @scheduler_mutex critical
441
+ # section as the @scheduled_at reset, so it is atomic against a concurrent
442
+ # start_upload (which installs the TracePoint under @scheduler_mutex). Without
443
+ # that, a stop interleaved with a start could leave an enabled TracePoint
444
+ # rooted by the VM after this returned.
445
+ # @return [void]
446
+ def suspend_scheduling
447
+ @scheduler_mutex.synchronize do
448
+ @hot_load_tracepoint&.disable
449
+ @hot_load_tracepoint = nil
450
+ @scheduled_at = nil
451
+ @scheduler_signaled = true
452
+ @scheduler_cv.signal
453
+ end
454
+ @hot_load_buffer_mutex.synchronize { @hot_load_buffer.clear }
455
+ @initial_extraction_done = false
456
+ nil
457
+ end
458
+
459
+ # Whether a remote-config-triggered upload may proceed now.
460
+ #
461
+ # force_upload and an explicit `symbol_database.enabled = true` both mean
462
+ # "upload regardless of Dynamic Instrumentation". Only the nil-default case
463
+ # — where Symbol Database mirrors DI — is gated on DI actually being active,
464
+ # so the tracer never extracts symbols for an application that never
465
+ # enabled Dynamic Instrumentation.
466
+ # @return [bool]
467
+ def upload_allowed?
468
+ return true if @settings.symbol_database.internal.force_upload
469
+
470
+ case @settings.symbol_database.enabled
471
+ when true then true
472
+ when false then false
473
+ # steep:ignore NoMethod — Steep does not narrow @di_active to non-nil after the .nil? check
474
+ else @di_active.nil? || @di_active.call # steep:ignore NoMethod
475
+ end
476
+ end
477
+
478
+ # Whether upload is currently blocked specifically by the nil-default
479
+ # DI-active gate — the only case that defers and retries via
480
+ # resume_pending_upload. An explicit symbol_database.enabled = false is a
481
+ # disabled feature, not a deferral, so it clears @upload_requested and is
482
+ # not retried. force_upload and explicit true are never gated, so they are
483
+ # never deferred.
484
+ # @return [bool]
485
+ def deferred_by_di_gate?
486
+ return false if @settings.symbol_database.internal.force_upload
487
+ return false unless @settings.symbol_database.enabled.nil?
488
+
489
+ # After the guards above, upload_allowed? reduces to the DI-active gate,
490
+ # so a disallowed upload here is precisely a DI-gate deferral.
491
+ !upload_allowed?
492
+ end
493
+
494
+ # Check whether the runtime environment supports symbol database upload,
495
+ # logging the reason when it does not.
382
496
  # @param logger [Logger]
383
497
  # @return [Boolean]
384
498
  def self.environment_supported?(logger)
499
+ return true if SymbolDatabase.supported_runtime?
500
+
385
501
  if RUBY_ENGINE != 'ruby'
386
502
  logger.debug { "symdb: not supported on #{RUBY_ENGINE}, skipping" }
387
- return false
388
- end
389
- if RubyVersion.is?('< 2.6')
390
- logger.debug { "symdb: requires Ruby 2.6+, running #{RUBY_VERSION}, skipping" }
391
- return false
503
+ else
504
+ logger.debug { "symdb: requires Ruby 2.7+, running #{RUBY_VERSION}, skipping" }
392
505
  end
393
- true
506
+ false
394
507
  end
395
508
  private_class_method :environment_supported?
396
509
 
@@ -454,7 +567,8 @@ module Datadog
454
567
 
455
568
  extract_and_upload
456
569
  end
457
- rescue => e
570
+ rescue Exception => e # standard:disable Lint/RescueException
571
+ Datadog::DI.reraise_if_fatal(e)
458
572
  @logger.debug { "symdb: scheduler error: #{e.class}: #{e.message}" }
459
573
  @telemetry&.report(e, description: 'symdb: scheduler error')
460
574
  end
@@ -507,7 +621,8 @@ module Datadog
507
621
  @last_upload_scope_count = extracted_count
508
622
  @last_upload_time_cv.broadcast
509
623
  end
510
- rescue => e
624
+ rescue Exception => e # standard:disable Lint/RescueException
625
+ Datadog::DI.reraise_if_fatal(e)
511
626
  @logger.debug { "symdb: extraction error: #{e.class}: #{e.message}" }
512
627
  @telemetry&.report(e, description: 'symdb: extraction error')
513
628
  @mutex.synchronize do
@@ -557,7 +672,8 @@ module Datadog
557
672
  mod = tp.self
558
673
  next if MODULE_SINGLETON_CLASS_PRED.bind(mod).call
559
674
  component.send(:enqueue_hot_load, mod)
560
- rescue => e
675
+ rescue Exception => e # standard:disable Lint/RescueException
676
+ Datadog::DI.reraise_if_fatal(e)
561
677
  # Logger or telemetry can themselves raise (custom logger
562
678
  # implementation, telemetry worker in an unexpected state). The
563
679
  # :class TracePoint fires inside customer class bodies, so the
@@ -566,7 +682,8 @@ module Datadog
566
682
  begin
567
683
  logger.debug { "symdb: hot-load hook error: #{e.class}: #{e.message}" }
568
684
  telemetry&.report(e, description: 'symdb: hot-load hook error')
569
- rescue
685
+ rescue Exception => report_exc # standard:disable Lint/RescueException
686
+ Datadog::DI.reraise_if_fatal(report_exc)
570
687
  nil
571
688
  end
572
689
  end
@@ -7,11 +7,11 @@ module Datadog
7
7
  # Configuration settings for symbol database upload feature.
8
8
  #
9
9
  # Public environment variable:
10
- # - DD_SYMBOL_DATABASE_UPLOAD_ENABLED (default: false) - Feature gate
10
+ # - DD_SYMBOL_DATABASE_UPLOAD_ENABLED - Feature gate, tri-state
11
+ # (true/false/nil). See the :enabled option.
11
12
  #
12
13
  # Extended into: Core::Configuration::Settings (via extend)
13
14
  # Accessed as: Datadog.configuration.symbol_database.enabled
14
- # Used by: Component.build (checks if feature enabled)
15
15
  module Settings
16
16
  # Hook called when this module is extended into a class.
17
17
  # @param base [Class, Module] The class or module being extended
@@ -28,10 +28,18 @@ module Datadog
28
28
  base.class_eval do
29
29
  # steep:ignore:start
30
30
  settings :symbol_database do
31
+ # @return [Boolean, nil]
32
+ # When nil (the default), symbol database mirrors Dynamic
33
+ # Instrumentation: it is advertised and built alongside DI, but
34
+ # only extracts and uploads symbols when DI is actually enabled
35
+ # (via DD_DYNAMIC_INSTRUMENTATION_ENABLED or implicit enablement
36
+ # through the DI UI). Set true/false explicitly via
37
+ # DD_SYMBOL_DATABASE_UPLOAD_ENABLED or c.symbol_database.enabled to
38
+ # override: true uploads regardless of DI, false disables entirely.
31
39
  option :enabled do |o|
32
- o.type :bool
33
40
  o.env 'DD_SYMBOL_DATABASE_UPLOAD_ENABLED'
34
- o.default false
41
+ o.default nil
42
+ o.type :bool, nilable: true
35
43
  end
36
44
 
37
45
  # Settings in the 'internal' group are for internal Datadog
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../core/configuration'
4
+ require_relative 'configuration'
5
+
6
+ module Datadog
7
+ module SymbolDatabase
8
+ # Registers the symbol_database settings group on core's Settings.
9
+ module Extensions
10
+ # Extends core Settings with the symbol_database settings group.
11
+ # @return [void]
12
+ def self.activate!
13
+ Core::Configuration::Settings.extend(Configuration::Settings)
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ Datadog::SymbolDatabase::Extensions.activate!