datadog 2.36.0 → 2.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +46 -1
- data/ext/datadog_profiling_native_extension/clock_id_from_mach.c +5 -12
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +6 -3
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +17 -3
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +219 -98
- data/ext/datadog_profiling_native_extension/collectors_thread_context.h +2 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +11 -0
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +7 -0
- data/ext/libdatadog_api/di.c +76 -0
- data/ext/libdatadog_api/extconf.rb +6 -0
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/ai_guard/api_client.rb +6 -4
- data/lib/datadog/appsec/api_security/route_extractor.rb +7 -4
- data/lib/datadog/appsec/configuration.rb +6 -0
- data/lib/datadog/appsec/context.rb +4 -2
- data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +59 -4
- data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +59 -5
- data/lib/datadog/appsec/contrib/graphql/gateway/multiplex.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +4 -0
- data/lib/datadog/appsec/contrib/rack/input_peeker.rb +4 -17
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +21 -0
- data/lib/datadog/appsec/contrib/rails/gateway/request.rb +2 -1
- data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +60 -7
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +4 -0
- data/lib/datadog/appsec/ext.rb +1 -0
- data/lib/datadog/appsec/metrics/collector.rb +18 -1
- data/lib/datadog/appsec/metrics/exporter.rb +9 -3
- data/lib/datadog/appsec/remote.rb +9 -3
- data/lib/datadog/appsec/route_normalizer/rails_route_pattern.rb +176 -0
- data/lib/datadog/appsec/route_normalizer/route_pattern.rb +378 -0
- data/lib/datadog/appsec/route_normalizer/route_text.rb +57 -0
- data/lib/datadog/appsec/route_normalizer.rb +80 -0
- data/lib/datadog/appsec/utils/http/body_reader.rb +61 -0
- data/lib/datadog/core/configuration/components.rb +82 -2
- data/lib/datadog/core/configuration/components_state.rb +6 -1
- data/lib/datadog/core/configuration/settings.rb +0 -3
- data/lib/datadog/core/configuration/supported_configurations.rb +2 -0
- data/lib/datadog/core/evp.rb +11 -0
- data/lib/datadog/core/remote/client/capabilities.rb +34 -7
- data/lib/datadog/core/telemetry/event/app_started.rb +8 -1
- data/lib/datadog/di/base.rb +3 -1
- data/lib/datadog/di/code_tracker.rb +5 -2
- data/lib/datadog/di/component.rb +110 -36
- data/lib/datadog/di/error.rb +10 -0
- data/lib/datadog/di/fatal_exceptions.rb +26 -0
- data/lib/datadog/di/instrumenter.rb +381 -165
- data/lib/datadog/di/probe.rb +14 -0
- data/lib/datadog/di/probe_file_loader.rb +8 -3
- data/lib/datadog/di/probe_manager.rb +67 -9
- data/lib/datadog/di/probe_notification_builder.rb +4 -1
- data/lib/datadog/di/probe_notifier_worker.rb +52 -32
- data/lib/datadog/di/redactor.rb +16 -1
- data/lib/datadog/di/remote.rb +175 -14
- data/lib/datadog/di/serializer.rb +12 -5
- data/lib/datadog/di/transport/input.rb +8 -4
- data/lib/datadog/di.rb +63 -0
- data/lib/datadog/kit/appsec/events/v2.rb +60 -2
- data/lib/datadog/open_feature/component.rb +29 -6
- data/lib/datadog/open_feature/configuration.rb +8 -0
- data/lib/datadog/open_feature/ext.rb +2 -0
- data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +286 -0
- data/lib/datadog/open_feature/flag_evaluation/writer.rb +433 -0
- data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +101 -0
- data/lib/datadog/open_feature/hooks/{flag_eval_hook.rb → flag_eval_metrics_hook.rb} +1 -1
- data/lib/datadog/open_feature/native_evaluator.rb +22 -0
- data/lib/datadog/open_feature/provider.rb +59 -27
- data/lib/datadog/open_feature/transport.rb +55 -1
- data/lib/datadog/opentelemetry/sdk/logs_exporter.rb +5 -12
- data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +4 -11
- data/lib/datadog/opentelemetry/sdk.rb +19 -0
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +1 -1
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +5 -3
- data/lib/datadog/symbol_database/component.rb +164 -47
- data/lib/datadog/symbol_database/configuration.rb +12 -4
- data/lib/datadog/symbol_database/extensions.rb +19 -0
- data/lib/datadog/symbol_database/extractor.rb +124 -87
- data/lib/datadog/symbol_database/file_hash.rb +3 -1
- data/lib/datadog/symbol_database/remote.rb +8 -3
- data/lib/datadog/symbol_database/scope_batcher.rb +7 -3
- data/lib/datadog/symbol_database/uploader.rb +9 -2
- data/lib/datadog/symbol_database.rb +22 -0
- data/lib/datadog/tracing/distributed/baggage.rb +2 -1
- data/lib/datadog/tracing/ext.rb +9 -0
- data/lib/datadog/tracing/remote.rb +34 -3
- data/lib/datadog/version.rb +1 -1
- data/lib/datadog.rb +1 -0
- metadata +19 -6
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'ext'
|
|
4
|
+
require_relative '../core/utils/time'
|
|
4
5
|
require 'open_feature/sdk'
|
|
5
6
|
|
|
6
7
|
module Datadog
|
|
7
8
|
module OpenFeature
|
|
8
9
|
# OpenFeature feature flagging provider backed by Datadog Remote Configuration.
|
|
9
10
|
#
|
|
10
|
-
# Requires openfeature-sdk >= 0.5.1 for flag evaluation metrics support.
|
|
11
|
+
# Requires openfeature-sdk >= 0.5.1 for flag evaluation metrics and EVP hook support.
|
|
12
|
+
#
|
|
13
|
+
# Hook lifecycle note: FlagEvalEVPHook is returned from #hooks so EVP uses the SDK-final
|
|
14
|
+
# EvaluationDetails. This matches FlagEvalMetricsHook and records defaults/errors produced
|
|
15
|
+
# by OpenFeature hook failures or post-provider type validation.
|
|
11
16
|
#
|
|
12
17
|
# Implementation follows the OpenFeature contract of Provider SDK.
|
|
13
18
|
# For details see:
|
|
@@ -70,8 +75,10 @@ module Datadog
|
|
|
70
75
|
end
|
|
71
76
|
|
|
72
77
|
def hooks
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
component = Datadog.send(:components).open_feature
|
|
79
|
+
otel_hook = component&.flag_eval_metrics_hook
|
|
80
|
+
evp_hook = component&.flag_eval_evp_hook
|
|
81
|
+
[otel_hook, evp_hook].compact
|
|
75
82
|
end
|
|
76
83
|
|
|
77
84
|
def fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil)
|
|
@@ -101,57 +108,82 @@ module Datadog
|
|
|
101
108
|
private
|
|
102
109
|
|
|
103
110
|
def evaluate(flag_key, default_value:, expected_type:, evaluation_context:)
|
|
111
|
+
# Stamp evaluation entry time once, here on the eval thread. The EVP path uses this for
|
|
112
|
+
# accurate first/last_evaluation bounds instead of a later hook-fire clock read.
|
|
113
|
+
eval_time_ms = (Core::Utils::Time.now.to_f * 1000).to_i
|
|
114
|
+
|
|
104
115
|
engine = OpenFeature.engine
|
|
105
|
-
return component_not_configured_default(default_value) if engine.nil?
|
|
116
|
+
return component_not_configured_default(default_value, eval_time_ms) if engine.nil?
|
|
117
|
+
|
|
118
|
+
result = fetch_engine_value(engine, flag_key, default_value, expected_type, evaluation_context)
|
|
119
|
+
|
|
120
|
+
# Build metadata before branching so provider-returned details carry eval-entry time.
|
|
121
|
+
flag_meta = build_flag_metadata(result, eval_time_ms)
|
|
122
|
+
|
|
123
|
+
if result.error?
|
|
124
|
+
return sdk_error_details(default_value, result.error_code, result.error_message, result.reason, flag_meta)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
sdk_success_details(result, flag_meta)
|
|
128
|
+
rescue => e
|
|
129
|
+
error_message = "#{e.class}: #{e.message}"
|
|
130
|
+
error_result = Datadog::OpenFeature::ResolutionDetails.build_error(
|
|
131
|
+
value: default_value,
|
|
132
|
+
error_code: Ext::GENERAL,
|
|
133
|
+
error_message: error_message
|
|
134
|
+
)
|
|
135
|
+
error_flag_meta = build_flag_metadata(error_result, eval_time_ms || (Core::Utils::Time.now.to_f * 1000).to_i)
|
|
106
136
|
|
|
107
|
-
|
|
137
|
+
sdk_error_details(default_value, Ext::GENERAL, error_message, Ext::ERROR, error_flag_meta)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def fetch_engine_value(engine, flag_key, default_value, expected_type, evaluation_context)
|
|
141
|
+
engine.fetch_value(
|
|
108
142
|
flag_key,
|
|
109
143
|
default_value: default_value,
|
|
110
144
|
expected_type: expected_type,
|
|
111
145
|
evaluation_context: evaluation_context
|
|
112
146
|
)
|
|
147
|
+
end
|
|
113
148
|
|
|
114
|
-
|
|
115
|
-
return ::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
|
116
|
-
value: default_value,
|
|
117
|
-
error_code: result.error_code,
|
|
118
|
-
error_message: result.error_message,
|
|
119
|
-
reason: result.reason
|
|
120
|
-
)
|
|
121
|
-
end
|
|
122
|
-
|
|
149
|
+
def sdk_success_details(result, flag_meta)
|
|
123
150
|
::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
|
124
151
|
value: result.value,
|
|
125
152
|
variant: result.variant,
|
|
126
153
|
reason: result.reason,
|
|
127
|
-
flag_metadata:
|
|
154
|
+
flag_metadata: flag_meta,
|
|
128
155
|
)
|
|
129
|
-
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def sdk_error_details(default_value, error_code, error_message, reason, flag_meta = {})
|
|
130
159
|
::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
|
131
160
|
value: default_value,
|
|
132
|
-
error_code:
|
|
133
|
-
error_message:
|
|
134
|
-
reason:
|
|
161
|
+
error_code: error_code,
|
|
162
|
+
error_message: error_message,
|
|
163
|
+
reason: reason,
|
|
164
|
+
flag_metadata: flag_meta
|
|
135
165
|
)
|
|
136
166
|
end
|
|
137
167
|
|
|
138
|
-
def build_flag_metadata(result)
|
|
139
|
-
metadata = result.flag_metadata || {}
|
|
168
|
+
def build_flag_metadata(result, eval_time_ms)
|
|
169
|
+
metadata = result.flag_metadata&.dup || {}
|
|
140
170
|
allocation_key = result.allocation_key
|
|
141
|
-
if allocation_key && !allocation_key.empty?
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
171
|
+
metadata['__dd_allocation_key'] = allocation_key if allocation_key && !allocation_key.empty?
|
|
172
|
+
|
|
173
|
+
# Eval-time stamped at provider entry; the EVP hook reads 'dd.eval.timestamp_ms' for
|
|
174
|
+
# accurate first/last_evaluation bounds (it falls back to hook-fire time when absent).
|
|
175
|
+
metadata['dd.eval.timestamp_ms'] = eval_time_ms
|
|
145
176
|
|
|
146
177
|
metadata
|
|
147
178
|
end
|
|
148
179
|
|
|
149
|
-
def component_not_configured_default(value)
|
|
180
|
+
def component_not_configured_default(value, eval_time_ms)
|
|
150
181
|
::OpenFeature::SDK::Provider::ResolutionDetails.new(
|
|
151
182
|
value: value,
|
|
152
183
|
error_code: Ext::PROVIDER_FATAL,
|
|
153
184
|
error_message: "Datadog's OpenFeature component must be configured",
|
|
154
|
-
reason: Ext::ERROR
|
|
185
|
+
reason: Ext::ERROR,
|
|
186
|
+
flag_metadata: {'dd.eval.timestamp_ms' => eval_time_ms}
|
|
155
187
|
)
|
|
156
188
|
end
|
|
157
189
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative '../core/encoding'
|
|
4
|
+
require_relative '../core/evp'
|
|
4
5
|
require_relative '../core/transport/http'
|
|
5
6
|
require_relative '../core/transport/http/env'
|
|
6
7
|
require_relative '../core/transport/http/api/endpoint'
|
|
@@ -12,6 +13,7 @@ module Datadog
|
|
|
12
13
|
module OpenFeature
|
|
13
14
|
module Transport
|
|
14
15
|
class HTTP
|
|
16
|
+
# API spec for the EVP exposures endpoint.
|
|
15
17
|
class Spec
|
|
16
18
|
def initialize
|
|
17
19
|
@endpoint = Core::Transport::HTTP::API::Endpoint.new(
|
|
@@ -23,7 +25,30 @@ module Datadog
|
|
|
23
25
|
def call(env, &block)
|
|
24
26
|
@endpoint.call(env) do |request_env|
|
|
25
27
|
request_env.headers['Content-Type'] = env.request.parcel.content_type
|
|
26
|
-
request_env.headers[
|
|
28
|
+
request_env.headers[Core::EVP::SUBDOMAIN_HEADER_NAME] =
|
|
29
|
+
Core::EVP::EVENT_PLATFORM_INTAKE_SUBDOMAIN
|
|
30
|
+
request_env.body = env.request.parcel.data
|
|
31
|
+
|
|
32
|
+
block.call(request_env)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# API spec for the EVP flagevaluation endpoint.
|
|
38
|
+
# Path: /evp_proxy/v2/api/v2/flagevaluation
|
|
39
|
+
# Header: X-Datadog-EVP-Subdomain: event-platform-intake (same as exposures)
|
|
40
|
+
class FlagevaluationsSpec
|
|
41
|
+
def initialize
|
|
42
|
+
@endpoint = Core::Transport::HTTP::API::Endpoint.new(
|
|
43
|
+
:post, '/evp_proxy/v2/api/v2/flagevaluation'
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def call(env, &block)
|
|
48
|
+
@endpoint.call(env) do |request_env|
|
|
49
|
+
request_env.headers['Content-Type'] = env.request.parcel.content_type
|
|
50
|
+
request_env.headers[Core::EVP::SUBDOMAIN_HEADER_NAME] =
|
|
51
|
+
Core::EVP::EVENT_PLATFORM_INTAKE_SUBDOMAIN
|
|
27
52
|
request_env.body = env.request.parcel.data
|
|
28
53
|
|
|
29
54
|
block.call(request_env)
|
|
@@ -38,6 +63,14 @@ module Datadog
|
|
|
38
63
|
) { |t| t.api('exposures', HTTP::Spec.new) }.to_transport(self)
|
|
39
64
|
end
|
|
40
65
|
|
|
66
|
+
# Build a transport instance for the flagevaluation EVP endpoint.
|
|
67
|
+
def self.build_flagevaluations(agent_settings:, logger:)
|
|
68
|
+
Core::Transport::HTTP.build(
|
|
69
|
+
agent_settings: agent_settings,
|
|
70
|
+
logger: logger
|
|
71
|
+
) { |t| t.api('flagevaluations', HTTP::FlagevaluationsSpec.new) }.to_transport(self)
|
|
72
|
+
end
|
|
73
|
+
|
|
41
74
|
def initialize(apis, default_api, logger:)
|
|
42
75
|
@api = apis[default_api]
|
|
43
76
|
@logger = logger
|
|
@@ -61,6 +94,27 @@ module Datadog
|
|
|
61
94
|
|
|
62
95
|
Core::Transport::InternalErrorResponse.new(e)
|
|
63
96
|
end
|
|
97
|
+
|
|
98
|
+
# POST a flag evaluations batch to /evp_proxy/v2/api/v2/flagevaluation.
|
|
99
|
+
# Mirrors send_exposures; uses the FlagevaluationsSpec endpoint.
|
|
100
|
+
def send_flag_evaluations(payload)
|
|
101
|
+
encoder = Core::Encoding::JSONEncoder
|
|
102
|
+
parcel = Core::Transport::Parcel.new(
|
|
103
|
+
encoder.encode(payload),
|
|
104
|
+
content_type: encoder.content_type
|
|
105
|
+
)
|
|
106
|
+
request = Core::Transport::Request.new(parcel)
|
|
107
|
+
|
|
108
|
+
@api.endpoint.call(Core::Transport::HTTP::Env.new(request)) do |env|
|
|
109
|
+
@api.call(env)
|
|
110
|
+
end
|
|
111
|
+
rescue => e
|
|
112
|
+
message = "Internal error during request. Cause: #{e.class}: #{e.message} " \
|
|
113
|
+
"Location: #{Array(e.backtrace).first}"
|
|
114
|
+
@logger.debug(message)
|
|
115
|
+
|
|
116
|
+
Core::Transport::InternalErrorResponse.new(e)
|
|
117
|
+
end
|
|
64
118
|
end
|
|
65
119
|
end
|
|
66
120
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'opentelemetry/exporter/otlp_logs'
|
|
4
|
+
require_relative '../sdk'
|
|
4
5
|
|
|
5
6
|
module Datadog
|
|
6
7
|
module OpenTelemetry
|
|
@@ -10,27 +11,19 @@ module Datadog
|
|
|
10
11
|
METRIC_EXPORT_SUCCESSES = 'otel.logs_export_successes'
|
|
11
12
|
METRIC_EXPORT_FAILURES = 'otel.logs_export_failures'
|
|
12
13
|
METRIC_LOG_RECORDS = 'otel.log_records'
|
|
13
|
-
TELEMETRY_NAMESPACE = 'tracers'
|
|
14
|
-
TELEMETRY_TAGS = {'protocol' => 'http', 'encoding' => 'protobuf'}.freeze
|
|
15
14
|
|
|
16
15
|
def export(log_records, timeout: nil)
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
SDK.telemetry_inc(METRIC_EXPORT_ATTEMPTS, 1)
|
|
17
|
+
SDK.telemetry_inc(METRIC_LOG_RECORDS, log_records.size)
|
|
19
18
|
result = super
|
|
20
19
|
metric_name = (result == 0) ? METRIC_EXPORT_SUCCESSES : METRIC_EXPORT_FAILURES
|
|
21
|
-
|
|
20
|
+
SDK.telemetry_inc(metric_name, 1)
|
|
22
21
|
result
|
|
23
22
|
rescue => e
|
|
24
23
|
Datadog.logger.warn("Failed to export OpenTelemetry Logs: #{e.class}: #{e.message}")
|
|
25
|
-
|
|
24
|
+
SDK.telemetry_inc(METRIC_EXPORT_FAILURES, 1)
|
|
26
25
|
raise
|
|
27
26
|
end
|
|
28
|
-
|
|
29
|
-
private
|
|
30
|
-
|
|
31
|
-
def telemetry
|
|
32
|
-
Datadog.send(:components).telemetry
|
|
33
|
-
end
|
|
34
27
|
end
|
|
35
28
|
end
|
|
36
29
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'opentelemetry/exporter/otlp_metrics'
|
|
4
|
+
require_relative '../sdk'
|
|
4
5
|
|
|
5
6
|
module Datadog
|
|
6
7
|
module OpenTelemetry
|
|
@@ -9,26 +10,18 @@ module Datadog
|
|
|
9
10
|
METRIC_EXPORT_ATTEMPTS = 'otel.metrics_export_attempts'
|
|
10
11
|
METRIC_EXPORT_SUCCESSES = 'otel.metrics_export_successes'
|
|
11
12
|
METRIC_EXPORT_FAILURES = 'otel.metrics_export_failures'
|
|
12
|
-
TELEMETRY_NAMESPACE = 'tracers'
|
|
13
|
-
TELEMETRY_TAGS = {'protocol' => "http", 'encoding' => 'protobuf'}
|
|
14
13
|
|
|
15
14
|
def export(metrics, timeout: nil)
|
|
16
|
-
|
|
15
|
+
SDK.telemetry_inc(METRIC_EXPORT_ATTEMPTS, 1)
|
|
17
16
|
result = super
|
|
18
17
|
metric_name = (result == 0) ? METRIC_EXPORT_SUCCESSES : METRIC_EXPORT_FAILURES
|
|
19
|
-
|
|
18
|
+
SDK.telemetry_inc(metric_name, 1)
|
|
20
19
|
result
|
|
21
20
|
rescue => e
|
|
22
21
|
Datadog.logger.error("Failed to export OpenTelemetry Metrics: #{e.class}: #{e.message}")
|
|
23
|
-
|
|
22
|
+
SDK.telemetry_inc(METRIC_EXPORT_FAILURES, 1)
|
|
24
23
|
raise
|
|
25
24
|
end
|
|
26
|
-
|
|
27
|
-
private
|
|
28
|
-
|
|
29
|
-
def telemetry
|
|
30
|
-
Datadog.send(:components).telemetry
|
|
31
|
-
end
|
|
32
25
|
end
|
|
33
26
|
end
|
|
34
27
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../tracing/ext'
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module OpenTelemetry
|
|
7
|
+
module SDK
|
|
8
|
+
TELEMETRY_TAGS = {'protocol' => 'http', 'encoding' => 'protobuf'}.freeze
|
|
9
|
+
|
|
10
|
+
def self.telemetry_inc(metric_name, value)
|
|
11
|
+
telemetry&.inc(Datadog::Tracing::Ext::TELEMETRY_METRICS_NAMESPACE, metric_name, value, tags: TELEMETRY_TAGS)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.telemetry
|
|
15
|
+
Datadog.send(:components).telemetry
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -49,7 +49,7 @@ module Datadog
|
|
|
49
49
|
# profiler overhead!
|
|
50
50
|
dynamic_sampling_rate_enabled: true,
|
|
51
51
|
skip_idle_samples_for_testing: false,
|
|
52
|
-
idle_sampling_helper: IdleSamplingHelper.new
|
|
52
|
+
idle_sampling_helper: IdleSamplingHelper.new(thread_context_collector: thread_context_collector)
|
|
53
53
|
)
|
|
54
54
|
unless dynamic_sampling_rate_enabled
|
|
55
55
|
Datadog.logger.warn(
|
|
@@ -10,6 +10,7 @@ module Datadog
|
|
|
10
10
|
class IdleSamplingHelper
|
|
11
11
|
# @rbs @worker_thread: untyped
|
|
12
12
|
# @rbs @start_stop_mutex: ::Thread::Mutex
|
|
13
|
+
# @rbs @thread_context_collector: Datadog::Profiling::Collectors::ThreadContext?
|
|
13
14
|
|
|
14
15
|
private
|
|
15
16
|
|
|
@@ -17,10 +18,11 @@ module Datadog
|
|
|
17
18
|
|
|
18
19
|
public
|
|
19
20
|
|
|
20
|
-
#: () -> void
|
|
21
|
-
def initialize
|
|
21
|
+
#: (thread_context_collector: Datadog::Profiling::Collectors::ThreadContext) -> void
|
|
22
|
+
def initialize(thread_context_collector:)
|
|
22
23
|
@worker_thread = nil
|
|
23
24
|
@start_stop_mutex = Mutex.new
|
|
25
|
+
@thread_context_collector = thread_context_collector
|
|
24
26
|
end
|
|
25
27
|
|
|
26
28
|
#: () -> (nil | true)
|
|
@@ -37,7 +39,7 @@ module Datadog
|
|
|
37
39
|
@worker_thread = Thread.new do
|
|
38
40
|
Thread.current.name = self.class.name
|
|
39
41
|
|
|
40
|
-
self.class._native_idle_sampling_loop(self)
|
|
42
|
+
self.class._native_idle_sampling_loop(self, @thread_context_collector)
|
|
41
43
|
|
|
42
44
|
Datadog.logger.debug("IdleSamplingHelper thread stopping cleanly")
|
|
43
45
|
rescue Exception => e # rubocop:disable Lint/RescueException
|