datadog 2.15.0 → 2.17.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +74 -2
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +7 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.c +22 -12
- data/ext/datadog_profiling_native_extension/encoded_profile.h +1 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +3 -0
- data/ext/datadog_profiling_native_extension/heap_recorder.c +8 -1
- data/ext/datadog_profiling_native_extension/http_transport.c +45 -72
- data/ext/datadog_profiling_native_extension/stack_recorder.c +4 -5
- data/ext/libdatadog_api/crashtracker.c +11 -12
- data/ext/libdatadog_api/crashtracker.h +5 -0
- data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
- data/ext/libdatadog_api/datadog_ruby_common.h +7 -0
- data/ext/libdatadog_api/init.c +15 -0
- data/ext/libdatadog_api/library_config.c +122 -0
- data/ext/libdatadog_api/library_config.h +19 -0
- data/ext/libdatadog_api/macos_development.md +3 -3
- data/ext/libdatadog_api/process_discovery.c +117 -0
- data/ext/libdatadog_api/process_discovery.h +5 -0
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/appsec/actions_handler.rb +3 -2
- data/lib/datadog/appsec/api_security/lru_cache.rb +49 -0
- data/lib/datadog/appsec/api_security.rb +9 -0
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +1344 -0
- data/lib/datadog/appsec/assets/waf_rules/strict.json +1344 -0
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +11 -4
- data/lib/datadog/appsec/configuration/settings.rb +31 -18
- data/lib/datadog/appsec/context.rb +1 -1
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +10 -12
- data/lib/datadog/appsec/contrib/active_record/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/active_record/patcher.rb +22 -22
- data/lib/datadog/appsec/contrib/devise/data_extractor.rb +2 -3
- data/lib/datadog/appsec/contrib/devise/ext.rb +1 -0
- data/lib/datadog/appsec/contrib/devise/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/devise/patcher.rb +3 -5
- data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +17 -4
- data/lib/datadog/appsec/contrib/excon/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +9 -10
- data/lib/datadog/appsec/contrib/faraday/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +8 -9
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +8 -9
- data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +22 -32
- data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +16 -16
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +11 -13
- data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/patcher.rb +21 -21
- data/lib/datadog/appsec/contrib/rest_client/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +10 -11
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +17 -23
- data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
- data/lib/datadog/appsec/event.rb +85 -95
- data/lib/datadog/appsec/instrumentation/gateway/argument.rb +5 -2
- data/lib/datadog/appsec/metrics/telemetry.rb +1 -1
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +42 -12
- data/lib/datadog/appsec/processor/rule_loader.rb +26 -28
- data/lib/datadog/appsec/processor/rule_merger.rb +5 -5
- data/lib/datadog/appsec/processor.rb +1 -1
- data/lib/datadog/appsec/remote.rb +14 -13
- data/lib/datadog/appsec/response.rb +6 -6
- data/lib/datadog/appsec/security_engine/runner.rb +1 -1
- data/lib/datadog/appsec/security_event.rb +39 -0
- data/lib/datadog/appsec.rb +1 -1
- data/lib/datadog/core/buffer/random.rb +18 -2
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +5 -5
- data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
- data/lib/datadog/core/configuration/components.rb +48 -30
- data/lib/datadog/core/configuration/components_state.rb +23 -0
- data/lib/datadog/core/configuration/option.rb +79 -43
- data/lib/datadog/core/configuration/option_definition.rb +4 -4
- data/lib/datadog/core/configuration/options.rb +1 -1
- data/lib/datadog/core/configuration/settings.rb +20 -10
- data/lib/datadog/core/configuration/stable_config.rb +23 -0
- data/lib/datadog/core/configuration.rb +40 -16
- data/lib/datadog/core/crashtracking/component.rb +3 -10
- data/lib/datadog/core/encoding.rb +1 -1
- data/lib/datadog/core/environment/cgroup.rb +10 -12
- data/lib/datadog/core/environment/container.rb +38 -40
- data/lib/datadog/core/environment/ext.rb +6 -6
- data/lib/datadog/core/environment/git.rb +1 -0
- data/lib/datadog/core/environment/identity.rb +3 -3
- data/lib/datadog/core/environment/platform.rb +3 -3
- data/lib/datadog/core/environment/variable_helpers.rb +1 -1
- data/lib/datadog/core/error.rb +11 -9
- data/lib/datadog/core/logger.rb +2 -2
- data/lib/datadog/core/metrics/client.rb +20 -21
- data/lib/datadog/core/metrics/logging.rb +5 -5
- data/lib/datadog/core/process_discovery.rb +32 -0
- data/lib/datadog/core/rate_limiter.rb +4 -2
- data/lib/datadog/core/remote/client.rb +39 -31
- data/lib/datadog/core/remote/component.rb +3 -3
- data/lib/datadog/core/remote/configuration/digest.rb +7 -7
- data/lib/datadog/core/remote/configuration/path.rb +1 -1
- data/lib/datadog/core/remote/transport/http/client.rb +1 -1
- data/lib/datadog/core/remote/transport/http/config.rb +21 -5
- data/lib/datadog/core/remote/transport/http/negotiation.rb +1 -1
- data/lib/datadog/core/runtime/metrics.rb +4 -4
- data/lib/datadog/core/telemetry/component.rb +78 -53
- data/lib/datadog/core/telemetry/emitter.rb +23 -11
- data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -0
- data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
- data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
- data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
- data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
- data/lib/datadog/core/telemetry/event/app_started.rb +179 -0
- data/lib/datadog/core/telemetry/event/base.rb +40 -0
- data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
- data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
- data/lib/datadog/core/telemetry/event/log.rb +76 -0
- data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
- data/lib/datadog/core/telemetry/event.rb +17 -472
- data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
- data/lib/datadog/core/telemetry/logger.rb +1 -1
- data/lib/datadog/core/telemetry/metric.rb +3 -3
- data/lib/datadog/core/telemetry/request.rb +3 -3
- data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
- data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
- data/lib/datadog/core/telemetry/transport/http.rb +63 -0
- data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
- data/lib/datadog/core/telemetry/worker.rb +90 -24
- data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
- data/lib/datadog/core/transport/http/builder.rb +13 -13
- data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
- data/lib/datadog/core/utils/duration.rb +32 -32
- data/lib/datadog/core/utils/forking.rb +2 -2
- data/lib/datadog/core/utils/network.rb +6 -6
- data/lib/datadog/core/utils/only_once_successful.rb +16 -5
- data/lib/datadog/core/utils/time.rb +20 -0
- data/lib/datadog/core/utils/truncation.rb +21 -0
- data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
- data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
- data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
- data/lib/datadog/core/worker.rb +1 -1
- data/lib/datadog/core/workers/async.rb +29 -12
- data/lib/datadog/core/workers/interval_loop.rb +12 -1
- data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
- data/lib/datadog/core.rb +8 -0
- data/lib/datadog/di/boot.rb +34 -0
- data/lib/datadog/di/remote.rb +2 -0
- data/lib/datadog/di.rb +5 -32
- data/lib/datadog/error_tracking/collector.rb +87 -0
- data/lib/datadog/error_tracking/component.rb +167 -0
- data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
- data/lib/datadog/error_tracking/configuration.rb +11 -0
- data/lib/datadog/error_tracking/ext.rb +18 -0
- data/lib/datadog/error_tracking/extensions.rb +16 -0
- data/lib/datadog/error_tracking/filters.rb +77 -0
- data/lib/datadog/error_tracking.rb +18 -0
- data/lib/datadog/kit/identity.rb +1 -1
- data/lib/datadog/profiling/collectors/code_provenance.rb +1 -1
- data/lib/datadog/profiling/exporter.rb +1 -1
- data/lib/datadog/profiling/ext.rb +0 -1
- data/lib/datadog/profiling/flush.rb +1 -1
- data/lib/datadog/profiling/http_transport.rb +1 -6
- data/lib/datadog/profiling/scheduler.rb +8 -1
- data/lib/datadog/profiling/tag_builder.rb +1 -5
- data/lib/datadog/tracing/analytics.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +4 -1
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +33 -0
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +2 -4
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
- data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +1 -5
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +1 -5
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +1 -5
- data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +2 -0
- data/lib/datadog/tracing/contrib/karafka/monitor.rb +1 -1
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
- data/lib/datadog/tracing/contrib/patcher.rb +5 -2
- data/lib/datadog/tracing/contrib/support.rb +28 -0
- data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
- data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
- data/lib/datadog/tracing/distributed/datadog.rb +2 -2
- data/lib/datadog/tracing/metadata/errors.rb +4 -4
- data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
- data/lib/datadog/tracing/span_operation.rb +38 -14
- data/lib/datadog/tracing/trace_operation.rb +15 -7
- data/lib/datadog/tracing/tracer.rb +7 -3
- data/lib/datadog/tracing/utils.rb +1 -1
- data/lib/datadog/version.rb +1 -1
- data/lib/datadog.rb +2 -3
- metadata +53 -10
- data/lib/datadog/core/telemetry/http/env.rb +0 -20
- data/lib/datadog/core/telemetry/http/ext.rb +0 -28
- data/lib/datadog/core/telemetry/http/response.rb +0 -70
- data/lib/datadog/core/telemetry/http/transport.rb +0 -90
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'agent_settings_resolver'
|
4
|
+
require_relative 'components_state'
|
4
5
|
require_relative 'ext'
|
5
6
|
require_relative '../diagnostics/environment_logger'
|
6
7
|
require_relative '../diagnostics/health'
|
@@ -8,15 +9,15 @@ require_relative '../logger'
|
|
8
9
|
require_relative '../runtime/metrics'
|
9
10
|
require_relative '../telemetry/component'
|
10
11
|
require_relative '../workers/runtime_metrics'
|
11
|
-
|
12
12
|
require_relative '../remote/component'
|
13
13
|
require_relative '../../tracing/component'
|
14
14
|
require_relative '../../profiling/component'
|
15
15
|
require_relative '../../appsec/component'
|
16
16
|
require_relative '../../di/component'
|
17
|
+
require_relative '../../error_tracking/component'
|
17
18
|
require_relative '../crashtracking/component'
|
18
|
-
|
19
19
|
require_relative '../environment/agent_info'
|
20
|
+
require_relative '../process_discovery'
|
20
21
|
|
21
22
|
module Datadog
|
22
23
|
module Core
|
@@ -26,12 +27,12 @@ module Datadog
|
|
26
27
|
class << self
|
27
28
|
include Datadog::Tracing::Component
|
28
29
|
|
29
|
-
def build_health_metrics(settings, logger)
|
30
|
+
def build_health_metrics(settings, logger, telemetry)
|
30
31
|
settings = settings.health_metrics
|
31
|
-
options = {
|
32
|
+
options = {enabled: settings.enabled}
|
32
33
|
options[:statsd] = settings.statsd unless settings.statsd.nil?
|
33
34
|
|
34
|
-
Core::Diagnostics::Health::Metrics.new(logger: logger, **options)
|
35
|
+
Core::Diagnostics::Health::Metrics.new(telemetry: telemetry, logger: logger, **options)
|
35
36
|
end
|
36
37
|
|
37
38
|
def build_logger(settings)
|
@@ -41,24 +42,24 @@ module Datadog
|
|
41
42
|
logger
|
42
43
|
end
|
43
44
|
|
44
|
-
def build_runtime_metrics(settings, logger)
|
45
|
-
options = {
|
45
|
+
def build_runtime_metrics(settings, logger, telemetry)
|
46
|
+
options = {enabled: settings.runtime_metrics.enabled}
|
46
47
|
options[:statsd] = settings.runtime_metrics.statsd unless settings.runtime_metrics.statsd.nil?
|
47
48
|
options[:services] = [settings.service] unless settings.service.nil?
|
48
49
|
options[:experimental_runtime_id_enabled] = settings.runtime_metrics.experimental_runtime_id_enabled
|
49
50
|
|
50
|
-
Core::Runtime::Metrics.new(logger: logger, **options)
|
51
|
+
Core::Runtime::Metrics.new(logger: logger, telemetry: telemetry, **options)
|
51
52
|
end
|
52
53
|
|
53
|
-
def build_runtime_metrics_worker(settings, logger)
|
54
|
+
def build_runtime_metrics_worker(settings, logger, telemetry)
|
54
55
|
# NOTE: Should we just ignore building the worker if its not enabled?
|
55
56
|
options = settings.runtime_metrics.opts.merge(
|
56
57
|
enabled: settings.runtime_metrics.enabled,
|
57
|
-
metrics: build_runtime_metrics(settings, logger),
|
58
|
+
metrics: build_runtime_metrics(settings, logger, telemetry),
|
58
59
|
logger: logger,
|
59
60
|
)
|
60
61
|
|
61
|
-
Core::Workers::RuntimeMetrics.new(options)
|
62
|
+
Core::Workers::RuntimeMetrics.new(telemetry: telemetry, **options)
|
62
63
|
end
|
63
64
|
|
64
65
|
def build_telemetry(settings, agent_settings, logger)
|
@@ -68,7 +69,7 @@ module Datadog
|
|
68
69
|
def build_crashtracker(settings, agent_settings, logger:)
|
69
70
|
return unless settings.crashtracking.enabled
|
70
71
|
|
71
|
-
if (libdatadog_api_failure = Datadog::Core::
|
72
|
+
if (libdatadog_api_failure = Datadog::Core::LIBDATADOG_API_FAILURE)
|
72
73
|
logger.debug("Cannot enable crashtracking: #{libdatadog_api_failure}")
|
73
74
|
return
|
74
75
|
end
|
@@ -88,6 +89,7 @@ module Datadog
|
|
88
89
|
:telemetry,
|
89
90
|
:tracer,
|
90
91
|
:crashtracker,
|
92
|
+
:error_tracking,
|
91
93
|
:dynamic_instrumentation,
|
92
94
|
:appsec,
|
93
95
|
:agent_info
|
@@ -118,17 +120,22 @@ module Datadog
|
|
118
120
|
)
|
119
121
|
@environment_logger_extra.merge!(profiler_logger_extra) if profiler_logger_extra
|
120
122
|
|
121
|
-
@runtime_metrics = self.class.build_runtime_metrics_worker(settings, @logger)
|
122
|
-
@health_metrics = self.class.build_health_metrics(settings, @logger)
|
123
|
+
@runtime_metrics = self.class.build_runtime_metrics_worker(settings, @logger, telemetry)
|
124
|
+
@health_metrics = self.class.build_health_metrics(settings, @logger, telemetry)
|
123
125
|
@appsec = Datadog::AppSec::Component.build_appsec_component(settings, telemetry: telemetry)
|
124
126
|
@dynamic_instrumentation = Datadog::DI::Component.build(settings, agent_settings, @logger, telemetry: telemetry)
|
127
|
+
@error_tracking = Datadog::ErrorTracking::Component.build(settings, @tracer, @logger)
|
125
128
|
@environment_logger_extra[:dynamic_instrumentation_enabled] = !!@dynamic_instrumentation
|
129
|
+
# TODO: Re-enable this once we have updated libdatadog to 17.1
|
130
|
+
# @process_discovery_fd = Core::ProcessDiscovery.get_and_store_metadata(settings, @logger)
|
126
131
|
|
127
132
|
self.class.configure_tracing(settings)
|
128
133
|
end
|
129
134
|
|
130
135
|
# Starts up components
|
131
136
|
def startup!(settings, old_state: nil)
|
137
|
+
telemetry.start(old_state&.telemetry_enabled?)
|
138
|
+
|
132
139
|
if settings.profiling.enabled
|
133
140
|
if profiler
|
134
141
|
profiler.start
|
@@ -139,7 +146,7 @@ module Datadog
|
|
139
146
|
end
|
140
147
|
end
|
141
148
|
|
142
|
-
if settings.remote.enabled && old_state&.
|
149
|
+
if settings.remote.enabled && old_state&.remote_started?
|
143
150
|
# The library was reconfigured and previously it already started
|
144
151
|
# the remote component (i.e., it received at least one request
|
145
152
|
# through the installed Rack middleware which started the remote).
|
@@ -157,20 +164,20 @@ module Datadog
|
|
157
164
|
# and avoid tearing down parts still in use.
|
158
165
|
def shutdown!(replacement = nil)
|
159
166
|
# Shutdown remote configuration
|
160
|
-
remote
|
167
|
+
remote&.shutdown!
|
161
168
|
|
162
169
|
# Shutdown DI after remote, since remote config triggers DI operations.
|
163
170
|
dynamic_instrumentation&.shutdown!
|
164
171
|
|
165
172
|
# Decommission AppSec
|
166
|
-
appsec
|
173
|
+
appsec&.shutdown!
|
167
174
|
|
168
175
|
# Shutdown the old tracer, unless it's still being used.
|
169
176
|
# (e.g. a custom tracer instance passed in.)
|
170
|
-
tracer.shutdown! unless replacement && tracer
|
177
|
+
tracer.shutdown! unless replacement && tracer.equal?(replacement.tracer)
|
171
178
|
|
172
179
|
# Shutdown old profiler
|
173
|
-
profiler
|
180
|
+
profiler&.shutdown!
|
174
181
|
|
175
182
|
# Shutdown workers
|
176
183
|
runtime_metrics.stop(true, close_metrics: false)
|
@@ -188,21 +195,32 @@ module Datadog
|
|
188
195
|
health_metrics.statsd
|
189
196
|
].compact.uniq
|
190
197
|
|
191
|
-
new_statsd =
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
198
|
+
new_statsd = if replacement
|
199
|
+
[
|
200
|
+
replacement.runtime_metrics.metrics.statsd,
|
201
|
+
replacement.health_metrics.statsd
|
202
|
+
].compact.uniq
|
203
|
+
else
|
204
|
+
[]
|
205
|
+
end
|
199
206
|
|
200
207
|
unused_statsd = (old_statsd - (old_statsd & new_statsd))
|
201
208
|
unused_statsd.each(&:close)
|
202
209
|
|
203
|
-
# enqueue closing event before stopping telemetry so it will be
|
204
|
-
telemetry.emit_closing! unless replacement
|
205
|
-
telemetry.
|
210
|
+
# enqueue closing event before stopping telemetry so it will be sent out on shutdown
|
211
|
+
telemetry.emit_closing! unless replacement&.telemetry&.enabled
|
212
|
+
telemetry.shutdown!
|
213
|
+
|
214
|
+
# TODO: Re-enable this once we have updated libdatadog to 17.1
|
215
|
+
# Core::ProcessDiscovery._native_close_tracer_memfd(@process_discovery_fd, @logger) if @process_discovery_fd
|
216
|
+
end
|
217
|
+
|
218
|
+
# Returns the current state of various components.
|
219
|
+
def state
|
220
|
+
ComponentsState.new(
|
221
|
+
telemetry_enabled: telemetry.enabled,
|
222
|
+
remote_started: remote&.started?,
|
223
|
+
)
|
206
224
|
end
|
207
225
|
end
|
208
226
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Core
|
5
|
+
module Configuration
|
6
|
+
# Stores the state of component tree when replacing the tree.
|
7
|
+
class ComponentsState
|
8
|
+
def initialize(telemetry_enabled:, remote_started:)
|
9
|
+
@telemetry_enabled = !!telemetry_enabled
|
10
|
+
@remote_started = !!remote_started
|
11
|
+
end
|
12
|
+
|
13
|
+
def telemetry_enabled?
|
14
|
+
@telemetry_enabled
|
15
|
+
end
|
16
|
+
|
17
|
+
def remote_started?
|
18
|
+
@remote_started
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'stable_config'
|
3
4
|
require_relative '../utils/safe_dup'
|
4
5
|
|
5
6
|
module Datadog
|
@@ -32,17 +33,25 @@ module Datadog
|
|
32
33
|
end
|
33
34
|
|
34
35
|
# Remote configuration provided through the Datadog app.
|
35
|
-
REMOTE_CONFIGURATION = Value.new(
|
36
|
+
REMOTE_CONFIGURATION = Value.new(5, :remote_configuration).freeze
|
36
37
|
|
37
38
|
# Configuration provided in Ruby code, in this same process
|
38
|
-
|
39
|
-
|
39
|
+
PROGRAMMATIC = Value.new(4, :programmatic).freeze
|
40
|
+
|
41
|
+
# Configuration provided by fleet managed stable config
|
42
|
+
FLEET_STABLE = Value.new(3, :fleet_stable).freeze
|
43
|
+
|
44
|
+
# Configuration provided via environment variable
|
45
|
+
ENVIRONMENT = Value.new(2, :environment).freeze
|
46
|
+
|
47
|
+
# Configuration provided by local stable config file
|
48
|
+
LOCAL_STABLE = Value.new(1, :local_stable).freeze
|
40
49
|
|
41
50
|
# Configuration that comes from default values
|
42
51
|
DEFAULT = Value.new(0, :default).freeze
|
43
52
|
|
44
53
|
# All precedences, sorted from highest to lowest
|
45
|
-
LIST = [REMOTE_CONFIGURATION, PROGRAMMATIC, DEFAULT].sort.reverse.freeze
|
54
|
+
LIST = [REMOTE_CONFIGURATION, PROGRAMMATIC, FLEET_STABLE, ENVIRONMENT, LOCAL_STABLE, DEFAULT].sort.reverse.freeze
|
46
55
|
end
|
47
56
|
|
48
57
|
def initialize(definition, context)
|
@@ -118,23 +127,29 @@ module Datadog
|
|
118
127
|
end
|
119
128
|
|
120
129
|
def get
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
130
|
+
unless @is_set
|
131
|
+
# Ensures that both the default value and the environment value are set.
|
132
|
+
# This approach handles scenarios where an environment value is unset
|
133
|
+
# by falling back to the default value consistently.
|
134
|
+
set_default_value
|
135
|
+
set_customer_stable_config_value
|
136
|
+
set_env_value
|
137
|
+
set_fleet_stable_config_value
|
125
138
|
end
|
139
|
+
|
140
|
+
@value
|
126
141
|
end
|
127
142
|
|
128
143
|
def reset
|
129
144
|
@value = if definition.resetter
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
145
|
+
# Don't change @is_set to false; custom resetters are
|
146
|
+
# responsible for changing @value back to a good state.
|
147
|
+
# Setting @is_set = false would cause a default to be applied.
|
148
|
+
context_exec(@value, &definition.resetter)
|
149
|
+
else
|
150
|
+
@is_set = false
|
151
|
+
nil
|
152
|
+
end
|
138
153
|
|
139
154
|
# Reset back to the lowest precedence, to allow all `set`s to succeed right after a reset.
|
140
155
|
@precedence_set = Precedence::DEFAULT
|
@@ -192,7 +207,7 @@ module Datadog
|
|
192
207
|
when :bool
|
193
208
|
string_value = value.strip
|
194
209
|
string_value = string_value.downcase
|
195
|
-
string_value == 'true' || string_value == '1'
|
210
|
+
string_value == 'true' || string_value == '1'
|
196
211
|
when :string, NilClass
|
197
212
|
value
|
198
213
|
else
|
@@ -212,20 +227,20 @@ module Datadog
|
|
212
227
|
|
213
228
|
unless valid_type
|
214
229
|
raise_error = if @definition.type_options[:nilable]
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
230
|
+
!value.is_a?(NilClass)
|
231
|
+
else
|
232
|
+
true
|
233
|
+
end
|
219
234
|
end
|
220
235
|
|
221
236
|
if raise_error
|
222
237
|
error_msg = if @definition.type_options[:nilable]
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
238
|
+
"The setting `#{@definition.name}` inside your app's `Datadog.configure` block expects a " \
|
239
|
+
"#{@definition.type} or `nil`, but a `#{value.class}` was provided (#{value.inspect})." \
|
240
|
+
else
|
241
|
+
"The setting `#{@definition.name}` inside your app's `Datadog.configure` block expects a " \
|
242
|
+
"#{@definition.type}, but a `#{value.class}` was provided (#{value.inspect})." \
|
243
|
+
end
|
229
244
|
|
230
245
|
error_msg = "#{error_msg} Please update your `configure` block. "
|
231
246
|
|
@@ -256,7 +271,8 @@ module Datadog
|
|
256
271
|
when NilClass
|
257
272
|
true # No validation is performed when option is typeless
|
258
273
|
else
|
259
|
-
raise
|
274
|
+
raise InvalidDefinitionError,
|
275
|
+
"The option #{@definition.name} is using an unsupported type option `#{@definition.type}`"
|
260
276
|
end
|
261
277
|
end
|
262
278
|
|
@@ -269,7 +285,7 @@ module Datadog
|
|
269
285
|
@resolved_env = resolved_env
|
270
286
|
# Store original value to ensure we can always safely call `#internal_set`
|
271
287
|
# when restoring a value from `@value_per_precedence`, and we are only running `definition.setter`
|
272
|
-
# on the original value, not on a
|
288
|
+
# on the original value, not on a value that has already been processed by `definition.setter`.
|
273
289
|
@value_per_precedence[precedence] = value
|
274
290
|
context_exec(v, old_value, precedence, &definition.after_set) if definition.after_set
|
275
291
|
end
|
@@ -283,39 +299,59 @@ module Datadog
|
|
283
299
|
@context.instance_eval(&block)
|
284
300
|
end
|
285
301
|
|
286
|
-
def
|
302
|
+
def set_default_value
|
303
|
+
set(default_value, precedence: Precedence::DEFAULT)
|
304
|
+
end
|
305
|
+
|
306
|
+
def set_env_value
|
307
|
+
value, resolved_env = get_value_and_resolved_env_from(ENV)
|
308
|
+
set(value, precedence: Precedence::ENVIRONMENT, resolved_env: resolved_env) unless value.nil?
|
309
|
+
end
|
310
|
+
|
311
|
+
def set_customer_stable_config_value
|
312
|
+
customer_config = StableConfig.configuration[:local]
|
313
|
+
return if customer_config.nil?
|
314
|
+
|
315
|
+
value, resolved_env = get_value_and_resolved_env_from(customer_config, source: 'local stable config')
|
316
|
+
set(value, precedence: Precedence::LOCAL_STABLE, resolved_env: resolved_env) unless value.nil?
|
317
|
+
end
|
318
|
+
|
319
|
+
def set_fleet_stable_config_value
|
320
|
+
fleet_config = StableConfig.configuration[:fleet]
|
321
|
+
return if fleet_config.nil?
|
322
|
+
|
323
|
+
value, resolved_env = get_value_and_resolved_env_from(fleet_config, source: 'fleet stable config')
|
324
|
+
set(value, precedence: Precedence::FLEET_STABLE, resolved_env: resolved_env) unless value.nil?
|
325
|
+
end
|
326
|
+
|
327
|
+
def get_value_and_resolved_env_from(env_vars, source: 'environment variable')
|
287
328
|
value = nil
|
288
|
-
precedence = nil
|
289
329
|
resolved_env = nil
|
290
330
|
|
291
331
|
if definition.env
|
292
332
|
Array(definition.env).each do |env|
|
293
|
-
next if
|
333
|
+
next if env_vars[env].nil?
|
294
334
|
|
295
335
|
resolved_env = env
|
296
|
-
value = coerce_env_variable(
|
297
|
-
precedence = Precedence::PROGRAMMATIC
|
336
|
+
value = coerce_env_variable(env_vars[env])
|
298
337
|
break
|
299
338
|
end
|
300
339
|
end
|
301
340
|
|
302
|
-
if value.nil? && definition.deprecated_env &&
|
341
|
+
if value.nil? && definition.deprecated_env && env_vars[definition.deprecated_env]
|
303
342
|
resolved_env = definition.deprecated_env
|
304
|
-
value = coerce_env_variable(
|
305
|
-
precedence = Precedence::PROGRAMMATIC
|
343
|
+
value = coerce_env_variable(env_vars[definition.deprecated_env])
|
306
344
|
|
307
345
|
Datadog::Core.log_deprecation do
|
308
|
-
"#{definition.deprecated_env}
|
346
|
+
"#{definition.deprecated_env} #{source} is deprecated, use #{definition.env} instead."
|
309
347
|
end
|
310
348
|
end
|
311
349
|
|
312
|
-
|
313
|
-
|
314
|
-
set(option_value, precedence: precedence || Precedence::DEFAULT, resolved_env: resolved_env)
|
350
|
+
[value, resolved_env]
|
315
351
|
rescue ArgumentError
|
316
352
|
raise ArgumentError,
|
317
|
-
"Expected
|
318
|
-
"but '#{
|
353
|
+
"Expected #{source} #{resolved_env} to be a #{@definition.type}, " \
|
354
|
+
"but '#{env_vars[resolved_env]}' was provided"
|
319
355
|
end
|
320
356
|
|
321
357
|
# Anchor object that represents a value that is not set.
|
@@ -71,11 +71,11 @@ module Datadog
|
|
71
71
|
validate_options!
|
72
72
|
end
|
73
73
|
|
74
|
-
def env(value)
|
74
|
+
def env(value) # standard:disable Style/TrivialAccessors
|
75
75
|
@env = value
|
76
76
|
end
|
77
77
|
|
78
|
-
def deprecated_env(value)
|
78
|
+
def deprecated_env(value) # standard:disable Style/TrivialAccessors
|
79
79
|
@deprecated_env = value
|
80
80
|
end
|
81
81
|
|
@@ -111,7 +111,7 @@ module Datadog
|
|
111
111
|
|
112
112
|
def type(value, nilable: false)
|
113
113
|
@type = value
|
114
|
-
@type_options = {
|
114
|
+
@type_options = {nilable: nilable}
|
115
115
|
|
116
116
|
value
|
117
117
|
end
|
@@ -156,7 +156,7 @@ module Datadog
|
|
156
156
|
if !@default.nil? && @default_proc
|
157
157
|
raise InvalidOptionError,
|
158
158
|
'Using `default` and `default_proc` is not allowed. Please use one or the other.' \
|
159
|
-
'If you want to store a block as the default value use `default_proc`'\
|
159
|
+
'If you want to store a block as the default value use `default_proc`' \
|
160
160
|
' otherwise use `default`'
|
161
161
|
end
|
162
162
|
end
|
@@ -18,7 +18,7 @@ module Datadog
|
|
18
18
|
module ClassMethods
|
19
19
|
def options
|
20
20
|
# Allows for class inheritance of option definitions
|
21
|
-
@options ||= superclass <= Options ? superclass.options.dup : {}
|
21
|
+
@options ||= (superclass <= Options) ? superclass.options.dup : {}
|
22
22
|
end
|
23
23
|
|
24
24
|
protected
|
@@ -18,7 +18,7 @@ module Datadog
|
|
18
18
|
module Configuration
|
19
19
|
# Global configuration settings for the Datadog library.
|
20
20
|
# @public_api
|
21
|
-
#
|
21
|
+
# standard:disable Metrics/BlockLength
|
22
22
|
class Settings
|
23
23
|
include Base
|
24
24
|
|
@@ -123,7 +123,7 @@ module Datadog
|
|
123
123
|
# @return [Boolean]
|
124
124
|
option :debug do |o|
|
125
125
|
o.env [Datadog::Core::Configuration::Ext::Diagnostics::ENV_DEBUG_ENABLED,
|
126
|
-
|
126
|
+
Datadog::Core::Configuration::Ext::Diagnostics::ENV_OTEL_LOG_LEVEL]
|
127
127
|
o.default false
|
128
128
|
o.type :bool
|
129
129
|
o.env_parser do |value|
|
@@ -137,7 +137,7 @@ module Datadog
|
|
137
137
|
o.after_set do |enabled|
|
138
138
|
# Enable rich debug print statements.
|
139
139
|
# We do not need to unnecessarily load 'pp' unless in debugging mode.
|
140
|
-
require 'pp' if enabled
|
140
|
+
require 'pp' if enabled # standard:disable Lint/RedundantRequireStatement
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
@@ -454,7 +454,7 @@ module Datadog
|
|
454
454
|
o.after_set do |_, _, precedence|
|
455
455
|
unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
|
456
456
|
Core.log_deprecation(key: :experimental_crash_tracking_enabled) do
|
457
|
-
'The profiling.advanced.experimental_crash_tracking_enabled setting has been deprecated for removal '\
|
457
|
+
'The profiling.advanced.experimental_crash_tracking_enabled setting has been deprecated for removal ' \
|
458
458
|
'and no longer does anything. Please remove it from your Datadog.configure block.'
|
459
459
|
end
|
460
460
|
end
|
@@ -641,11 +641,11 @@ module Datadog
|
|
641
641
|
val ||= ''
|
642
642
|
# maps OpenTelemetry semantic attributes to Datadog tags
|
643
643
|
key = case key.downcase
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
644
|
+
when 'deployment.environment' then 'env'
|
645
|
+
when 'service.version' then 'version'
|
646
|
+
when 'service.name' then 'service'
|
647
|
+
else key
|
648
|
+
end
|
649
649
|
result[key] = val unless key.empty?
|
650
650
|
end
|
651
651
|
end
|
@@ -888,6 +888,16 @@ module Datadog
|
|
888
888
|
o.env Core::Telemetry::Ext::ENV_LOG_COLLECTION
|
889
889
|
o.default true
|
890
890
|
end
|
891
|
+
|
892
|
+
# For internal use only.
|
893
|
+
# Enables telemetry debugging through the Datadog platform.
|
894
|
+
#
|
895
|
+
# @default `false`.
|
896
|
+
# @return [Boolean]
|
897
|
+
option :debug do |o|
|
898
|
+
o.type :bool
|
899
|
+
o.default false
|
900
|
+
end
|
891
901
|
end
|
892
902
|
|
893
903
|
# Remote configuration
|
@@ -985,7 +995,7 @@ module Datadog
|
|
985
995
|
# Keep this extension here for now to keep things working.
|
986
996
|
extend Datadog::Tracing::Configuration::Settings
|
987
997
|
end
|
988
|
-
#
|
998
|
+
# standard:enable Metrics/BlockLength
|
989
999
|
end
|
990
1000
|
end
|
991
1001
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module Core
|
5
|
+
module Configuration
|
6
|
+
# Import config from config files (fleet automation)
|
7
|
+
module StableConfig
|
8
|
+
def self.extract_configuration
|
9
|
+
if (libdatadog_api_failure = Datadog::Core::LIBDATADOG_API_FAILURE)
|
10
|
+
Datadog.config_init_logger.debug("Cannot enable stable config: #{libdatadog_api_failure}")
|
11
|
+
return {}
|
12
|
+
end
|
13
|
+
Configurator.new.get
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.configuration
|
17
|
+
# @configuration ||= StableConfig.extract_configuration # TODO: After libdatadog 17.1 release, uncomment this line
|
18
|
+
@configuration ||= {} # TODO: After libdatadog 17.1 release, delete this line
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -172,6 +172,10 @@ module Datadog
|
|
172
172
|
end
|
173
173
|
end
|
174
174
|
|
175
|
+
def config_init_logger
|
176
|
+
configuration? ? logger : logger_without_configuration
|
177
|
+
end
|
178
|
+
|
175
179
|
# Gracefully shuts down all components.
|
176
180
|
#
|
177
181
|
# Components will still respond to method calls as usual,
|
@@ -231,19 +235,21 @@ module Datadog
|
|
231
235
|
end
|
232
236
|
|
233
237
|
COMPONENTS_WRITE_LOCK.synchronize do
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
nil
|
243
|
-
end
|
238
|
+
yield write_components
|
239
|
+
rescue ThreadError => e
|
240
|
+
logger_without_components.error(
|
241
|
+
'Detected deadlock during datadog initialization. ' \
|
242
|
+
'Please report this at https://github.com/datadog/dd-trace-rb/blob/master/CONTRIBUTING.md#found-a-bug' \
|
243
|
+
"\n\tSource:\n\t#{Array(e.backtrace).join("\n\t")}"
|
244
|
+
)
|
245
|
+
nil
|
244
246
|
end
|
245
247
|
end
|
246
248
|
|
249
|
+
def configuration?
|
250
|
+
(defined?(@configuration) && @configuration) != nil
|
251
|
+
end
|
252
|
+
|
247
253
|
def components?
|
248
254
|
# This does not need to grab the COMPONENTS_READ_LOCK because it's not returning the components
|
249
255
|
(defined?(@components) && @components) != nil
|
@@ -259,12 +265,14 @@ module Datadog
|
|
259
265
|
components = Components.new(settings)
|
260
266
|
|
261
267
|
# Carry over state from existing components to the new ones.
|
262
|
-
# Currently
|
263
|
-
#
|
264
|
-
#
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
+
# Currently:
|
269
|
+
# 1. If we already started the remote component (which
|
270
|
+
# happens after a request goes through installed Rack middleware),
|
271
|
+
# we will start the new remote component as well.
|
272
|
+
# 2. If telemetry has been enabled and is enabled in the new
|
273
|
+
# component tree, we send AppConfigurationChange event instead
|
274
|
+
# of AppStarted event.
|
275
|
+
old_state = old.state
|
268
276
|
|
269
277
|
old.shutdown!(components)
|
270
278
|
components.startup!(settings, old_state: old_state)
|
@@ -274,6 +282,7 @@ module Datadog
|
|
274
282
|
def logger_without_components
|
275
283
|
# Use default logger without initializing components.
|
276
284
|
# This enables logging during initialization, otherwise we'd run into deadlocks.
|
285
|
+
|
277
286
|
@temp_logger ||= begin
|
278
287
|
logger = configuration.logger.instance || Core::Logger.new($stdout)
|
279
288
|
logger.level = configuration.diagnostics.debug ? ::Logger::DEBUG : configuration.logger.level
|
@@ -281,6 +290,21 @@ module Datadog
|
|
281
290
|
end
|
282
291
|
end
|
283
292
|
|
293
|
+
def logger_without_configuration
|
294
|
+
# There's rare cases where we need to use logger during configuration initialization,
|
295
|
+
# such as reading stable config. In this case we cannot access configuration.
|
296
|
+
|
297
|
+
@temp_config_logger ||= begin
|
298
|
+
debug_env_value = ENV[Ext::Diagnostics::ENV_DEBUG_ENABLED]&.strip&.downcase
|
299
|
+
debug_value = debug_env_value == 'true' || debug_env_value == '1'
|
300
|
+
|
301
|
+
logger = Core::Logger.new($stdout)
|
302
|
+
# We cannot access config and the default level is INFO, so we need to set the level manually
|
303
|
+
logger.level = debug_value ? ::Logger::DEBUG : ::Logger::INFO
|
304
|
+
logger
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
284
308
|
# Called from our at_exit hook whenever there was a pending Interrupt exception (e.g. typically due to ctrl+c)
|
285
309
|
# to print a nice message whenever we're taking a bit longer than usual to finish the process.
|
286
310
|
def handle_interrupt_shutdown!
|