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
@@ -29,13 +29,13 @@ module Datadog
|
|
29
29
|
class << self
|
30
30
|
def hexdigest(type, data)
|
31
31
|
d = case type
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
32
|
+
when :sha256
|
33
|
+
::Digest::SHA256.new
|
34
|
+
when :sha512
|
35
|
+
::Digest::SHA512.new
|
36
|
+
else
|
37
|
+
raise InvalidHashTypeError, type
|
38
|
+
end
|
39
39
|
|
40
40
|
while (buf = data.read(DIGEST_CHUNK))
|
41
41
|
d.update(buf)
|
@@ -5,6 +5,7 @@ require 'json'
|
|
5
5
|
require_relative '../config'
|
6
6
|
require_relative 'client'
|
7
7
|
require_relative '../../../utils/base64'
|
8
|
+
require_relative '../../../utils/truncation'
|
8
9
|
require_relative '../../../transport/http/response'
|
9
10
|
require_relative '../../../transport/http/api/endpoint'
|
10
11
|
|
@@ -20,9 +21,11 @@ module Datadog
|
|
20
21
|
include Datadog::Core::Transport::HTTP::Response
|
21
22
|
include Core::Remote::Transport::Config::Response
|
22
23
|
|
23
|
-
def initialize(http_response, options = {}) #
|
24
|
+
def initialize(http_response, options = {}) # standard:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
24
25
|
super(http_response)
|
25
26
|
|
27
|
+
raise AgentErrorResponse.new(http_response.code, http_response.payload) if http_response.code != 200
|
28
|
+
|
26
29
|
begin
|
27
30
|
payload = JSON.parse(http_response.payload, symbolize_names: true)
|
28
31
|
rescue JSON::ParserError => e
|
@@ -130,8 +133,21 @@ module Datadog
|
|
130
133
|
end
|
131
134
|
end
|
132
135
|
|
136
|
+
# Base class for Remote Configuration Config errors
|
137
|
+
class ConfigError < StandardError
|
138
|
+
end
|
139
|
+
|
140
|
+
# When the agent returned an error response to our request
|
141
|
+
class AgentErrorResponse < ConfigError
|
142
|
+
def initialize(code, body)
|
143
|
+
truncated_body = Core::Utils::Truncation.truncate_in_middle(body, 700, 300)
|
144
|
+
message = "Agent returned an error response: #{code}: #{truncated_body}"
|
145
|
+
super(message)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
133
149
|
# When an expected value type is incorrect
|
134
|
-
class TypeError <
|
150
|
+
class TypeError < ConfigError
|
135
151
|
def initialize(type, value)
|
136
152
|
message = "not a #{type}: #{value.inspect}"
|
137
153
|
|
@@ -140,7 +156,7 @@ module Datadog
|
|
140
156
|
end
|
141
157
|
|
142
158
|
# When value decoding fails
|
143
|
-
class DecodeError <
|
159
|
+
class DecodeError < ConfigError
|
144
160
|
def initialize(key, value)
|
145
161
|
message = "could not decode key #{key.inspect}: #{value.inspect}"
|
146
162
|
|
@@ -149,7 +165,7 @@ module Datadog
|
|
149
165
|
end
|
150
166
|
|
151
167
|
# When value parsing fails
|
152
|
-
class ParseError <
|
168
|
+
class ParseError < ConfigError
|
153
169
|
def initialize(key, value)
|
154
170
|
message = "could not parse key #{key.inspect}: #{value.inspect}"
|
155
171
|
|
@@ -215,7 +231,7 @@ module Datadog
|
|
215
231
|
env.body = env.request.parcel.data
|
216
232
|
|
217
233
|
# Query for response
|
218
|
-
http_response = super
|
234
|
+
http_response = super
|
219
235
|
|
220
236
|
response_options = {}
|
221
237
|
|
@@ -14,7 +14,7 @@ module Datadog
|
|
14
14
|
module Runtime
|
15
15
|
# For generating runtime metrics
|
16
16
|
class Metrics < Core::Metrics::Client
|
17
|
-
def initialize(**options)
|
17
|
+
def initialize(telemetry:, **options)
|
18
18
|
super
|
19
19
|
|
20
20
|
# Initialize service list
|
@@ -96,7 +96,7 @@ module Datadog
|
|
96
96
|
|
97
97
|
def try_flush
|
98
98
|
yield
|
99
|
-
rescue
|
99
|
+
rescue => e
|
100
100
|
Datadog.logger.warn("Error while sending runtime metric. Cause: #{e.class.name} #{e.message}")
|
101
101
|
end
|
102
102
|
|
@@ -147,7 +147,7 @@ module Datadog
|
|
147
147
|
gauge(metric_name, metric_value) if metric_value
|
148
148
|
end
|
149
149
|
|
150
|
-
#
|
150
|
+
# standard:disable Metrics/MethodLength
|
151
151
|
def flush_yjit_stats
|
152
152
|
# Only on Ruby >= 3.2
|
153
153
|
try_flush do
|
@@ -195,7 +195,7 @@ module Datadog
|
|
195
195
|
end
|
196
196
|
end
|
197
197
|
end
|
198
|
-
#
|
198
|
+
# standard:enable Metrics/MethodLength
|
199
199
|
end
|
200
200
|
end
|
201
201
|
end
|
@@ -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
|
@@ -15,8 +16,10 @@ module Datadog
|
|
15
16
|
module Telemetry
|
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.
|
19
|
+
#
|
20
|
+
# @api private
|
18
21
|
class Component
|
19
|
-
attr_reader :enabled, :logger
|
22
|
+
attr_reader :enabled, :logger, :transport, :worker
|
20
23
|
|
21
24
|
include Core::Utils::Forking
|
22
25
|
include Telemetry::Logging
|
@@ -25,89 +28,100 @@ module Datadog
|
|
25
28
|
enabled = settings.telemetry.enabled
|
26
29
|
agentless_enabled = settings.telemetry.agentless_enabled
|
27
30
|
|
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
31
|
if agentless_enabled && settings.api_key.nil?
|
34
32
|
enabled = false
|
35
|
-
logger.debug { 'Telemetry disabled. Agentless telemetry requires
|
33
|
+
logger.debug { 'Telemetry disabled. Agentless telemetry requires a DD_API_KEY variable to be set.' }
|
36
34
|
end
|
37
35
|
|
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
36
|
Telemetry::Component.new(
|
49
|
-
|
37
|
+
settings: settings,
|
38
|
+
agent_settings: agent_settings,
|
50
39
|
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
40
|
logger: logger,
|
56
|
-
shutdown_timeout_seconds: settings.telemetry.shutdown_timeout_seconds,
|
57
|
-
log_collection_enabled: settings.telemetry.log_collection_enabled
|
58
41
|
)
|
59
42
|
end
|
60
43
|
|
61
44
|
# @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:,
|
45
|
+
def initialize( # standard:disable Metrics/MethodLength
|
46
|
+
settings:,
|
47
|
+
agent_settings:,
|
70
48
|
logger:,
|
71
|
-
|
72
|
-
shutdown_timeout_seconds:,
|
73
|
-
enabled: true,
|
74
|
-
metrics_enabled: true,
|
75
|
-
log_collection_enabled: true
|
49
|
+
enabled:
|
76
50
|
)
|
77
51
|
@enabled = enabled
|
78
|
-
@log_collection_enabled = log_collection_enabled
|
52
|
+
@log_collection_enabled = settings.telemetry.log_collection_enabled
|
79
53
|
@logger = logger
|
80
54
|
|
81
55
|
@metrics_manager = MetricsManager.new(
|
82
|
-
enabled: enabled && metrics_enabled,
|
83
|
-
aggregation_interval: metrics_aggregation_interval_seconds
|
56
|
+
enabled: @enabled && settings.telemetry.metrics_enabled,
|
57
|
+
aggregation_interval: settings.telemetry.metrics_aggregation_interval_seconds,
|
84
58
|
)
|
85
59
|
|
60
|
+
@stopped = false
|
61
|
+
|
62
|
+
return unless @enabled
|
63
|
+
|
64
|
+
@transport = if settings.telemetry.agentless_enabled
|
65
|
+
agent_settings = Core::Configuration::AgentlessSettingsResolver.call(
|
66
|
+
settings,
|
67
|
+
host_prefix: 'instrumentation-telemetry-intake',
|
68
|
+
url_override: settings.telemetry.agentless_url_override,
|
69
|
+
url_override_source: 'c.telemetry.agentless_url_override',
|
70
|
+
logger: logger,
|
71
|
+
)
|
72
|
+
Telemetry::Transport::HTTP.agentless_telemetry(
|
73
|
+
agent_settings: agent_settings,
|
74
|
+
logger: logger,
|
75
|
+
# api_key should have already validated to be
|
76
|
+
# not nil by +build+ method above.
|
77
|
+
api_key: settings.api_key,
|
78
|
+
)
|
79
|
+
else
|
80
|
+
Telemetry::Transport::HTTP.agent_telemetry(
|
81
|
+
agent_settings: agent_settings, logger: logger,
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
86
85
|
@worker = Telemetry::Worker.new(
|
87
86
|
enabled: @enabled,
|
88
|
-
heartbeat_interval_seconds: heartbeat_interval_seconds,
|
89
|
-
metrics_aggregation_interval_seconds: metrics_aggregation_interval_seconds,
|
90
|
-
emitter: Emitter.new(
|
87
|
+
heartbeat_interval_seconds: settings.telemetry.heartbeat_interval_seconds,
|
88
|
+
metrics_aggregation_interval_seconds: settings.telemetry.metrics_aggregation_interval_seconds,
|
89
|
+
emitter: Emitter.new(
|
90
|
+
@transport,
|
91
|
+
logger: @logger,
|
92
|
+
debug: settings.telemetry.debug,
|
93
|
+
),
|
91
94
|
metrics_manager: @metrics_manager,
|
92
|
-
dependency_collection: dependency_collection,
|
95
|
+
dependency_collection: settings.telemetry.dependency_collection,
|
93
96
|
logger: logger,
|
94
|
-
shutdown_timeout: shutdown_timeout_seconds
|
97
|
+
shutdown_timeout: settings.telemetry.shutdown_timeout_seconds,
|
95
98
|
)
|
96
|
-
|
97
|
-
@stopped = false
|
98
|
-
|
99
|
-
@worker.start
|
100
99
|
end
|
101
100
|
|
102
101
|
def disable!
|
103
102
|
@enabled = false
|
104
|
-
@worker
|
103
|
+
@worker&.enabled = false
|
104
|
+
end
|
105
|
+
|
106
|
+
def start(initial_event_is_change = false)
|
107
|
+
return if !@enabled
|
108
|
+
|
109
|
+
initial_event = if initial_event_is_change
|
110
|
+
Event::SynthAppClientConfigurationChange.new
|
111
|
+
else
|
112
|
+
Event::AppStarted.new
|
113
|
+
end
|
114
|
+
|
115
|
+
@worker.start(initial_event)
|
105
116
|
end
|
106
117
|
|
107
|
-
def
|
118
|
+
def shutdown!
|
108
119
|
return if @stopped
|
109
120
|
|
110
|
-
@worker
|
121
|
+
if defined?(@worker)
|
122
|
+
@worker&.stop(true)
|
123
|
+
end
|
124
|
+
|
111
125
|
@stopped = true
|
112
126
|
end
|
113
127
|
|
@@ -129,6 +143,17 @@ module Datadog
|
|
129
143
|
@worker.enqueue(event)
|
130
144
|
end
|
131
145
|
|
146
|
+
# Wait for the worker to send out all events that have already
|
147
|
+
# been queued, up to 15 seconds. Returns whether all events have
|
148
|
+
# been flushed.
|
149
|
+
#
|
150
|
+
# @api private
|
151
|
+
def flush
|
152
|
+
return if !@enabled || forked?
|
153
|
+
|
154
|
+
@worker.flush
|
155
|
+
end
|
156
|
+
|
132
157
|
# Report configuration changes caused by Remote Configuration.
|
133
158
|
def client_configuration_change!(changes)
|
134
159
|
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,38 @@ 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 {
|
38
|
+
"Unable to send telemetry request for event `#{begin
|
39
|
+
event.type
|
40
|
+
rescue
|
41
|
+
"unknown"
|
42
|
+
end}`: #{e}"
|
43
|
+
}
|
44
|
+
Core::Transport::InternalErrorResponse.new(e)
|
33
45
|
end
|
34
46
|
|
35
47
|
# Initializes a Sequence object to track seq_id if not already initialized; else returns stored
|
@@ -0,0 +1,65 @@
|
|
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 class for the 'app-client-configuration-change' event
|
10
|
+
class AppClientConfigurationChange < Base
|
11
|
+
attr_reader :changes, :origin
|
12
|
+
|
13
|
+
def type
|
14
|
+
'app-client-configuration-change'
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(changes, origin)
|
18
|
+
super()
|
19
|
+
@changes = changes
|
20
|
+
@origin = origin
|
21
|
+
end
|
22
|
+
|
23
|
+
def payload
|
24
|
+
{configuration: configuration}
|
25
|
+
end
|
26
|
+
|
27
|
+
def configuration
|
28
|
+
config = Datadog.configuration
|
29
|
+
seq_id = Event.configuration_sequence.next
|
30
|
+
|
31
|
+
res = @changes.map do |name, value|
|
32
|
+
{
|
33
|
+
name: name,
|
34
|
+
value: value,
|
35
|
+
origin: @origin,
|
36
|
+
seq_id: seq_id,
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
unless config.dig('appsec', 'sca_enabled').nil?
|
41
|
+
res << {
|
42
|
+
name: 'appsec.sca_enabled',
|
43
|
+
value: config.appsec.sca_enabled,
|
44
|
+
origin: 'code',
|
45
|
+
seq_id: seq_id,
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
res
|
50
|
+
end
|
51
|
+
|
52
|
+
def ==(other)
|
53
|
+
other.is_a?(AppClientConfigurationChange) && other.changes == @changes && other.origin == @origin
|
54
|
+
end
|
55
|
+
|
56
|
+
alias_method :eql?, :==
|
57
|
+
|
58
|
+
def hash
|
59
|
+
[self.class, @changes, @origin].hash
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,18 @@
|
|
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 class for the 'app-closing' event
|
10
|
+
class AppClosing < Base
|
11
|
+
def type
|
12
|
+
'app-closing'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
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 class for the 'app-dependencies-loaded' event
|
10
|
+
class AppDependenciesLoaded < Base
|
11
|
+
def type
|
12
|
+
'app-dependencies-loaded'
|
13
|
+
end
|
14
|
+
|
15
|
+
def payload
|
16
|
+
{dependencies: dependencies}
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def dependencies
|
22
|
+
Gem.loaded_specs.collect do |name, gem|
|
23
|
+
{
|
24
|
+
name: name,
|
25
|
+
version: gem.version.to_s,
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,18 @@
|
|
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 class for the 'app-heartbeat' event
|
10
|
+
class AppHeartbeat < Base
|
11
|
+
def type
|
12
|
+
'app-heartbeat'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,58 @@
|
|
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 class for the 'app-integrations-change' event
|
10
|
+
class AppIntegrationsChange < Base
|
11
|
+
def type
|
12
|
+
'app-integrations-change'
|
13
|
+
end
|
14
|
+
|
15
|
+
def payload
|
16
|
+
{integrations: integrations}
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def integrations
|
22
|
+
instrumented_integrations = Datadog.configuration.tracing.instrumented_integrations
|
23
|
+
Datadog.registry.map do |integration|
|
24
|
+
is_instrumented = instrumented_integrations.include?(integration.name)
|
25
|
+
|
26
|
+
is_enabled = is_instrumented && integration.klass.patcher.patch_successful
|
27
|
+
|
28
|
+
version = integration.klass.class.version&.to_s
|
29
|
+
|
30
|
+
res = {
|
31
|
+
name: integration.name.to_s,
|
32
|
+
enabled: is_enabled,
|
33
|
+
version: version,
|
34
|
+
compatible: integration.klass.class.compatible?,
|
35
|
+
error: (patch_error(integration) if is_instrumented && !is_enabled),
|
36
|
+
# TODO: Track if integration is instrumented by manual configuration or by auto instrumentation
|
37
|
+
# auto_enabled: is_enabled && ???,
|
38
|
+
}
|
39
|
+
res.reject! { |_, v| v.nil? }
|
40
|
+
res
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def patch_error(integration)
|
45
|
+
patch_error_result = integration.klass.patcher.patch_error_result
|
46
|
+
return patch_error_result.compact.to_s if patch_error_result
|
47
|
+
|
48
|
+
# If no error occurred during patching, but integration is still not instrumented
|
49
|
+
"Available?: #{integration.klass.class.available?}" \
|
50
|
+
", Loaded? #{integration.klass.class.loaded?}" \
|
51
|
+
", Compatible? #{integration.klass.class.compatible?}" \
|
52
|
+
", Patchable? #{integration.klass.class.patchable?}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|