datadog 2.21.0 → 2.23.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 +106 -2
- data/ext/LIBDATADOG_DEVELOPMENT.md +3 -0
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
- data/ext/datadog_profiling_native_extension/collectors_stack.c +4 -0
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +1 -1
- data/ext/datadog_profiling_native_extension/extconf.rb +6 -4
- data/ext/datadog_profiling_native_extension/heap_recorder.c +1 -1
- data/ext/libdatadog_api/datadog_ruby_common.h +1 -1
- data/ext/libdatadog_api/ddsketch.c +106 -0
- data/ext/libdatadog_api/feature_flags.c +554 -0
- data/ext/libdatadog_api/feature_flags.h +5 -0
- data/ext/libdatadog_api/init.c +5 -0
- data/ext/libdatadog_api/library_config.c +34 -25
- data/ext/libdatadog_api/process_discovery.c +19 -13
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/appsec/api_security/endpoint_collection/grape_route_serializer.rb +26 -0
- data/lib/datadog/appsec/api_security/endpoint_collection/rails_collector.rb +59 -0
- data/lib/datadog/appsec/api_security/endpoint_collection/rails_route_serializer.rb +29 -0
- data/lib/datadog/appsec/api_security/endpoint_collection/sinatra_route_serializer.rb +26 -0
- data/lib/datadog/appsec/api_security/endpoint_collection.rb +10 -0
- data/lib/datadog/appsec/api_security/route_extractor.rb +23 -6
- data/lib/datadog/appsec/api_security/sampler.rb +7 -4
- data/lib/datadog/appsec/assets/blocked.html +8 -0
- data/lib/datadog/appsec/assets/blocked.json +1 -1
- data/lib/datadog/appsec/assets/blocked.text +3 -1
- data/lib/datadog/appsec/assets/waf_rules/README.md +30 -36
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +359 -4
- data/lib/datadog/appsec/assets/waf_rules/strict.json +43 -2
- data/lib/datadog/appsec/assets.rb +1 -1
- data/lib/datadog/appsec/compressed_json.rb +1 -1
- data/lib/datadog/appsec/configuration/settings.rb +9 -0
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +3 -1
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +3 -2
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +3 -1
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +3 -1
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +9 -4
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +5 -1
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +7 -2
- data/lib/datadog/appsec/contrib/rails/patcher.rb +30 -0
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +3 -1
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +10 -4
- data/lib/datadog/appsec/event.rb +12 -14
- data/lib/datadog/appsec/metrics/collector.rb +19 -3
- data/lib/datadog/appsec/metrics/telemetry_exporter.rb +2 -1
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +4 -4
- data/lib/datadog/appsec/remote.rb +29 -13
- data/lib/datadog/appsec/response.rb +18 -4
- data/lib/datadog/appsec/security_engine/result.rb +28 -9
- data/lib/datadog/appsec/security_engine/runner.rb +17 -7
- data/lib/datadog/appsec/security_event.rb +5 -7
- data/lib/datadog/core/configuration/components.rb +44 -9
- data/lib/datadog/core/configuration/config_helper.rb +1 -1
- data/lib/datadog/core/configuration/settings.rb +14 -0
- data/lib/datadog/core/configuration/stable_config.rb +10 -0
- data/lib/datadog/core/configuration/supported_configurations.rb +330 -299
- data/lib/datadog/core/configuration.rb +1 -1
- data/lib/datadog/core/ddsketch.rb +19 -0
- data/lib/datadog/core/environment/ext.rb +6 -0
- data/lib/datadog/core/environment/process.rb +79 -0
- data/lib/datadog/core/environment/yjit.rb +2 -1
- data/lib/datadog/core/feature_flags.rb +61 -0
- data/lib/datadog/core/pin.rb +4 -8
- data/lib/datadog/core/process_discovery.rb +4 -2
- data/lib/datadog/core/remote/client/capabilities.rb +7 -0
- data/lib/datadog/core/remote/component.rb +4 -6
- data/lib/datadog/core/remote/transport/config.rb +2 -10
- data/lib/datadog/core/remote/transport/http/config.rb +9 -9
- data/lib/datadog/core/remote/transport/http/negotiation.rb +17 -8
- data/lib/datadog/core/remote/transport/http.rb +2 -0
- data/lib/datadog/core/remote/transport/negotiation.rb +2 -18
- data/lib/datadog/core/remote/worker.rb +25 -37
- data/lib/datadog/core/tag_builder.rb +0 -4
- data/lib/datadog/core/tag_normalizer.rb +84 -0
- data/lib/datadog/core/telemetry/component.rb +18 -3
- data/lib/datadog/core/telemetry/emitter.rb +6 -6
- data/lib/datadog/core/telemetry/event/app_endpoints_loaded.rb +30 -0
- data/lib/datadog/core/telemetry/event/app_started.rb +52 -49
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +1 -1
- data/lib/datadog/core/telemetry/event.rb +1 -0
- data/lib/datadog/core/telemetry/logger.rb +2 -2
- data/lib/datadog/core/telemetry/logging.rb +2 -8
- data/lib/datadog/core/telemetry/transport/http/telemetry.rb +5 -6
- data/lib/datadog/core/telemetry/transport/telemetry.rb +1 -2
- data/lib/datadog/core/transport/http/client.rb +69 -0
- data/lib/datadog/core/transport/response.rb +4 -1
- data/lib/datadog/core/utils/array.rb +29 -0
- data/lib/datadog/{appsec/api_security → core/utils}/lru_cache.rb +10 -21
- data/lib/datadog/core/utils/network.rb +22 -1
- data/lib/datadog/core/utils/only_once_successful.rb +6 -2
- data/lib/datadog/core/utils.rb +2 -0
- data/lib/datadog/data_streams/configuration/settings.rb +49 -0
- data/lib/datadog/data_streams/configuration.rb +11 -0
- data/lib/datadog/data_streams/ext.rb +11 -0
- data/lib/datadog/data_streams/extensions.rb +16 -0
- data/lib/datadog/data_streams/pathway_context.rb +169 -0
- data/lib/datadog/data_streams/processor.rb +509 -0
- data/lib/datadog/data_streams/transport/http/api.rb +33 -0
- data/lib/datadog/data_streams/transport/http/client.rb +21 -0
- data/lib/datadog/data_streams/transport/http/stats.rb +87 -0
- data/lib/datadog/data_streams/transport/http.rb +41 -0
- data/lib/datadog/data_streams/transport/stats.rb +60 -0
- data/lib/datadog/data_streams.rb +100 -0
- data/lib/datadog/di/boot.rb +1 -0
- data/lib/datadog/di/component.rb +14 -16
- data/lib/datadog/di/context.rb +70 -0
- data/lib/datadog/di/el/compiler.rb +164 -0
- data/lib/datadog/di/el/evaluator.rb +159 -0
- data/lib/datadog/di/el/expression.rb +42 -0
- data/lib/datadog/di/el.rb +5 -0
- data/lib/datadog/di/error.rb +29 -0
- data/lib/datadog/di/instrumenter.rb +163 -48
- data/lib/datadog/di/probe.rb +55 -15
- data/lib/datadog/di/probe_builder.rb +39 -1
- data/lib/datadog/di/probe_manager.rb +13 -4
- data/lib/datadog/di/probe_notification_builder.rb +105 -67
- data/lib/datadog/di/proc_responder.rb +32 -0
- data/lib/datadog/di/serializer.rb +151 -7
- data/lib/datadog/di/transport/diagnostics.rb +2 -2
- data/lib/datadog/di/transport/http/diagnostics.rb +2 -4
- data/lib/datadog/di/transport/http/input.rb +2 -4
- data/lib/datadog/di/transport/http.rb +6 -2
- data/lib/datadog/di/transport/input.rb +64 -4
- data/lib/datadog/open_feature/component.rb +60 -0
- data/lib/datadog/open_feature/configuration.rb +27 -0
- data/lib/datadog/open_feature/evaluation_engine.rb +69 -0
- data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
- data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
- data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
- data/lib/datadog/open_feature/exposures/event.rb +60 -0
- data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
- data/lib/datadog/open_feature/exposures/worker.rb +116 -0
- data/lib/datadog/open_feature/ext.rb +14 -0
- data/lib/datadog/open_feature/native_evaluator.rb +38 -0
- data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
- data/lib/datadog/open_feature/provider.rb +141 -0
- data/lib/datadog/open_feature/remote.rb +74 -0
- data/lib/datadog/open_feature/resolution_details.rb +35 -0
- data/lib/datadog/open_feature/transport.rb +72 -0
- data/lib/datadog/open_feature.rb +19 -0
- data/lib/datadog/opentelemetry/configuration/settings.rb +159 -0
- data/lib/datadog/opentelemetry/metrics.rb +110 -0
- data/lib/datadog/opentelemetry/sdk/configurator.rb +25 -1
- data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +38 -0
- data/lib/datadog/opentelemetry.rb +3 -0
- data/lib/datadog/profiling/collectors/code_provenance.rb +15 -6
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +1 -1
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +1 -1
- data/lib/datadog/profiling/profiler.rb +4 -0
- data/lib/datadog/profiling/tag_builder.rb +36 -3
- data/lib/datadog/profiling.rb +1 -2
- data/lib/datadog/single_step_instrument.rb +1 -1
- data/lib/datadog/tracing/component.rb +6 -17
- data/lib/datadog/tracing/configuration/dynamic.rb +2 -2
- data/lib/datadog/tracing/configuration/ext.rb +9 -0
- data/lib/datadog/tracing/configuration/settings.rb +77 -3
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +4 -4
- data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -2
- data/lib/datadog/tracing/contrib/active_job/log_injection.rb +21 -7
- data/lib/datadog/tracing/contrib/active_job/patcher.rb +5 -1
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +4 -2
- data/lib/datadog/tracing/contrib/component.rb +2 -2
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -1
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +11 -3
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +11 -7
- data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +7 -3
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +7 -0
- data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +74 -44
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +11 -3
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +11 -3
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +11 -3
- data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +66 -0
- data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +66 -0
- data/lib/datadog/tracing/contrib/kafka/patcher.rb +14 -0
- data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
- data/lib/datadog/tracing/contrib/karafka/monitor.rb +11 -0
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +32 -0
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +59 -27
- data/lib/datadog/tracing/contrib/rack/route_inference.rb +53 -0
- data/lib/datadog/tracing/contrib/rails/middlewares.rb +2 -2
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +4 -1
- data/lib/datadog/tracing/contrib/roda/instrumentation.rb +3 -1
- data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -1
- data/lib/datadog/tracing/contrib/status_range_matcher.rb +7 -0
- data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +27 -0
- data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +48 -0
- data/lib/datadog/tracing/contrib/waterdrop/ext.rb +17 -0
- data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
- data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
- data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +46 -0
- data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
- data/lib/datadog/tracing/contrib/waterdrop.rb +37 -0
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing/metadata/ext.rb +9 -1
- data/lib/datadog/tracing/transport/http/client.rb +12 -26
- data/lib/datadog/tracing/transport/trace_formatter.rb +11 -0
- data/lib/datadog/tracing/transport/traces.rb +3 -5
- data/lib/datadog/version.rb +2 -2
- data/lib/datadog.rb +2 -0
- metadata +92 -16
- data/ext/libdatadog_api/macos_development.md +0 -26
- data/lib/datadog/core/remote/transport/http/client.rb +0 -49
- data/lib/datadog/core/telemetry/transport/http/client.rb +0 -49
- data/lib/datadog/di/transport/http/client.rb +0 -47
|
@@ -19,6 +19,8 @@ module Datadog
|
|
|
19
19
|
#
|
|
20
20
|
# @api private
|
|
21
21
|
class Component
|
|
22
|
+
ENDPOINT_COLLECTION_MESSAGE_LIMIT = 300
|
|
23
|
+
|
|
22
24
|
attr_reader :enabled, :logger, :transport, :worker
|
|
23
25
|
|
|
24
26
|
include Core::Utils::Forking
|
|
@@ -107,13 +109,17 @@ module Datadog
|
|
|
107
109
|
@worker&.enabled = false
|
|
108
110
|
end
|
|
109
111
|
|
|
110
|
-
def start(initial_event_is_change = false)
|
|
112
|
+
def start(initial_event_is_change = false, components:)
|
|
111
113
|
return if !@enabled
|
|
112
114
|
|
|
113
115
|
initial_event = if initial_event_is_change
|
|
114
|
-
Event::SynthAppClientConfigurationChange.new(
|
|
116
|
+
Event::SynthAppClientConfigurationChange.new(
|
|
117
|
+
components: components,
|
|
118
|
+
)
|
|
115
119
|
else
|
|
116
|
-
Event::AppStarted.new(
|
|
120
|
+
Event::AppStarted.new(
|
|
121
|
+
components: components,
|
|
122
|
+
)
|
|
117
123
|
end
|
|
118
124
|
|
|
119
125
|
@worker.start(initial_event)
|
|
@@ -165,6 +171,15 @@ module Datadog
|
|
|
165
171
|
@worker.enqueue(Event::AppClientConfigurationChange.new(changes, 'remote_config'))
|
|
166
172
|
end
|
|
167
173
|
|
|
174
|
+
# Report application endpoints
|
|
175
|
+
def app_endpoints_loaded(endpoints, page_size: ENDPOINT_COLLECTION_MESSAGE_LIMIT)
|
|
176
|
+
return if !@enabled || forked?
|
|
177
|
+
|
|
178
|
+
endpoints.each_slice(page_size).with_index do |endpoints_slice, i|
|
|
179
|
+
@worker.enqueue(Event::AppEndpointsLoaded.new(endpoints_slice, is_first: i.zero?))
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
168
183
|
# Increments a count metric.
|
|
169
184
|
def inc(namespace, metric_name, value, tags: {}, common: true)
|
|
170
185
|
@metrics_manager.inc(namespace, metric_name, value, tags: tags, common: common)
|
|
@@ -31,15 +31,15 @@ module Datadog
|
|
|
31
31
|
seq_id = self.class.sequence.next
|
|
32
32
|
payload = Request.build_payload(event, seq_id, debug: debug?)
|
|
33
33
|
res = @transport.send_telemetry(request_type: event.type, payload: payload)
|
|
34
|
-
|
|
34
|
+
if res.ok?
|
|
35
|
+
logger.debug { "Telemetry sent for event `#{event.type}`" }
|
|
36
|
+
else
|
|
37
|
+
logger.debug { "Failed to send telemetry for event `#{event.type}`: #{res.inspect}" }
|
|
38
|
+
end
|
|
35
39
|
res
|
|
36
40
|
rescue => e
|
|
37
41
|
logger.debug {
|
|
38
|
-
"Unable to send telemetry request for event `#{
|
|
39
|
-
event.type
|
|
40
|
-
rescue
|
|
41
|
-
"unknown"
|
|
42
|
-
end}`: #{e}"
|
|
42
|
+
"Unable to send telemetry request for event `#{event.respond_to?(:type) ? event.type : event.to_s}`: #{e.class}: #{e}"
|
|
43
43
|
}
|
|
44
44
|
Core::Transport::InternalErrorResponse.new(e)
|
|
45
45
|
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base'
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module Core
|
|
7
|
+
module Telemetry
|
|
8
|
+
module Event
|
|
9
|
+
# Telemetry event class for sending 'app-endpoints' payload
|
|
10
|
+
class AppEndpointsLoaded < Base
|
|
11
|
+
def initialize(endpoints, is_first:)
|
|
12
|
+
@endpoints = endpoints
|
|
13
|
+
@is_first = !!is_first
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def type
|
|
17
|
+
'app-endpoints'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def payload
|
|
21
|
+
{
|
|
22
|
+
is_first: @is_first,
|
|
23
|
+
endpoints: @endpoints
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -8,8 +8,12 @@ module Datadog
|
|
|
8
8
|
module Event
|
|
9
9
|
# Telemetry class for the 'app-started' event
|
|
10
10
|
class AppStarted < Base
|
|
11
|
-
def initialize(
|
|
12
|
-
|
|
11
|
+
def initialize(components:)
|
|
12
|
+
# To not hold a reference to the component tree, generate
|
|
13
|
+
# the event payload here in the constructor.
|
|
14
|
+
@configuration = configuration(components.settings, components.agent_settings)
|
|
15
|
+
@install_signature = install_signature(components.settings)
|
|
16
|
+
@products = products(components)
|
|
13
17
|
end
|
|
14
18
|
|
|
15
19
|
def type
|
|
@@ -18,9 +22,9 @@ module Datadog
|
|
|
18
22
|
|
|
19
23
|
def payload
|
|
20
24
|
{
|
|
21
|
-
products: products,
|
|
22
|
-
configuration: configuration,
|
|
23
|
-
install_signature: install_signature,
|
|
25
|
+
products: @products,
|
|
26
|
+
configuration: @configuration,
|
|
27
|
+
install_signature: @install_signature,
|
|
24
28
|
# DEV: Not implemented yet
|
|
25
29
|
# error: error, # Start-up errors
|
|
26
30
|
}
|
|
@@ -28,17 +32,18 @@ module Datadog
|
|
|
28
32
|
|
|
29
33
|
private
|
|
30
34
|
|
|
31
|
-
def products
|
|
35
|
+
def products(components)
|
|
32
36
|
# @type var products: Hash[Symbol, Hash[Symbol, Hash[Symbol, String | Integer] | bool | nil]]
|
|
33
37
|
products = {
|
|
34
38
|
appsec: {
|
|
35
|
-
|
|
39
|
+
# TODO take appsec status out of component tree?
|
|
40
|
+
enabled: components.settings.appsec.enabled,
|
|
36
41
|
},
|
|
37
42
|
profiler: {
|
|
38
|
-
enabled:
|
|
43
|
+
enabled: !!components.profiler&.enabled?,
|
|
39
44
|
},
|
|
40
45
|
dynamic_instrumentation: {
|
|
41
|
-
enabled:
|
|
46
|
+
enabled: !!components.dynamic_instrumentation,
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
49
|
|
|
@@ -73,12 +78,11 @@ module Datadog
|
|
|
73
78
|
|
|
74
79
|
# standard:disable Metrics/AbcSize
|
|
75
80
|
# standard:disable Metrics/MethodLength
|
|
76
|
-
def configuration
|
|
77
|
-
config = Datadog.configuration
|
|
81
|
+
def configuration(settings, agent_settings)
|
|
78
82
|
seq_id = Event.configuration_sequence.next
|
|
79
83
|
|
|
80
84
|
# tracing.writer_options.buffer_size and tracing.writer_options.flush_interval have the same origin.
|
|
81
|
-
writer_option_origin = get_telemetry_origin(
|
|
85
|
+
writer_option_origin = get_telemetry_origin(settings, 'tracing.writer_options')
|
|
82
86
|
|
|
83
87
|
list = [
|
|
84
88
|
# Only set using env var as of June 2025
|
|
@@ -100,59 +104,59 @@ module Datadog
|
|
|
100
104
|
),
|
|
101
105
|
|
|
102
106
|
# Mix of env var, programmatic and default config, so we use unknown
|
|
103
|
-
conf_value('DD_AGENT_TRANSPORT', agent_transport, seq_id, 'unknown'), # rubocop:disable CustomCops/EnvStringValidationCop
|
|
107
|
+
conf_value('DD_AGENT_TRANSPORT', agent_transport(agent_settings), seq_id, 'unknown'), # rubocop:disable CustomCops/EnvStringValidationCop
|
|
104
108
|
|
|
105
109
|
# writer_options is defined as an option that has a Hash value.
|
|
106
110
|
conf_value(
|
|
107
111
|
'tracing.writer_options.buffer_size',
|
|
108
|
-
to_value(
|
|
112
|
+
to_value(settings.tracing.writer_options[:buffer_size]),
|
|
109
113
|
seq_id,
|
|
110
114
|
writer_option_origin
|
|
111
115
|
),
|
|
112
116
|
conf_value(
|
|
113
117
|
'tracing.writer_options.flush_interval',
|
|
114
|
-
to_value(
|
|
118
|
+
to_value(settings.tracing.writer_options[:flush_interval]),
|
|
115
119
|
seq_id,
|
|
116
120
|
writer_option_origin
|
|
117
121
|
),
|
|
118
122
|
|
|
119
|
-
conf_value('DD_AGENT_HOST',
|
|
123
|
+
conf_value('DD_AGENT_HOST', settings.agent.host, seq_id, get_telemetry_origin(settings, 'agent.host')),
|
|
120
124
|
conf_value(
|
|
121
125
|
'DD_TRACE_SAMPLE_RATE',
|
|
122
|
-
to_value(
|
|
126
|
+
to_value(settings.tracing.sampling.default_rate),
|
|
123
127
|
seq_id,
|
|
124
|
-
get_telemetry_origin(
|
|
128
|
+
get_telemetry_origin(settings, 'tracing.sampling.default_rate')
|
|
125
129
|
),
|
|
126
130
|
conf_value(
|
|
127
131
|
'DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED',
|
|
128
|
-
|
|
132
|
+
settings.tracing.contrib.global_default_service_name.enabled,
|
|
129
133
|
seq_id,
|
|
130
|
-
get_telemetry_origin(
|
|
134
|
+
get_telemetry_origin(settings, 'tracing.contrib.global_default_service_name.enabled')
|
|
131
135
|
),
|
|
132
136
|
conf_value(
|
|
133
137
|
'DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED',
|
|
134
|
-
|
|
138
|
+
settings.tracing.contrib.peer_service_defaults,
|
|
135
139
|
seq_id,
|
|
136
|
-
get_telemetry_origin(
|
|
140
|
+
get_telemetry_origin(settings, 'tracing.contrib.peer_service_defaults')
|
|
137
141
|
),
|
|
138
142
|
conf_value(
|
|
139
143
|
'DD_TRACE_DEBUG',
|
|
140
|
-
|
|
144
|
+
settings.diagnostics.debug,
|
|
141
145
|
seq_id,
|
|
142
|
-
get_telemetry_origin(
|
|
146
|
+
get_telemetry_origin(settings, 'diagnostics.debug')
|
|
143
147
|
)
|
|
144
148
|
]
|
|
145
149
|
|
|
146
150
|
peer_service_mapping_str = ''
|
|
147
|
-
unless
|
|
148
|
-
peer_service_mapping =
|
|
151
|
+
unless settings.tracing.contrib.peer_service_mapping.empty?
|
|
152
|
+
peer_service_mapping = settings.tracing.contrib.peer_service_mapping
|
|
149
153
|
peer_service_mapping_str = peer_service_mapping.map { |key, value| "#{key}:#{value}" }.join(',')
|
|
150
154
|
end
|
|
151
155
|
list << conf_value(
|
|
152
156
|
'DD_TRACE_PEER_SERVICE_MAPPING',
|
|
153
157
|
peer_service_mapping_str,
|
|
154
158
|
seq_id,
|
|
155
|
-
get_telemetry_origin(
|
|
159
|
+
get_telemetry_origin(settings, 'tracing.contrib.peer_service_mapping')
|
|
156
160
|
)
|
|
157
161
|
|
|
158
162
|
# Whitelist of configuration options to send in additional payload object
|
|
@@ -160,9 +164,9 @@ module Datadog
|
|
|
160
164
|
split_option = option_path.split('.')
|
|
161
165
|
list << conf_value(
|
|
162
166
|
option_path,
|
|
163
|
-
to_value(
|
|
167
|
+
to_value(settings.dig(*split_option)),
|
|
164
168
|
seq_id,
|
|
165
|
-
get_telemetry_origin(
|
|
169
|
+
get_telemetry_origin(settings, option_path)
|
|
166
170
|
)
|
|
167
171
|
end
|
|
168
172
|
|
|
@@ -181,34 +185,34 @@ module Datadog
|
|
|
181
185
|
)
|
|
182
186
|
|
|
183
187
|
# Add some more custom additional payload values here
|
|
184
|
-
if
|
|
188
|
+
if settings.logger.instance
|
|
185
189
|
list << conf_value(
|
|
186
190
|
'logger.instance',
|
|
187
|
-
|
|
191
|
+
settings.logger.instance.class.to_s,
|
|
188
192
|
seq_id,
|
|
189
|
-
get_telemetry_origin(
|
|
193
|
+
get_telemetry_origin(settings, 'logger.instance')
|
|
190
194
|
)
|
|
191
195
|
end
|
|
192
|
-
if
|
|
196
|
+
if settings.respond_to?('appsec')
|
|
193
197
|
list << conf_value(
|
|
194
198
|
'appsec.enabled',
|
|
195
|
-
|
|
199
|
+
settings.dig('appsec', 'enabled'),
|
|
196
200
|
seq_id,
|
|
197
|
-
get_telemetry_origin(
|
|
201
|
+
get_telemetry_origin(settings, 'appsec.enabled')
|
|
198
202
|
)
|
|
199
203
|
list << conf_value(
|
|
200
204
|
'appsec.sca_enabled',
|
|
201
|
-
|
|
205
|
+
settings.dig('appsec', 'sca_enabled'),
|
|
202
206
|
seq_id,
|
|
203
|
-
get_telemetry_origin(
|
|
207
|
+
get_telemetry_origin(settings, 'appsec.sca_enabled')
|
|
204
208
|
)
|
|
205
209
|
end
|
|
206
|
-
if
|
|
210
|
+
if settings.respond_to?('ci')
|
|
207
211
|
list << conf_value(
|
|
208
212
|
'ci.enabled',
|
|
209
|
-
|
|
213
|
+
settings.dig('ci', 'enabled'),
|
|
210
214
|
seq_id,
|
|
211
|
-
get_telemetry_origin(
|
|
215
|
+
get_telemetry_origin(settings, 'ci.enabled')
|
|
212
216
|
)
|
|
213
217
|
end
|
|
214
218
|
|
|
@@ -218,8 +222,8 @@ module Datadog
|
|
|
218
222
|
# standard:enable Metrics/AbcSize
|
|
219
223
|
# standard:enable Metrics/MethodLength
|
|
220
224
|
|
|
221
|
-
def agent_transport
|
|
222
|
-
adapter =
|
|
225
|
+
def agent_transport(agent_settings)
|
|
226
|
+
adapter = agent_settings.adapter
|
|
223
227
|
if adapter == Datadog::Core::Transport::Ext::UnixSocket::ADAPTER
|
|
224
228
|
'UDS'
|
|
225
229
|
else
|
|
@@ -260,23 +264,22 @@ module Datadog
|
|
|
260
264
|
end
|
|
261
265
|
end
|
|
262
266
|
|
|
263
|
-
def install_signature
|
|
264
|
-
config = Datadog.configuration
|
|
267
|
+
def install_signature(settings)
|
|
265
268
|
{
|
|
266
|
-
install_id:
|
|
267
|
-
install_type:
|
|
268
|
-
install_time:
|
|
269
|
+
install_id: settings.dig('telemetry', 'install_id'),
|
|
270
|
+
install_type: settings.dig('telemetry', 'install_type'),
|
|
271
|
+
install_time: settings.dig('telemetry', 'install_time'),
|
|
269
272
|
}
|
|
270
273
|
end
|
|
271
274
|
|
|
272
|
-
def get_telemetry_origin(
|
|
275
|
+
def get_telemetry_origin(settings, config_path)
|
|
273
276
|
split_option = config_path.split('.')
|
|
274
277
|
option_name = split_option.pop
|
|
275
278
|
return 'unknown' if option_name.nil?
|
|
276
279
|
|
|
277
280
|
# @type var parent_setting: Core::Configuration::Options
|
|
278
281
|
# @type var option: Core::Configuration::Option
|
|
279
|
-
parent_setting =
|
|
282
|
+
parent_setting = settings.dig(*split_option)
|
|
280
283
|
option = parent_setting.send(:resolve_option, option_name.to_sym)
|
|
281
284
|
option.precedence_set&.origin || 'unknown'
|
|
282
285
|
end
|
|
@@ -26,6 +26,7 @@ require_relative 'event/base'
|
|
|
26
26
|
require_relative 'event/app_client_configuration_change'
|
|
27
27
|
require_relative 'event/app_closing'
|
|
28
28
|
require_relative 'event/app_dependencies_loaded'
|
|
29
|
+
require_relative 'event/app_endpoints_loaded'
|
|
29
30
|
require_relative 'event/app_heartbeat'
|
|
30
31
|
require_relative 'event/app_integrations_change'
|
|
31
32
|
require_relative 'event/app_started'
|
|
@@ -14,8 +14,8 @@ module Datadog
|
|
|
14
14
|
# read: lib/datadog/core/telemetry/logging.rb
|
|
15
15
|
module Logger
|
|
16
16
|
class << self
|
|
17
|
-
def report(exception, level: :error, description: nil
|
|
18
|
-
instance&.report(exception, level: level, description: description
|
|
17
|
+
def report(exception, level: :error, description: nil)
|
|
18
|
+
instance&.report(exception, level: level, description: description)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def error(description)
|
|
@@ -45,17 +45,11 @@ module Datadog
|
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
def report(exception, level: :error, description: nil
|
|
48
|
+
def report(exception, level: :error, description: nil)
|
|
49
49
|
# Anonymous exceptions to be logged as <Class:0x00007f8b1c0b3b40>
|
|
50
50
|
message = +"#{exception.class.name || exception.class.inspect}" # standard:disable Style/RedundantInterpolation
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if description || exception_message
|
|
55
|
-
message << ':'
|
|
56
|
-
message << " #{description}" if description
|
|
57
|
-
message << " (#{exception.message})" if exception_message
|
|
58
|
-
end
|
|
52
|
+
message << ": #{description}" if description
|
|
59
53
|
|
|
60
54
|
event = Event::Log.new(
|
|
61
55
|
message: message,
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
require_relative '../../../transport/http/api/endpoint'
|
|
4
4
|
require_relative '../../../transport/http/api/instance'
|
|
5
5
|
require_relative '../../../transport/http/api/spec'
|
|
6
|
+
require_relative '../../../transport/http/client'
|
|
6
7
|
require_relative '../../../transport/request'
|
|
7
|
-
require_relative 'client'
|
|
8
8
|
|
|
9
9
|
module Datadog
|
|
10
10
|
module Core
|
|
@@ -12,10 +12,11 @@ module Datadog
|
|
|
12
12
|
module Transport
|
|
13
13
|
module HTTP
|
|
14
14
|
module Telemetry
|
|
15
|
-
|
|
15
|
+
class Client < Core::Transport::HTTP::Client
|
|
16
16
|
def send_telemetry_payload(request)
|
|
17
|
-
send_request(request) do |api, env|
|
|
18
|
-
api
|
|
17
|
+
send_request(request) do |api, env|
|
|
18
|
+
# TODO how to make api have the derived type for steep?
|
|
19
|
+
api.send_telemetry(env) # steep:ignore
|
|
19
20
|
end
|
|
20
21
|
end
|
|
21
22
|
end
|
|
@@ -83,8 +84,6 @@ module Datadog
|
|
|
83
84
|
end
|
|
84
85
|
end
|
|
85
86
|
end
|
|
86
|
-
|
|
87
|
-
HTTP::Client.include(Telemetry::Client)
|
|
88
87
|
end
|
|
89
88
|
end
|
|
90
89
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative '../../transport/parcel'
|
|
4
|
-
require_relative 'http/client'
|
|
5
4
|
require_relative 'http/telemetry'
|
|
6
5
|
|
|
7
6
|
module Datadog
|
|
@@ -32,7 +31,7 @@ module Datadog
|
|
|
32
31
|
@apis = apis
|
|
33
32
|
@logger = logger
|
|
34
33
|
|
|
35
|
-
@client = HTTP::Client.new(@apis[default_api], logger: logger)
|
|
34
|
+
@client = Core::Telemetry::Transport::HTTP::Telemetry::Client.new(@apis[default_api], logger: logger)
|
|
36
35
|
end
|
|
37
36
|
|
|
38
37
|
def send_telemetry(request_type:, payload:)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'env'
|
|
4
|
+
require_relative '../response'
|
|
5
|
+
|
|
6
|
+
module Datadog
|
|
7
|
+
module Core
|
|
8
|
+
module Transport
|
|
9
|
+
module HTTP
|
|
10
|
+
# Routes, encodes, and sends DI data to the trace agent via HTTP.
|
|
11
|
+
#
|
|
12
|
+
# @api private
|
|
13
|
+
class Client
|
|
14
|
+
attr_reader :api, :logger
|
|
15
|
+
|
|
16
|
+
def initialize(api, logger:)
|
|
17
|
+
@api = api
|
|
18
|
+
@logger = logger
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def send_request(request, &block)
|
|
24
|
+
# Build request into env
|
|
25
|
+
env = build_env(request)
|
|
26
|
+
|
|
27
|
+
# Get responses from API
|
|
28
|
+
yield(api, env).tap do |response|
|
|
29
|
+
on_response(response)
|
|
30
|
+
end
|
|
31
|
+
rescue => exception
|
|
32
|
+
on_exception(exception)
|
|
33
|
+
|
|
34
|
+
Datadog::Core::Transport::InternalErrorResponse.new(exception)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def build_env(request)
|
|
38
|
+
Datadog::Core::Transport::HTTP::Env.new(request)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Callback that is invoked if a request did not raise an exception
|
|
42
|
+
# (but did not necessarily complete successfully).
|
|
43
|
+
#
|
|
44
|
+
# Override in subclasses.
|
|
45
|
+
#
|
|
46
|
+
# Note that the client will return the original response -
|
|
47
|
+
# the return value of this method is ignored, and response should
|
|
48
|
+
# not be modified.
|
|
49
|
+
def on_response(response)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Callback that is invoked if a request failed with an exception.
|
|
53
|
+
#
|
|
54
|
+
# Override in subclasses.
|
|
55
|
+
def on_exception(exception)
|
|
56
|
+
message = build_exception_message(exception)
|
|
57
|
+
|
|
58
|
+
logger.debug(message)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def build_exception_message(exception)
|
|
62
|
+
"Internal error during #{self.class.name} request. Cause: #{exception.class}: #{exception} " \
|
|
63
|
+
"Location: #{Array(exception.backtrace).first}"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -34,7 +34,10 @@ module Datadog
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def inspect
|
|
37
|
-
|
|
37
|
+
maybe_code = if respond_to?(:code)
|
|
38
|
+
" code:#{code}," # steep:ignore
|
|
39
|
+
end
|
|
40
|
+
"#{self.class} ok?:#{ok?},#{maybe_code} unsupported?:#{unsupported?}, " \
|
|
38
41
|
"not_found?:#{not_found?}, client_error?:#{client_error?}, " \
|
|
39
42
|
"server_error?:#{server_error?}, internal_error?:#{internal_error?}, " \
|
|
40
43
|
"payload:#{payload}"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module Core
|
|
5
|
+
module Utils
|
|
6
|
+
# Common array-related utility functions.
|
|
7
|
+
module Array
|
|
8
|
+
def self.filter_map(array, &block)
|
|
9
|
+
if array.respond_to?(:filter_map)
|
|
10
|
+
# DEV Supported since Ruby 2.7, saves an intermediate object creation
|
|
11
|
+
array.filter_map(&block)
|
|
12
|
+
elsif array.is_a?(Enumerator::Lazy)
|
|
13
|
+
# You would think that .compact would work here, but it does not:
|
|
14
|
+
# the result of .map could be an Enumerator::Lazy instance which
|
|
15
|
+
# does not implement #compact on Ruby 2.5/2.6.
|
|
16
|
+
array.map(&block).reject do |item|
|
|
17
|
+
item.nil?
|
|
18
|
+
end
|
|
19
|
+
else
|
|
20
|
+
array.each_with_object([]) do |item, memo|
|
|
21
|
+
new_item = block.call(item)
|
|
22
|
+
memo.push(new_item) unless new_item.nil?
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
require 'forwardable'
|
|
4
4
|
|
|
5
5
|
module Datadog
|
|
6
|
-
module
|
|
7
|
-
module
|
|
6
|
+
module Core
|
|
7
|
+
module Utils
|
|
8
8
|
# An LRU (Least Recently Used) cache implementation that relies on the
|
|
9
9
|
# Ruby 1.9+ `Hash` implementation that guarantees insertion order.
|
|
10
10
|
#
|
|
11
11
|
# WARNING: This implementation is NOT thread-safe and should be used
|
|
12
|
-
# in a single-threaded context.
|
|
12
|
+
# in a single-threaded context or guarded by Mutex.
|
|
13
13
|
class LRUCache
|
|
14
14
|
extend Forwardable
|
|
15
15
|
|
|
@@ -30,25 +30,14 @@ module Datadog
|
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
def
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
# NOTE: If the key exists, it's moved to the end of the list and
|
|
42
|
-
# if does not, the given block will be executed and the result
|
|
43
|
-
# will be stored (which will add it to the end of the list).
|
|
44
|
-
def fetch_or_store(key)
|
|
45
|
-
if (entry = @store.delete(key))
|
|
46
|
-
return @store[key] = entry
|
|
33
|
+
def []=(key, value)
|
|
34
|
+
if @store.delete(key)
|
|
35
|
+
@store[key] = value
|
|
36
|
+
else
|
|
37
|
+
# NOTE: evict the oldest entry if store reached the maximum allowed size
|
|
38
|
+
@store.shift if @store.size >= @max_size
|
|
39
|
+
@store[key] = value
|
|
47
40
|
end
|
|
48
|
-
|
|
49
|
-
# NOTE: evict the oldest entry if store reached the maximum allowed size
|
|
50
|
-
@store.shift if @store.size >= @max_size
|
|
51
|
-
@store[key] = yield
|
|
52
41
|
end
|
|
53
42
|
end
|
|
54
43
|
end
|
|
@@ -13,6 +13,7 @@ module Datadog
|
|
|
13
13
|
true-client-ip
|
|
14
14
|
x-client-ip
|
|
15
15
|
x-forwarded
|
|
16
|
+
forwarded
|
|
16
17
|
forwarded-for
|
|
17
18
|
x-cluster-client-ip
|
|
18
19
|
fastly-client-ip
|
|
@@ -20,6 +21,8 @@ module Datadog
|
|
|
20
21
|
cf-connecting-ipv6
|
|
21
22
|
].freeze
|
|
22
23
|
|
|
24
|
+
CGNAT_IP_RANGE = IPAddr.new('100.64.0.0/10')
|
|
25
|
+
|
|
23
26
|
class << self
|
|
24
27
|
# Returns a client IP associated with the request if it was
|
|
25
28
|
# retrieved successfully.
|
|
@@ -73,6 +76,8 @@ module Datadog
|
|
|
73
76
|
next unless value
|
|
74
77
|
|
|
75
78
|
ips = value.split(',')
|
|
79
|
+
ips = process_forwarded_header_values(ips) if name == 'forwarded'
|
|
80
|
+
|
|
76
81
|
ips.each do |ip|
|
|
77
82
|
parsed_ip = ip_to_ipaddr(ip.strip)
|
|
78
83
|
|
|
@@ -83,6 +88,22 @@ module Datadog
|
|
|
83
88
|
nil
|
|
84
89
|
end
|
|
85
90
|
|
|
91
|
+
def process_forwarded_header_values(values)
|
|
92
|
+
values.each_with_object([]) do |value, acc|
|
|
93
|
+
value.downcase!
|
|
94
|
+
|
|
95
|
+
value.split(';').each do |tuple_str|
|
|
96
|
+
tuple_str.strip!
|
|
97
|
+
next unless tuple_str.start_with?('for=')
|
|
98
|
+
|
|
99
|
+
tuple_str.delete_prefix!('for=')
|
|
100
|
+
tuple_str.delete!('"')
|
|
101
|
+
|
|
102
|
+
acc << tuple_str
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
86
107
|
# Returns whether the given value is more likely to be an IPv4 than an IPv6 address.
|
|
87
108
|
#
|
|
88
109
|
# This is done by checking if a dot (`'.'`) character appears before a colon (`':'`) in the value.
|
|
@@ -112,7 +133,7 @@ module Datadog
|
|
|
112
133
|
end
|
|
113
134
|
|
|
114
135
|
def global_ip?(parsed_ip)
|
|
115
|
-
parsed_ip && !parsed_ip.private? && !parsed_ip.loopback? && !parsed_ip.link_local?
|
|
136
|
+
parsed_ip && !parsed_ip.private? && !parsed_ip.loopback? && !parsed_ip.link_local? && !CGNAT_IP_RANGE.include?(parsed_ip)
|
|
116
137
|
end
|
|
117
138
|
end
|
|
118
139
|
end
|