datadog 2.14.0 → 2.16.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 +67 -1
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +7 -6
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
- data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.c +69 -0
- data/ext/datadog_profiling_native_extension/encoded_profile.h +7 -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 +25 -32
- data/ext/datadog_profiling_native_extension/profiling.c +2 -0
- data/ext/datadog_profiling_native_extension/stack_recorder.c +22 -21
- data/ext/libdatadog_api/crashtracker.c +1 -9
- 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 +10 -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/process_discovery.c +117 -0
- data/ext/libdatadog_api/process_discovery.h +5 -0
- data/lib/datadog/appsec/actions_handler.rb +3 -2
- data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
- data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
- data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
- data/lib/datadog/appsec/autoload.rb +1 -1
- data/lib/datadog/appsec/component.rb +29 -20
- data/lib/datadog/appsec/compressed_json.rb +40 -0
- 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 +2 -2
- 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 +95 -134
- 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 +16 -11
- 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/configuration/agentless_settings_resolver.rb +176 -0
- data/lib/datadog/core/configuration/components.rb +19 -10
- data/lib/datadog/core/configuration/option.rb +61 -25
- data/lib/datadog/core/configuration/settings.rb +10 -0
- data/lib/datadog/core/configuration/stable_config.rb +23 -0
- data/lib/datadog/core/configuration.rb +24 -0
- data/lib/datadog/core/crashtracking/component.rb +1 -9
- data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
- data/lib/datadog/core/environment/git.rb +1 -0
- data/lib/datadog/core/environment/variable_helpers.rb +1 -1
- data/lib/datadog/core/metrics/client.rb +8 -7
- data/lib/datadog/core/process_discovery.rb +32 -0
- data/lib/datadog/core/remote/client.rb +7 -0
- data/lib/datadog/core/runtime/metrics.rb +1 -1
- data/lib/datadog/core/telemetry/component.rb +60 -50
- data/lib/datadog/core/telemetry/emitter.rb +17 -11
- data/lib/datadog/core/telemetry/event.rb +7 -4
- data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
- data/lib/datadog/core/telemetry/metric.rb +5 -5
- data/lib/datadog/core/telemetry/request.rb +4 -4
- 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 +52 -0
- data/lib/datadog/core/telemetry/worker.rb +45 -0
- data/lib/datadog/core/utils/time.rb +12 -0
- data/lib/datadog/core/workers/async.rb +20 -2
- 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/probe_notification_builder.rb +1 -1
- data/lib/datadog/di/remote.rb +2 -0
- data/lib/datadog/di/transport/http/diagnostics.rb +0 -1
- data/lib/datadog/di/transport/http/input.rb +0 -1
- data/lib/datadog/di/transport/http.rb +0 -6
- 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/info.rb +3 -0
- data/lib/datadog/profiling/encoded_profile.rb +11 -0
- data/lib/datadog/profiling/exporter.rb +3 -4
- data/lib/datadog/profiling/ext.rb +0 -1
- data/lib/datadog/profiling/flush.rb +4 -7
- data/lib/datadog/profiling/http_transport.rb +10 -59
- data/lib/datadog/profiling/stack_recorder.rb +4 -4
- data/lib/datadog/profiling.rb +1 -0
- data/lib/datadog/tracing/analytics.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/integration.rb +1 -1
- 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/opensearch/configuration/settings.rb +17 -0
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
- data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
- data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +1 -1
- 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/sampling/rate_sampler.rb +2 -1
- data/lib/datadog/tracing/span_event.rb +1 -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 +40 -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
@@ -140,6 +140,13 @@ module Datadog
|
|
140
140
|
"ruby.gem.libdatadog.platform:#{gem_spec('libdatadog').platform}",
|
141
141
|
]
|
142
142
|
|
143
|
+
if (git_repository_url = Core::Environment::Git.git_repository_url)
|
144
|
+
client_tracer_tags << "git.repository_url:#{git_repository_url}"
|
145
|
+
end
|
146
|
+
if (git_commit_sha = Core::Environment::Git.git_commit_sha)
|
147
|
+
client_tracer_tags << "git.commit.sha:#{git_commit_sha}"
|
148
|
+
end
|
149
|
+
|
143
150
|
client_tracer = {
|
144
151
|
runtime_id: Core::Environment::Identity.id,
|
145
152
|
language: Core::Environment::Identity.lang,
|
@@ -2,12 +2,13 @@
|
|
2
2
|
|
3
3
|
require_relative 'emitter'
|
4
4
|
require_relative 'event'
|
5
|
-
require_relative 'http/transport'
|
6
5
|
require_relative 'metrics_manager'
|
7
6
|
require_relative 'worker'
|
8
7
|
require_relative 'logging'
|
8
|
+
require_relative 'transport/http'
|
9
9
|
|
10
10
|
require_relative '../configuration/ext'
|
11
|
+
require_relative '../configuration/agentless_settings_resolver'
|
11
12
|
require_relative '../utils/forking'
|
12
13
|
|
13
14
|
module Datadog
|
@@ -16,7 +17,7 @@ module Datadog
|
|
16
17
|
# Telemetry entrypoint, coordinates sending telemetry events at various points in app lifecycle.
|
17
18
|
# Note: Telemetry does not spawn its worker thread in fork processes, thus no telemetry is sent in forked processes.
|
18
19
|
class Component
|
19
|
-
attr_reader :enabled, :logger
|
20
|
+
attr_reader :enabled, :logger, :transport, :worker
|
20
21
|
|
21
22
|
include Core::Utils::Forking
|
22
23
|
include Telemetry::Logging
|
@@ -25,89 +26,87 @@ module Datadog
|
|
25
26
|
enabled = settings.telemetry.enabled
|
26
27
|
agentless_enabled = settings.telemetry.agentless_enabled
|
27
28
|
|
28
|
-
if !agentless_enabled && agent_settings.adapter != Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
29
|
-
enabled = false
|
30
|
-
logger.debug { "Telemetry disabled. Agent network adapter not supported: #{agent_settings.adapter}" }
|
31
|
-
end
|
32
|
-
|
33
29
|
if agentless_enabled && settings.api_key.nil?
|
34
30
|
enabled = false
|
35
|
-
logger.debug { 'Telemetry disabled. Agentless telemetry requires
|
31
|
+
logger.debug { 'Telemetry disabled. Agentless telemetry requires a DD_API_KEY variable to be set.' }
|
36
32
|
end
|
37
33
|
|
38
|
-
transport = if agentless_enabled
|
39
|
-
Datadog::Core::Telemetry::Http::Transport.build_agentless_transport(
|
40
|
-
api_key: settings.api_key,
|
41
|
-
dd_site: settings.site,
|
42
|
-
url_override: settings.telemetry.agentless_url_override
|
43
|
-
)
|
44
|
-
else
|
45
|
-
Datadog::Core::Telemetry::Http::Transport.build_agent_transport(agent_settings)
|
46
|
-
end
|
47
|
-
|
48
34
|
Telemetry::Component.new(
|
49
|
-
|
35
|
+
settings: settings,
|
36
|
+
agent_settings: agent_settings,
|
50
37
|
enabled: enabled,
|
51
|
-
metrics_enabled: enabled && settings.telemetry.metrics_enabled,
|
52
|
-
heartbeat_interval_seconds: settings.telemetry.heartbeat_interval_seconds,
|
53
|
-
metrics_aggregation_interval_seconds: settings.telemetry.metrics_aggregation_interval_seconds,
|
54
|
-
dependency_collection: settings.telemetry.dependency_collection,
|
55
38
|
logger: logger,
|
56
|
-
shutdown_timeout_seconds: settings.telemetry.shutdown_timeout_seconds,
|
57
|
-
log_collection_enabled: settings.telemetry.log_collection_enabled
|
58
39
|
)
|
59
40
|
end
|
60
41
|
|
61
42
|
# @param enabled [Boolean] Determines whether telemetry events should be sent to the API
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
# @param [Boolean] dependency_collection Whether to send the `app-dependencies-loaded` event
|
66
|
-
def initialize(
|
67
|
-
heartbeat_interval_seconds:,
|
68
|
-
metrics_aggregation_interval_seconds:,
|
69
|
-
dependency_collection:,
|
43
|
+
def initialize( # rubocop: disable Metrics/MethodLength
|
44
|
+
settings:,
|
45
|
+
agent_settings:,
|
70
46
|
logger:,
|
71
|
-
|
72
|
-
shutdown_timeout_seconds:,
|
73
|
-
enabled: true,
|
74
|
-
metrics_enabled: true,
|
75
|
-
log_collection_enabled: true
|
47
|
+
enabled:
|
76
48
|
)
|
77
49
|
@enabled = enabled
|
78
|
-
@log_collection_enabled = log_collection_enabled
|
50
|
+
@log_collection_enabled = settings.telemetry.log_collection_enabled
|
79
51
|
@logger = logger
|
80
52
|
|
81
53
|
@metrics_manager = MetricsManager.new(
|
82
|
-
enabled: enabled && metrics_enabled,
|
83
|
-
aggregation_interval: metrics_aggregation_interval_seconds
|
54
|
+
enabled: @enabled && settings.telemetry.metrics_enabled,
|
55
|
+
aggregation_interval: settings.telemetry.metrics_aggregation_interval_seconds,
|
84
56
|
)
|
85
57
|
|
58
|
+
@stopped = false
|
59
|
+
|
60
|
+
return unless @enabled
|
61
|
+
|
62
|
+
@transport = if settings.telemetry.agentless_enabled
|
63
|
+
agent_settings = Core::Configuration::AgentlessSettingsResolver.call(
|
64
|
+
settings,
|
65
|
+
host_prefix: 'instrumentation-telemetry-intake',
|
66
|
+
url_override: settings.telemetry.agentless_url_override,
|
67
|
+
url_override_source: 'c.telemetry.agentless_url_override',
|
68
|
+
logger: logger,
|
69
|
+
)
|
70
|
+
Telemetry::Transport::HTTP.agentless_telemetry(
|
71
|
+
agent_settings: agent_settings,
|
72
|
+
logger: logger,
|
73
|
+
# api_key should have already validated to be
|
74
|
+
# not nil by +build+ method above.
|
75
|
+
api_key: settings.api_key,
|
76
|
+
)
|
77
|
+
else
|
78
|
+
Telemetry::Transport::HTTP.agent_telemetry(
|
79
|
+
agent_settings: agent_settings, logger: logger,
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
86
83
|
@worker = Telemetry::Worker.new(
|
87
84
|
enabled: @enabled,
|
88
|
-
heartbeat_interval_seconds: heartbeat_interval_seconds,
|
89
|
-
metrics_aggregation_interval_seconds: metrics_aggregation_interval_seconds,
|
90
|
-
emitter: Emitter.new(
|
85
|
+
heartbeat_interval_seconds: settings.telemetry.heartbeat_interval_seconds,
|
86
|
+
metrics_aggregation_interval_seconds: settings.telemetry.metrics_aggregation_interval_seconds,
|
87
|
+
emitter: Emitter.new(
|
88
|
+
@transport,
|
89
|
+
logger: @logger,
|
90
|
+
debug: settings.telemetry.debug,
|
91
|
+
),
|
91
92
|
metrics_manager: @metrics_manager,
|
92
|
-
dependency_collection: dependency_collection,
|
93
|
+
dependency_collection: settings.telemetry.dependency_collection,
|
93
94
|
logger: logger,
|
94
|
-
shutdown_timeout: shutdown_timeout_seconds
|
95
|
+
shutdown_timeout: settings.telemetry.shutdown_timeout_seconds,
|
95
96
|
)
|
96
97
|
|
97
|
-
@stopped = false
|
98
|
-
|
99
98
|
@worker.start
|
100
99
|
end
|
101
100
|
|
102
101
|
def disable!
|
103
102
|
@enabled = false
|
104
|
-
@worker
|
103
|
+
@worker&.enabled = false
|
105
104
|
end
|
106
105
|
|
107
106
|
def stop!
|
108
107
|
return if @stopped
|
109
108
|
|
110
|
-
@worker
|
109
|
+
@worker&.stop(true)
|
111
110
|
@stopped = true
|
112
111
|
end
|
113
112
|
|
@@ -129,6 +128,17 @@ module Datadog
|
|
129
128
|
@worker.enqueue(event)
|
130
129
|
end
|
131
130
|
|
131
|
+
# Wait for the worker to send out all events that have already
|
132
|
+
# been queued, up to 15 seconds. Returns whether all events have
|
133
|
+
# been flushed.
|
134
|
+
#
|
135
|
+
# @api private
|
136
|
+
def flush
|
137
|
+
return if !@enabled || forked?
|
138
|
+
|
139
|
+
@worker.flush
|
140
|
+
end
|
141
|
+
|
132
142
|
# Report configuration changes caused by Remote Configuration.
|
133
143
|
def client_configuration_change!(changes)
|
134
144
|
return if !@enabled || forked?
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'request'
|
4
|
-
require_relative '
|
4
|
+
require_relative '../transport/response'
|
5
5
|
require_relative '../utils/sequence'
|
6
6
|
require_relative '../utils/forking'
|
7
7
|
|
@@ -10,26 +10,32 @@ module Datadog
|
|
10
10
|
module Telemetry
|
11
11
|
# Class that emits telemetry events
|
12
12
|
class Emitter
|
13
|
-
attr_reader :
|
13
|
+
attr_reader :transport, :logger
|
14
14
|
|
15
15
|
extend Core::Utils::Forking
|
16
16
|
|
17
|
-
# @param
|
18
|
-
#
|
19
|
-
def initialize(
|
20
|
-
@
|
17
|
+
# @param transport [Datadog::Core::Telemetry::Transport::Telemetry::Transport]
|
18
|
+
# Transport object that can be used to send telemetry requests
|
19
|
+
def initialize(transport, logger: Datadog.logger, debug: false)
|
20
|
+
@transport = transport
|
21
|
+
@logger = logger
|
22
|
+
@debug = !!debug
|
23
|
+
end
|
24
|
+
|
25
|
+
def debug?
|
26
|
+
@debug
|
21
27
|
end
|
22
28
|
|
23
29
|
# Retrieves and emits a TelemetryRequest object based on the request type specified
|
24
30
|
def request(event)
|
25
31
|
seq_id = self.class.sequence.next
|
26
|
-
payload = Request.build_payload(event, seq_id)
|
27
|
-
res = @
|
28
|
-
|
32
|
+
payload = Request.build_payload(event, seq_id, debug: debug?)
|
33
|
+
res = @transport.send_telemetry(request_type: event.type, payload: payload)
|
34
|
+
logger.debug { "Telemetry sent for event `#{event.type}` (response code: #{res.code})" }
|
29
35
|
res
|
30
36
|
rescue => e
|
31
|
-
|
32
|
-
|
37
|
+
logger.debug { "Unable to send telemetry request for event `#{event.type rescue 'unknown'}`: #{e}" }
|
38
|
+
Core::Transport::InternalErrorResponse.new(e)
|
33
39
|
end
|
34
40
|
|
35
41
|
# Initializes a Sequence object to track seq_id if not already initialized; else returns stored
|
@@ -74,10 +74,9 @@ module Datadog
|
|
74
74
|
profiler: {
|
75
75
|
enabled: Datadog::Profiling.enabled?,
|
76
76
|
},
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
# }
|
77
|
+
dynamic_instrumentation: {
|
78
|
+
enabled: defined?(Datadog::DI) && Datadog::DI.respond_to?(:enabled?) && Datadog::DI.enabled?,
|
79
|
+
}
|
81
80
|
}
|
82
81
|
|
83
82
|
if (unsupported_reason = Datadog::Profiling.unsupported_reason)
|
@@ -91,6 +90,7 @@ module Datadog
|
|
91
90
|
end
|
92
91
|
|
93
92
|
TARGET_OPTIONS = %w[
|
93
|
+
dynamic_instrumentation.enabled
|
94
94
|
logger.level
|
95
95
|
profiling.advanced.code_provenance_enabled
|
96
96
|
profiling.advanced.endpoint.collection.enabled
|
@@ -114,6 +114,9 @@ module Datadog
|
|
114
114
|
seq_id = Event.configuration_sequence.next
|
115
115
|
|
116
116
|
list = [
|
117
|
+
conf_value('DD_GIT_REPOSITORY_URL', Core::Environment::Git.git_repository_url, seq_id, 'env_var'),
|
118
|
+
conf_value('DD_GIT_COMMIT_SHA', Core::Environment::Git.git_commit_sha, seq_id, 'env_var'),
|
119
|
+
|
117
120
|
conf_value('DD_AGENT_HOST', config.agent.host, seq_id),
|
118
121
|
conf_value('DD_AGENT_TRANSPORT', agent_transport(config), seq_id),
|
119
122
|
conf_value('DD_TRACE_SAMPLE_RATE', to_value(config.tracing.sampling.default_rate), seq_id),
|
@@ -1,108 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
# datadog-ci-rb versions 1.15.0 and lower require this file and guard
|
4
|
+
# the require with a rescue of StandardError. Unfortunately LoadError,
|
5
|
+
# which would be raised if the file is missing, is not a subclass of
|
6
|
+
# StandardError and thus would not be caught by the rescue.
|
7
|
+
# We provide this file with a dummy class in it to avoid exceptions
|
8
|
+
# in datadog-ci-rb until version 2.0 is released.
|
9
|
+
#
|
10
|
+
# Note that datadog-ci-rb patches telemetry transport to be "real" even when
|
11
|
+
# webmock is used; this patching won't work with datadog-ci-rb versions
|
12
|
+
# 1.15.0 and older and dd-trace-rb 2.16.0 and newer. There will be no
|
13
|
+
# errors/exceptions reported but telemetry events will not be sent.
|
4
14
|
|
5
15
|
module Datadog
|
6
16
|
module Core
|
7
17
|
module Telemetry
|
8
18
|
module Http
|
9
19
|
module Adapters
|
10
|
-
|
11
|
-
class Net
|
12
|
-
attr_reader \
|
13
|
-
:hostname,
|
14
|
-
:port,
|
15
|
-
:timeout,
|
16
|
-
:ssl
|
17
|
-
|
18
|
-
DEFAULT_TIMEOUT = 2
|
19
|
-
|
20
|
-
def initialize(hostname:, port: nil, timeout: DEFAULT_TIMEOUT, ssl: true)
|
21
|
-
@hostname = hostname
|
22
|
-
@port = port
|
23
|
-
@timeout = timeout
|
24
|
-
@ssl = ssl.nil? || ssl
|
25
|
-
end
|
26
|
-
|
27
|
-
def open(&block)
|
28
|
-
req = ::Net::HTTP.new(@hostname, @port)
|
29
|
-
|
30
|
-
req.use_ssl = @ssl
|
31
|
-
req.open_timeout = req.read_timeout = @timeout
|
32
|
-
|
33
|
-
req.start(&block)
|
34
|
-
end
|
35
|
-
|
36
|
-
def post(env)
|
37
|
-
post = ::Net::HTTP::Post.new(env.path, env.headers)
|
38
|
-
post.body = env.body
|
39
|
-
|
40
|
-
http_response = open do |http|
|
41
|
-
http.request(post)
|
42
|
-
end
|
43
|
-
|
44
|
-
Response.new(http_response)
|
45
|
-
rescue StandardError => e
|
46
|
-
Datadog.logger.debug("Unable to send telemetry event to agent: #{e}")
|
47
|
-
Telemetry::Http::InternalErrorResponse.new(e)
|
48
|
-
end
|
49
|
-
|
50
|
-
# Data structure for an HTTP Response
|
51
|
-
class Response
|
52
|
-
include Datadog::Core::Telemetry::Http::Response
|
53
|
-
|
54
|
-
attr_reader :http_response
|
55
|
-
|
56
|
-
def initialize(http_response)
|
57
|
-
@http_response = http_response
|
58
|
-
end
|
59
|
-
|
60
|
-
def payload
|
61
|
-
return super if http_response.nil?
|
62
|
-
|
63
|
-
http_response.body
|
64
|
-
end
|
65
|
-
|
66
|
-
def code
|
67
|
-
return super if http_response.nil?
|
68
|
-
|
69
|
-
http_response.code.to_i
|
70
|
-
end
|
71
|
-
|
72
|
-
def ok?
|
73
|
-
return super if http_response.nil?
|
74
|
-
|
75
|
-
code.between?(200, 299)
|
76
|
-
end
|
77
|
-
|
78
|
-
def unsupported?
|
79
|
-
return super if http_response.nil?
|
80
|
-
|
81
|
-
code == 415
|
82
|
-
end
|
83
|
-
|
84
|
-
def not_found?
|
85
|
-
return super if http_response.nil?
|
86
|
-
|
87
|
-
code == 404
|
88
|
-
end
|
89
|
-
|
90
|
-
def client_error?
|
91
|
-
return super if http_response.nil?
|
92
|
-
|
93
|
-
code.between?(400, 499)
|
94
|
-
end
|
95
|
-
|
96
|
-
def server_error?
|
97
|
-
return super if http_response.nil?
|
98
|
-
|
99
|
-
code.between?(500, 599)
|
100
|
-
end
|
101
|
-
|
102
|
-
def inspect
|
103
|
-
"#{super}, http_response:#{http_response}"
|
104
|
-
end
|
105
|
-
end
|
20
|
+
class Net # rubocop:disable Lint/EmptyClass
|
106
21
|
end
|
107
22
|
end
|
108
23
|
end
|
@@ -108,9 +108,9 @@ module Datadog
|
|
108
108
|
value = value.to_i
|
109
109
|
|
110
110
|
if values.empty?
|
111
|
-
values << [Time.now.to_i, value]
|
111
|
+
values << [Core::Utils::Time.now.to_i, value]
|
112
112
|
else
|
113
|
-
values[0][0] = Time.now.to_i
|
113
|
+
values[0][0] = Core::Utils::Time.now.to_i
|
114
114
|
values[0][1] += value
|
115
115
|
end
|
116
116
|
nil
|
@@ -129,9 +129,9 @@ module Datadog
|
|
129
129
|
|
130
130
|
def track(value)
|
131
131
|
if values.empty?
|
132
|
-
values << [Time.now.to_i, value]
|
132
|
+
values << [Core::Utils::Time.now.to_i, value]
|
133
133
|
else
|
134
|
-
values[0][0] = Time.now.to_i
|
134
|
+
values[0][0] = Core::Utils::Time.now.to_i
|
135
135
|
values[0][1] = value
|
136
136
|
end
|
137
137
|
nil
|
@@ -155,7 +155,7 @@ module Datadog
|
|
155
155
|
|
156
156
|
def track(value = 1.0)
|
157
157
|
@value += value
|
158
|
-
@values = [[Time.now.to_i, @value / interval]]
|
158
|
+
@values = [[Core::Utils::Time.now.to_i, @value / interval]]
|
159
159
|
nil
|
160
160
|
end
|
161
161
|
end
|
@@ -11,17 +11,17 @@ module Datadog
|
|
11
11
|
class << self
|
12
12
|
using Core::Utils::Hash::Refinement
|
13
13
|
|
14
|
-
def build_payload(event, seq_id)
|
14
|
+
def build_payload(event, seq_id, api_version: 'v2', debug: false)
|
15
15
|
hash = {
|
16
|
-
api_version:
|
16
|
+
api_version: api_version,
|
17
17
|
application: application,
|
18
|
-
debug:
|
18
|
+
debug: debug,
|
19
19
|
host: host,
|
20
20
|
payload: event.payload,
|
21
21
|
request_type: event.type,
|
22
22
|
runtime_id: Core::Environment::Identity.id,
|
23
23
|
seq_id: seq_id,
|
24
|
-
tracer_time: Time.now.to_i,
|
24
|
+
tracer_time: Core::Utils::Time.now.to_i,
|
25
25
|
}
|
26
26
|
hash.compact!
|
27
27
|
hash
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../../encoding'
|
4
|
+
require_relative '../../../transport/http/api/map'
|
5
|
+
require_relative '../../../transport/http/api/instance'
|
6
|
+
require_relative '../../../transport/http/api/spec'
|
7
|
+
require_relative 'telemetry'
|
8
|
+
|
9
|
+
module Datadog
|
10
|
+
module Core
|
11
|
+
module Telemetry
|
12
|
+
module Transport
|
13
|
+
module HTTP
|
14
|
+
# Namespace for API components
|
15
|
+
module API
|
16
|
+
# Default API versions
|
17
|
+
AGENT_TELEMETRY = 'agent_telemetry'
|
18
|
+
AGENTLESS_TELEMETRY = 'agentless_telemetry'
|
19
|
+
|
20
|
+
module_function
|
21
|
+
|
22
|
+
def defaults
|
23
|
+
Datadog::Core::Transport::HTTP::API::Map[
|
24
|
+
AGENT_TELEMETRY => Telemetry::API::Spec.new do |s|
|
25
|
+
s.telemetry = Telemetry::API::Endpoint.new(
|
26
|
+
'/telemetry/proxy/api/v2/apmtelemetry',
|
27
|
+
Core::Encoding::JSONEncoder,
|
28
|
+
)
|
29
|
+
end,
|
30
|
+
AGENTLESS_TELEMETRY => Telemetry::API::Spec.new do |s|
|
31
|
+
s.telemetry = Telemetry::API::Endpoint.new(
|
32
|
+
'/api/v2/apmtelemetry',
|
33
|
+
Core::Encoding::JSONEncoder,
|
34
|
+
)
|
35
|
+
end,
|
36
|
+
]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../../transport/http/env'
|
4
|
+
require_relative '../../../transport/http/response'
|
5
|
+
|
6
|
+
# TODO: Decouple transport/http/client
|
7
|
+
#
|
8
|
+
# The standard one does `include Transport::HTTP::Statistics` and performs
|
9
|
+
# stats updates, which may or may not be desirable in general.
|
10
|
+
|
11
|
+
module Datadog
|
12
|
+
module Core
|
13
|
+
module Telemetry
|
14
|
+
module Transport
|
15
|
+
module HTTP
|
16
|
+
# Routes, encodes, and sends DI data to the trace agent via HTTP.
|
17
|
+
class Client
|
18
|
+
attr_reader :api, :logger
|
19
|
+
|
20
|
+
def initialize(api, logger:)
|
21
|
+
@api = api
|
22
|
+
@logger = logger
|
23
|
+
end
|
24
|
+
|
25
|
+
def send_request(request, &block)
|
26
|
+
# Build request into env
|
27
|
+
env = build_env(request)
|
28
|
+
|
29
|
+
# Get responses from API
|
30
|
+
yield(api, env)
|
31
|
+
rescue => e
|
32
|
+
message =
|
33
|
+
"Internal error during #{self.class.name} request. Cause: #{e.class.name} #{e.message} " \
|
34
|
+
"Location: #{Array(e.backtrace).first}"
|
35
|
+
|
36
|
+
logger.debug(message)
|
37
|
+
|
38
|
+
Datadog::Core::Transport::InternalErrorResponse.new(e)
|
39
|
+
end
|
40
|
+
|
41
|
+
def build_env(request)
|
42
|
+
Datadog::Core::Transport::HTTP::Env.new(request)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../../transport/http/api/endpoint'
|
4
|
+
require_relative '../../../transport/http/api/instance'
|
5
|
+
require_relative '../../../transport/http/api/spec'
|
6
|
+
require_relative '../../../transport/request'
|
7
|
+
require_relative 'client'
|
8
|
+
|
9
|
+
module Datadog
|
10
|
+
module Core
|
11
|
+
module Telemetry
|
12
|
+
module Transport
|
13
|
+
module HTTP
|
14
|
+
module Telemetry
|
15
|
+
module Client
|
16
|
+
def send_telemetry_payload(request)
|
17
|
+
send_request(request) do |api, env| # steep:ignore
|
18
|
+
api.send_telemetry(env)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module API
|
24
|
+
class Instance < Core::Transport::HTTP::API::Instance
|
25
|
+
def send_telemetry(env)
|
26
|
+
raise Core::Transport::HTTP::API::Instance::EndpointNotSupportedError.new('telemetry', self) unless spec.is_a?(Telemetry::API::Spec)
|
27
|
+
|
28
|
+
spec.send_telemetry(env) do |request_env|
|
29
|
+
call(request_env)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Spec < Core::Transport::HTTP::API::Spec
|
35
|
+
attr_accessor :telemetry
|
36
|
+
|
37
|
+
def send_telemetry(env, &block)
|
38
|
+
raise Core::Transport::HTTP::API::Spec::EndpointNotDefinedError.new('telemetry', self) if telemetry.nil?
|
39
|
+
|
40
|
+
telemetry.call(env, &block)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Endpoint < Datadog::Core::Transport::HTTP::API::Endpoint
|
45
|
+
HEADER_CONTENT_TYPE = 'Content-Type'
|
46
|
+
|
47
|
+
attr_reader \
|
48
|
+
:encoder
|
49
|
+
|
50
|
+
def initialize(path, encoder)
|
51
|
+
super(:post, path)
|
52
|
+
@encoder = encoder
|
53
|
+
end
|
54
|
+
|
55
|
+
def call(env, &block)
|
56
|
+
# Encode body & type
|
57
|
+
env.headers[HEADER_CONTENT_TYPE] = encoder.content_type
|
58
|
+
env.headers.update(headers(
|
59
|
+
request_type: env.request.request_type,
|
60
|
+
api_key: env.request.api_key,
|
61
|
+
))
|
62
|
+
env.body = env.request.parcel.data
|
63
|
+
|
64
|
+
super
|
65
|
+
end
|
66
|
+
|
67
|
+
def headers(request_type:, api_version: 'v2', api_key:)
|
68
|
+
{
|
69
|
+
Core::Transport::Ext::HTTP::HEADER_DD_INTERNAL_UNTRACED_REQUEST => '1',
|
70
|
+
# Provided by encoder
|
71
|
+
#'Content-Type' => 'application/json',
|
72
|
+
'DD-Telemetry-API-Version' => api_version,
|
73
|
+
'DD-Telemetry-Request-Type' => request_type,
|
74
|
+
'DD-Client-Library-Language' => Core::Environment::Ext::LANG,
|
75
|
+
'DD-Client-Library-Version' => Core::Environment::Identity.gem_datadog_version_semver2,
|
76
|
+
|
77
|
+
# Enable debug mode for telemetry
|
78
|
+
# 'DD-Telemetry-Debug-Enabled' => 'true',
|
79
|
+
}.tap do |result|
|
80
|
+
result['DD-API-KEY'] = api_key unless api_key.nil?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
HTTP::Client.include(Telemetry::Client)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|