cw-datadog 2.23.0.2 → 2.23.0.3
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/ext/datadog_profiling_native_extension/extconf.rb +4 -2
- data/ext/libdatadog_api/library_config.c +12 -11
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/appsec/api_security/route_extractor.rb +20 -5
- data/lib/datadog/appsec/api_security/sampler.rb +3 -1
- 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.rb +1 -1
- data/lib/datadog/appsec/remote.rb +4 -0
- data/lib/datadog/appsec/response.rb +18 -4
- data/lib/datadog/core/cloudwise/client.rb +364 -25
- data/lib/datadog/core/cloudwise/component.rb +197 -52
- data/lib/datadog/core/cloudwise/docc_heartbeat_worker.rb +105 -0
- data/lib/datadog/core/cloudwise/docc_operation_worker.rb +191 -0
- data/lib/datadog/core/cloudwise/docc_registration_worker.rb +89 -0
- data/lib/datadog/core/cloudwise/license_worker.rb +3 -1
- data/lib/datadog/core/cloudwise/probe_state.rb +134 -12
- data/lib/datadog/core/configuration/components.rb +10 -9
- data/lib/datadog/core/configuration/settings.rb +28 -0
- data/lib/datadog/core/configuration/supported_configurations.rb +5 -2
- data/lib/datadog/core/remote/client/capabilities.rb +7 -0
- data/lib/datadog/core/remote/component.rb +2 -2
- 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 +23 -35
- data/lib/datadog/core/telemetry/component.rb +26 -13
- data/lib/datadog/core/telemetry/event/app_started.rb +67 -49
- data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +27 -4
- 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/telemetry/worker.rb +51 -6
- data/lib/datadog/core/transport/http/adapters/net.rb +2 -0
- data/lib/datadog/core/transport/http/client.rb +69 -0
- data/lib/datadog/core/utils/only_once_successful.rb +6 -2
- data/lib/datadog/data_streams/transport/http/client.rb +4 -32
- data/lib/datadog/data_streams/transport/stats.rb +1 -1
- data/lib/datadog/di/probe_notification_builder.rb +35 -13
- 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/input.rb +2 -2
- 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 +59 -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 +13 -0
- data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
- data/lib/datadog/open_feature/provider.rb +134 -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/profiling/component.rb +6 -0
- data/lib/datadog/profiling/profiler.rb +4 -0
- data/lib/datadog/profiling.rb +1 -2
- data/lib/datadog/single_step_instrument.rb +1 -1
- data/lib/datadog/tracing/contrib/cloudwise/propagation.rb +164 -7
- data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +22 -17
- data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
- data/lib/datadog/tracing/contrib/karafka/patcher.rb +14 -0
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +6 -2
- 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/transport/http/api.rb +40 -1
- data/lib/datadog/tracing/transport/http/client.rb +12 -26
- data/lib/datadog/tracing/transport/http/traces.rb +4 -2
- data/lib/datadog/tracing/transport/trace_formatter.rb +16 -0
- data/lib/datadog/version.rb +2 -2
- data/lib/datadog.rb +1 -0
- metadata +38 -15
- data/lib/datadog/core/cloudwise/IMPLEMENTATION_V2.md +0 -517
- data/lib/datadog/core/cloudwise/QUICKSTART.md +0 -398
- data/lib/datadog/core/cloudwise/README.md +0 -722
- 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
|
@@ -76,9 +76,11 @@ module Datadog
|
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
code = result[:code]
|
|
79
|
+
# msg 字段在响应的顶层(result[:message]),是字符串 "true" 或 "false"
|
|
80
|
+
msg = result[:message]
|
|
79
81
|
|
|
80
82
|
# License 校验成功 (code == 1000)
|
|
81
|
-
if code == CODE_SUCCESS
|
|
83
|
+
if code == CODE_SUCCESS && msg == 'true'
|
|
82
84
|
Cloudwise.log_debug { 'Cloudwise: License valid' }
|
|
83
85
|
probe_state.mark_license_valid!
|
|
84
86
|
@failure_count = 0 # 重置失败计数
|
|
@@ -15,6 +15,12 @@ module Datadog
|
|
|
15
15
|
@heartbeat_active = false # 心跳是否正常
|
|
16
16
|
@license_valid = false # License 是否校验通过
|
|
17
17
|
@app_registered = false # 应用是否已注册(注册失败不影响采集)
|
|
18
|
+
|
|
19
|
+
# 融合模式状态
|
|
20
|
+
@docc_registered = false # 注册是否成功
|
|
21
|
+
@docc_heartbeat_active = false # 心跳是否正常
|
|
22
|
+
@docc_operation_active = true # 操作状态(默认为 true,agent_stop 时为 false)
|
|
23
|
+
@use_docc_mode = false # 是否使用 模式
|
|
18
24
|
end
|
|
19
25
|
|
|
20
26
|
# Host ID 相关
|
|
@@ -91,10 +97,81 @@ module Datadog
|
|
|
91
97
|
end
|
|
92
98
|
end
|
|
93
99
|
|
|
94
|
-
#
|
|
100
|
+
# DOCC 注册相关
|
|
101
|
+
def mark_docc_registered!
|
|
102
|
+
@mutex.synchronize do
|
|
103
|
+
return if @docc_registered
|
|
104
|
+
@docc_registered = true
|
|
105
|
+
Cloudwise.log_debug { 'Cloudwise DOCC: Extension registered' }
|
|
106
|
+
log_status_change
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def mark_docc_unregistered!
|
|
111
|
+
@mutex.synchronize do
|
|
112
|
+
return unless @docc_registered
|
|
113
|
+
@docc_registered = false
|
|
114
|
+
Cloudwise.log_warn { 'Cloudwise DOCC: Extension not registered' }
|
|
115
|
+
log_status_change
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# DOCC 心跳相关
|
|
120
|
+
def mark_docc_heartbeat_active!
|
|
121
|
+
@mutex.synchronize do
|
|
122
|
+
return if @docc_heartbeat_active
|
|
123
|
+
@docc_heartbeat_active = true
|
|
124
|
+
Cloudwise.log_debug { 'Cloudwise DOCC: Heartbeat active' }
|
|
125
|
+
log_status_change
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def mark_docc_heartbeat_inactive!
|
|
130
|
+
@mutex.synchronize do
|
|
131
|
+
return unless @docc_heartbeat_active
|
|
132
|
+
@docc_heartbeat_active = false
|
|
133
|
+
Cloudwise.log_warn { 'Cloudwise DOCC: Heartbeat inactive' }
|
|
134
|
+
log_status_change
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# DOCC 操作相关
|
|
139
|
+
def mark_docc_operation_active!
|
|
140
|
+
@mutex.synchronize do
|
|
141
|
+
return if @docc_operation_active
|
|
142
|
+
@docc_operation_active = true
|
|
143
|
+
Cloudwise.log_info { 'Cloudwise DOCC: Agent started - data collection enabled' }
|
|
144
|
+
log_status_change
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def mark_docc_operation_inactive!
|
|
149
|
+
@mutex.synchronize do
|
|
150
|
+
return unless @docc_operation_active
|
|
151
|
+
@docc_operation_active = false
|
|
152
|
+
Cloudwise.log_info { 'Cloudwise DOCC: Agent stopped - data collection disabled' }
|
|
153
|
+
log_status_change
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# 设置使用 DOCC 模式
|
|
158
|
+
def enable_docc_mode!
|
|
159
|
+
@mutex.synchronize do
|
|
160
|
+
@use_docc_mode = true
|
|
161
|
+
Cloudwise.log_debug { 'Cloudwise: Using DOCC integrated mode' }
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# 探针是否可以采集数据
|
|
166
|
+
# 如果使用 DOCC 模式:需要 DOCC 心跳 + License + Operation 都正常
|
|
167
|
+
# 如果使用传统模式:需要 Host ID + 心跳 + License 都正常
|
|
95
168
|
def can_collect_data?
|
|
96
169
|
@mutex.synchronize do
|
|
97
|
-
|
|
170
|
+
if @use_docc_mode
|
|
171
|
+
@docc_heartbeat_active && @license_valid && @docc_operation_active
|
|
172
|
+
else
|
|
173
|
+
@host_id_ready && @heartbeat_active && @license_valid
|
|
174
|
+
end
|
|
98
175
|
end
|
|
99
176
|
end
|
|
100
177
|
|
|
@@ -115,6 +192,22 @@ module Datadog
|
|
|
115
192
|
@mutex.synchronize { @app_registered }
|
|
116
193
|
end
|
|
117
194
|
|
|
195
|
+
def docc_registered?
|
|
196
|
+
@mutex.synchronize { @docc_registered }
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def docc_heartbeat_active?
|
|
200
|
+
@mutex.synchronize { @docc_heartbeat_active }
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def docc_operation_active?
|
|
204
|
+
@mutex.synchronize { @docc_operation_active }
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def using_docc_mode?
|
|
208
|
+
@mutex.synchronize { @use_docc_mode }
|
|
209
|
+
end
|
|
210
|
+
|
|
118
211
|
# 兼容旧接口
|
|
119
212
|
def suspended?
|
|
120
213
|
!can_collect_data?
|
|
@@ -127,13 +220,27 @@ module Datadog
|
|
|
127
220
|
# 获取当前状态摘要
|
|
128
221
|
def status
|
|
129
222
|
@mutex.synchronize do
|
|
130
|
-
{
|
|
223
|
+
base_status = {
|
|
131
224
|
host_id_ready: @host_id_ready,
|
|
132
225
|
heartbeat_active: @heartbeat_active,
|
|
133
226
|
license_valid: @license_valid,
|
|
134
|
-
app_registered: @app_registered
|
|
135
|
-
can_collect_data: @host_id_ready && @heartbeat_active && @license_valid
|
|
227
|
+
app_registered: @app_registered
|
|
136
228
|
}
|
|
229
|
+
|
|
230
|
+
if @use_docc_mode
|
|
231
|
+
base_status.merge(
|
|
232
|
+
use_docc_mode: true,
|
|
233
|
+
docc_registered: @docc_registered,
|
|
234
|
+
docc_heartbeat_active: @docc_heartbeat_active,
|
|
235
|
+
docc_operation_active: @docc_operation_active,
|
|
236
|
+
can_collect_data: @docc_heartbeat_active && @license_valid && @docc_operation_active
|
|
237
|
+
)
|
|
238
|
+
else
|
|
239
|
+
base_status.merge(
|
|
240
|
+
use_docc_mode: false,
|
|
241
|
+
can_collect_data: @host_id_ready && @heartbeat_active && @license_valid
|
|
242
|
+
)
|
|
243
|
+
end
|
|
137
244
|
end
|
|
138
245
|
end
|
|
139
246
|
|
|
@@ -143,15 +250,30 @@ module Datadog
|
|
|
143
250
|
# 它不能再次获取锁,所以直接读取实例变量
|
|
144
251
|
def log_status_change
|
|
145
252
|
# 直接读取实例变量,避免递归锁定(不调用 can_collect_data? 方法)
|
|
146
|
-
if @
|
|
147
|
-
|
|
253
|
+
if @use_docc_mode
|
|
254
|
+
# DOCC 模式状态日志
|
|
255
|
+
if @docc_heartbeat_active && @license_valid && @docc_operation_active
|
|
256
|
+
Cloudwise.log_debug { 'Cloudwise DOCC: Probe ACTIVE - data collection enabled' }
|
|
257
|
+
else
|
|
258
|
+
reasons = []
|
|
259
|
+
reasons << 'DOCC Heartbeat inactive' unless @docc_heartbeat_active
|
|
260
|
+
reasons << 'License invalid' unless @license_valid
|
|
261
|
+
reasons << 'Agent stopped by operation' unless @docc_operation_active
|
|
262
|
+
|
|
263
|
+
Cloudwise.log_debug { "Cloudwise DOCC: Probe SUSPENDED - data collection disabled (#{reasons.join(', ')})" }
|
|
264
|
+
end
|
|
148
265
|
else
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
266
|
+
# 传统模式状态日志
|
|
267
|
+
if @host_id_ready && @heartbeat_active && @license_valid
|
|
268
|
+
Cloudwise.log_debug { 'Cloudwise: Probe ACTIVE - data collection enabled' }
|
|
269
|
+
else
|
|
270
|
+
reasons = []
|
|
271
|
+
reasons << 'Host ID not ready' unless @host_id_ready
|
|
272
|
+
reasons << 'Heartbeat inactive' unless @heartbeat_active
|
|
273
|
+
reasons << 'License invalid' unless @license_valid
|
|
153
274
|
|
|
154
|
-
|
|
275
|
+
Cloudwise.log_debug { "Cloudwise: Probe SUSPENDED - data collection disabled (#{reasons.join(', ')})" }
|
|
276
|
+
end
|
|
155
277
|
end
|
|
156
278
|
end
|
|
157
279
|
end
|
|
@@ -15,6 +15,7 @@ require_relative '../../tracing/component'
|
|
|
15
15
|
require_relative '../../profiling/component'
|
|
16
16
|
require_relative '../../appsec/component'
|
|
17
17
|
require_relative '../../di/component'
|
|
18
|
+
require_relative '../../open_feature/component'
|
|
18
19
|
require_relative '../../error_tracking/component'
|
|
19
20
|
require_relative '../crashtracking/component'
|
|
20
21
|
require_relative '../environment/agent_info'
|
|
@@ -151,6 +152,7 @@ module Datadog
|
|
|
151
152
|
attr_reader \
|
|
152
153
|
:health_metrics,
|
|
153
154
|
:settings,
|
|
155
|
+
:agent_settings,
|
|
154
156
|
:logger,
|
|
155
157
|
:remote,
|
|
156
158
|
:profiler,
|
|
@@ -163,7 +165,8 @@ module Datadog
|
|
|
163
165
|
:appsec,
|
|
164
166
|
:agent_info,
|
|
165
167
|
:data_streams,
|
|
166
|
-
:cloudwise
|
|
168
|
+
:cloudwise,
|
|
169
|
+
:open_feature
|
|
167
170
|
|
|
168
171
|
def initialize(settings)
|
|
169
172
|
@settings = settings
|
|
@@ -207,7 +210,7 @@ module Datadog
|
|
|
207
210
|
# This agent_settings is intended for use within Core. If you require
|
|
208
211
|
# agent_settings within a product outside of core you should extend
|
|
209
212
|
# the Core resolver from within your product/component's namespace.
|
|
210
|
-
agent_settings = AgentSettingsResolver.call(settings, logger: @logger)
|
|
213
|
+
@agent_settings = AgentSettingsResolver.call(settings, logger: @logger)
|
|
211
214
|
|
|
212
215
|
# Exposes agent capability information for detection by any components
|
|
213
216
|
@agent_info = Core::Environment::AgentInfo.new(agent_settings, logger: @logger)
|
|
@@ -233,6 +236,7 @@ module Datadog
|
|
|
233
236
|
@runtime_metrics = self.class.build_runtime_metrics_worker(settings, @logger, telemetry)
|
|
234
237
|
@health_metrics = self.class.build_health_metrics(settings, @logger, telemetry)
|
|
235
238
|
@appsec = Datadog::AppSec::Component.build_appsec_component(settings, telemetry: telemetry)
|
|
239
|
+
@open_feature = OpenFeature::Component.build(settings, agent_settings, logger: @logger, telemetry: telemetry)
|
|
236
240
|
@dynamic_instrumentation = Datadog::DI::Component.build(settings, agent_settings, @logger, telemetry: telemetry)
|
|
237
241
|
@error_tracking = Datadog::ErrorTracking::Component.build(settings, @tracer, @logger)
|
|
238
242
|
@data_streams = self.class.build_data_streams(settings, agent_settings, @logger)
|
|
@@ -268,14 +272,8 @@ module Datadog
|
|
|
268
272
|
|
|
269
273
|
# Starts up components
|
|
270
274
|
def startup!(settings, old_state: nil)
|
|
271
|
-
# If Datadog components are not initialized yet (waiting for Cloudwise),
|
|
272
|
-
# skip startup - it will be called after Datadog components are initialized
|
|
273
|
-
unless datadog_components_initialized?
|
|
274
|
-
@pending_startup = { settings: settings, old_state: old_state }
|
|
275
|
-
return
|
|
276
|
-
end
|
|
277
275
|
|
|
278
|
-
telemetry.start(old_state&.telemetry_enabled
|
|
276
|
+
telemetry.start(old_state&.telemetry_enabled?, components: self)
|
|
279
277
|
|
|
280
278
|
if settings.profiling.enabled
|
|
281
279
|
if profiler
|
|
@@ -321,6 +319,9 @@ module Datadog
|
|
|
321
319
|
# Shutdown DI after remote, since remote config triggers DI operations.
|
|
322
320
|
dynamic_instrumentation&.shutdown!
|
|
323
321
|
|
|
322
|
+
# Shutdown OpenFeature component
|
|
323
|
+
open_feature&.shutdown!
|
|
324
|
+
|
|
324
325
|
# Decommission AppSec
|
|
325
326
|
appsec&.shutdown!
|
|
326
327
|
|
|
@@ -1025,6 +1025,34 @@ module Datadog
|
|
|
1025
1025
|
o.default nil
|
|
1026
1026
|
end
|
|
1027
1027
|
|
|
1028
|
+
# Integrated mode - whether agent handles integrated environment
|
|
1029
|
+
# @default `DD_CLOUDWISE_INTEGRATED_MODE` environment variable, otherwise `true`
|
|
1030
|
+
# @return [Boolean]
|
|
1031
|
+
option :integrated_mode do |o|
|
|
1032
|
+
o.type :bool
|
|
1033
|
+
o.env 'DD_CLOUDWISE_INTEGRATED_MODE'
|
|
1034
|
+
o.default true
|
|
1035
|
+
end
|
|
1036
|
+
|
|
1037
|
+
# Token for integrated mode (DOCC interface authentication)
|
|
1038
|
+
# Format: base64 encoded "account_id@user_id"
|
|
1039
|
+
# @default `DD_CLOUDWISE_TOKEN` environment variable
|
|
1040
|
+
# @return [String,nil]
|
|
1041
|
+
option :token do |o|
|
|
1042
|
+
o.type :string, nilable: true
|
|
1043
|
+
o.env 'DD_CLOUDWISE_TOKEN'
|
|
1044
|
+
o.default nil
|
|
1045
|
+
end
|
|
1046
|
+
|
|
1047
|
+
# API 路径前缀,用于在所有 Cloudwise API 请求前添加统一前缀
|
|
1048
|
+
# 例如: '/doop-agent-api' 会将请求从 '/api/v2/traces' 改为 '/doop-agent-api/api/v2/traces'
|
|
1049
|
+
# 优先级: DD_CLOUDWISE_API_PREFIX > integrated_mode ('/apm') > 无前缀
|
|
1050
|
+
option :api_prefix do |o|
|
|
1051
|
+
o.type :string, nilable: true
|
|
1052
|
+
o.env 'DD_CLOUDWISE_API_PREFIX'
|
|
1053
|
+
o.default nil
|
|
1054
|
+
end
|
|
1055
|
+
|
|
1028
1056
|
# Heartbeat interval in seconds
|
|
1029
1057
|
# @default `DD_CLOUDWISE_HEARTBEAT_INTERVAL` environment variable, otherwise `30`
|
|
1030
1058
|
# @return [Integer]
|
|
@@ -34,9 +34,10 @@ module Datadog
|
|
|
34
34
|
"DD_APPSEC_WAF_TIMEOUT" => {version: ["A"]},
|
|
35
35
|
"DD_CLOUDWISE_APP_REGISTRATION_INTERVAL" => {version: ["A"]},
|
|
36
36
|
"DD_CLOUDWISE_ENABLED" => {version: ["A"]},
|
|
37
|
-
"DD_CLOUDWISE_HEARTBEAT_INTERVAL" => {version: ["A"]},
|
|
38
|
-
"DD_CLOUDWISE_LICENSE_CHECK_INTERVAL" => {version: ["A"]},
|
|
39
37
|
"DD_CLOUDWISE_LICENSE_KEY" => {version: ["A"]},
|
|
38
|
+
"DD_CLOUDWISE_TOKEN" => {version: ["A"]},
|
|
39
|
+
"CW_SYS" => {version: ["A"]},
|
|
40
|
+
"DD_CLOUDWISE_API_PREFIX" => {version: ["A"]},
|
|
40
41
|
"DD_CRASHTRACKING_ENABLED" => {version: ["A"]},
|
|
41
42
|
"DD_DATA_STREAMS_ENABLED" => {version: ["A"]},
|
|
42
43
|
"DD_DBM_PROPAGATION_MODE" => {version: ["A"]},
|
|
@@ -48,6 +49,7 @@ module Datadog
|
|
|
48
49
|
"DD_ENV" => {version: ["A"]},
|
|
49
50
|
"DD_ERROR_TRACKING_HANDLED_ERRORS" => {version: ["A"]},
|
|
50
51
|
"DD_ERROR_TRACKING_HANDLED_ERRORS_INCLUDE" => {version: ["A"]},
|
|
52
|
+
"DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED" => {version: ["A"]},
|
|
51
53
|
"DD_GIT_COMMIT_SHA" => {version: ["A"]},
|
|
52
54
|
"DD_GIT_REPOSITORY_URL" => {version: ["A"]},
|
|
53
55
|
"DD_HEALTH_METRICS_ENABLED" => {version: ["A"]},
|
|
@@ -314,6 +316,7 @@ module Datadog
|
|
|
314
316
|
"DD_TRACE_TRILOGY_ENABLED" => {version: ["A"]},
|
|
315
317
|
"DD_TRACE_TRILOGY_PEER_SERVICE" => {version: ["A"]},
|
|
316
318
|
"DD_TRACE_TRILOGY_SERVICE_NAME" => {version: ["A"]},
|
|
319
|
+
"DD_TRACE_WATERDROP_ENABLED" => {version: ["A"]},
|
|
317
320
|
"DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH" => {version: ["A"]},
|
|
318
321
|
"DD_VERSION" => {version: ["A"]},
|
|
319
322
|
"OTEL_TRACES_SAMPLER_ARG" => {version: ["A"]}}.freeze
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative '../../utils/base64'
|
|
4
4
|
require_relative '../../../appsec/remote'
|
|
5
5
|
require_relative '../../../tracing/remote'
|
|
6
|
+
require_relative '../../../open_feature/remote'
|
|
6
7
|
|
|
7
8
|
module Datadog
|
|
8
9
|
module Core
|
|
@@ -38,6 +39,12 @@ module Datadog
|
|
|
38
39
|
register_receivers(Datadog::DI::Remote.receivers(@telemetry))
|
|
39
40
|
end
|
|
40
41
|
|
|
42
|
+
if settings.respond_to?(:open_feature) && settings.open_feature.enabled
|
|
43
|
+
register_capabilities(Datadog::OpenFeature::Remote.capabilities)
|
|
44
|
+
register_products(Datadog::OpenFeature::Remote.products)
|
|
45
|
+
register_receivers(Datadog::OpenFeature::Remote.receivers(@telemetry))
|
|
46
|
+
end
|
|
47
|
+
|
|
41
48
|
register_capabilities(Datadog::Tracing::Remote.capabilities)
|
|
42
49
|
register_products(Datadog::Tracing::Remote.products)
|
|
43
50
|
register_receivers(Datadog::Tracing::Remote.receivers(@telemetry))
|
|
@@ -68,12 +68,12 @@ module Datadog
|
|
|
68
68
|
|
|
69
69
|
# Starts the Remote Configuration worker without waiting for first run
|
|
70
70
|
def start
|
|
71
|
-
@worker.start
|
|
71
|
+
# @worker.start
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
# Is the Remote Configuration worker running?
|
|
75
75
|
def started?
|
|
76
|
-
@worker.started?
|
|
76
|
+
# @worker.started?
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
# If the worker is not initialized, initialize it.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative '../../../core/transport/request'
|
|
4
4
|
require_relative '../../../core/transport/parcel'
|
|
5
|
+
require_relative 'http/config'
|
|
5
6
|
|
|
6
7
|
module Datadog
|
|
7
8
|
module Core
|
|
@@ -21,15 +22,6 @@ module Datadog
|
|
|
21
22
|
class Request < Datadog::Core::Transport::Request
|
|
22
23
|
end
|
|
23
24
|
|
|
24
|
-
# Config response
|
|
25
|
-
module Response
|
|
26
|
-
attr_reader :roots, :targets, :target_files, :client_configs
|
|
27
|
-
|
|
28
|
-
def empty?
|
|
29
|
-
@empty
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
25
|
# Config transport
|
|
34
26
|
class Transport
|
|
35
27
|
attr_reader :client, :apis, :default_api, :current_api_id, :logger
|
|
@@ -38,7 +30,7 @@ module Datadog
|
|
|
38
30
|
@apis = apis
|
|
39
31
|
@logger = logger
|
|
40
32
|
|
|
41
|
-
@client = HTTP::Client.new(current_api, logger: logger)
|
|
33
|
+
@client = Remote::Transport::HTTP::Config::Client.new(current_api, logger: logger)
|
|
42
34
|
end
|
|
43
35
|
|
|
44
36
|
##### there is only one transport! it's negotiation!
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'json'
|
|
4
4
|
|
|
5
|
-
require_relative '
|
|
6
|
-
require_relative 'client'
|
|
5
|
+
require_relative '../../../transport/http/client'
|
|
7
6
|
require_relative '../../../utils/base64'
|
|
8
7
|
require_relative '../../../utils/truncation'
|
|
9
8
|
require_relative '../../../transport/http/response'
|
|
@@ -19,7 +18,6 @@ module Datadog
|
|
|
19
18
|
# Response from HTTP transport for remote configuration
|
|
20
19
|
class Response
|
|
21
20
|
include Datadog::Core::Transport::HTTP::Response
|
|
22
|
-
include Core::Remote::Transport::Config::Response
|
|
23
21
|
|
|
24
22
|
def initialize(http_response, options = {}) # standard:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
25
23
|
super(http_response)
|
|
@@ -114,6 +112,12 @@ module Datadog
|
|
|
114
112
|
end.freeze
|
|
115
113
|
end
|
|
116
114
|
|
|
115
|
+
attr_reader :roots, :targets, :target_files, :client_configs
|
|
116
|
+
|
|
117
|
+
def empty?
|
|
118
|
+
@empty
|
|
119
|
+
end
|
|
120
|
+
|
|
117
121
|
def inspect
|
|
118
122
|
"#{super}, #{
|
|
119
123
|
{
|
|
@@ -174,8 +178,8 @@ module Datadog
|
|
|
174
178
|
end
|
|
175
179
|
end
|
|
176
180
|
|
|
177
|
-
#
|
|
178
|
-
|
|
181
|
+
# Remote transport HTTP client
|
|
182
|
+
class Client < Core::Transport::HTTP::Client
|
|
179
183
|
def send_config_payload(request)
|
|
180
184
|
send_request(request) do |api, env|
|
|
181
185
|
api.send_config(env)
|
|
@@ -240,10 +244,6 @@ module Datadog
|
|
|
240
244
|
end
|
|
241
245
|
end
|
|
242
246
|
end
|
|
243
|
-
|
|
244
|
-
# Add remote configuration behavior to transport components
|
|
245
|
-
###### overrides send_payload! which calls send_<endpoint>! kills any other possible endpoint!
|
|
246
|
-
HTTP::Client.include(Config::Client)
|
|
247
247
|
end
|
|
248
248
|
end
|
|
249
249
|
end
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'json'
|
|
4
4
|
|
|
5
|
-
require_relative '
|
|
6
|
-
require_relative 'client'
|
|
5
|
+
require_relative '../../../transport/http/client'
|
|
7
6
|
require_relative '../../../transport/http/response'
|
|
8
7
|
require_relative '../../../transport/http/api/endpoint'
|
|
9
8
|
|
|
@@ -17,7 +16,6 @@ module Datadog
|
|
|
17
16
|
# Response from HTTP transport for agent feature negotiation
|
|
18
17
|
class Response
|
|
19
18
|
include Datadog::Core::Transport::HTTP::Response
|
|
20
|
-
include Core::Remote::Transport::Negotiation::Response
|
|
21
19
|
|
|
22
20
|
def initialize(http_response, options = {})
|
|
23
21
|
super(http_response)
|
|
@@ -29,10 +27,24 @@ module Datadog
|
|
|
29
27
|
@config = options[:config]
|
|
30
28
|
@span_events = options[:span_events]
|
|
31
29
|
end
|
|
30
|
+
|
|
31
|
+
# @!attribute [r] version
|
|
32
|
+
# The version of the agent.
|
|
33
|
+
# @return [String]
|
|
34
|
+
# @!attribute [r] endpoints
|
|
35
|
+
# The HTTP endpoints the agent supports.
|
|
36
|
+
# @return [Array<String>]
|
|
37
|
+
# @!attribute [r] config
|
|
38
|
+
# The agent configuration. These are configured by the user when starting the agent, as well as any defaults.
|
|
39
|
+
# @return [Hash]
|
|
40
|
+
# @!attribute [r] span_events
|
|
41
|
+
# Whether the agent supports the top-level span events field in flushed spans.
|
|
42
|
+
# @return [Boolean,nil]
|
|
43
|
+
attr_reader :version, :endpoints, :config, :span_events
|
|
32
44
|
end
|
|
33
45
|
|
|
34
|
-
#
|
|
35
|
-
|
|
46
|
+
# Remote negotiation HTTP client
|
|
47
|
+
class Client < Core::Transport::HTTP::Client
|
|
36
48
|
def send_info_payload(request)
|
|
37
49
|
send_request(request) do |api, env|
|
|
38
50
|
api.send_info(env)
|
|
@@ -92,9 +104,6 @@ module Datadog
|
|
|
92
104
|
end
|
|
93
105
|
end
|
|
94
106
|
end
|
|
95
|
-
|
|
96
|
-
# Add negotiation behavior to transport components
|
|
97
|
-
HTTP::Client.include(Negotiation::Client)
|
|
98
107
|
end
|
|
99
108
|
end
|
|
100
109
|
end
|
|
@@ -4,6 +4,8 @@ require_relative '../../environment/container'
|
|
|
4
4
|
require_relative '../../environment/ext'
|
|
5
5
|
require_relative '../../transport/ext'
|
|
6
6
|
require_relative '../../transport/http'
|
|
7
|
+
require_relative 'config'
|
|
8
|
+
require_relative 'negotiation'
|
|
7
9
|
|
|
8
10
|
# TODO: Improve negotiation to allow per endpoint selection
|
|
9
11
|
#
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative '../../../core/transport/request'
|
|
4
|
+
require_relative 'http/negotiation'
|
|
4
5
|
|
|
5
6
|
# TODO: Resolve conceptual conundrum
|
|
6
7
|
#
|
|
@@ -30,23 +31,6 @@ module Datadog
|
|
|
30
31
|
class Request < Datadog::Core::Transport::Request
|
|
31
32
|
end
|
|
32
33
|
|
|
33
|
-
# Negotiation response
|
|
34
|
-
module Response
|
|
35
|
-
# @!attribute [r] version
|
|
36
|
-
# The version of the agent.
|
|
37
|
-
# @return [String]
|
|
38
|
-
# @!attribute [r] endpoints
|
|
39
|
-
# The HTTP endpoints the agent supports.
|
|
40
|
-
# @return [Array<String>]
|
|
41
|
-
# @!attribute [r] config
|
|
42
|
-
# The agent configuration. These are configured by the user when starting the agent, as well as any defaults.
|
|
43
|
-
# @return [Hash]
|
|
44
|
-
# @!attribute [r] span_events
|
|
45
|
-
# Whether the agent supports the top-level span events field in flushed spans.
|
|
46
|
-
# @return [Boolean,nil]
|
|
47
|
-
attr_reader :version, :endpoints, :config, :span_events
|
|
48
|
-
end
|
|
49
|
-
|
|
50
34
|
# Negotiation transport
|
|
51
35
|
class Transport
|
|
52
36
|
attr_reader :client, :apis, :default_api, :current_api_id, :logger
|
|
@@ -55,7 +39,7 @@ module Datadog
|
|
|
55
39
|
@apis = apis
|
|
56
40
|
@logger = logger
|
|
57
41
|
|
|
58
|
-
@client = HTTP::Client.new(current_api, logger: logger)
|
|
42
|
+
@client = Remote::Transport::HTTP::Negotiation::Client.new(current_api, logger: logger)
|
|
59
43
|
end
|
|
60
44
|
|
|
61
45
|
def send_info
|
|
@@ -25,49 +25,45 @@ module Datadog
|
|
|
25
25
|
def start
|
|
26
26
|
logger.debug { "remote worker starting (pid: #{Process.pid})" }
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
@mutex.synchronize do
|
|
29
|
+
if @stopped
|
|
30
|
+
logger.debug('remote worker: refusing to restart after previous stop')
|
|
31
|
+
return
|
|
32
|
+
end
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
logger.debug('remote worker: refusing to restart after previous stop')
|
|
32
|
-
return
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
return if @starting || @started
|
|
34
|
+
return if @starting || @started
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
@starting = true
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
thread = Thread.new { poll(@interval) }
|
|
39
|
+
thread.name = self.class.name
|
|
40
|
+
thread.thread_variable_set(:fork_safe, true)
|
|
41
|
+
@thr = thread
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
@started = true
|
|
44
|
+
@starting = false
|
|
45
|
+
end
|
|
46
46
|
|
|
47
47
|
logger.debug { 'remote worker started' }
|
|
48
|
-
ensure
|
|
49
|
-
release_lock
|
|
50
48
|
end
|
|
51
49
|
|
|
52
50
|
def stop
|
|
53
51
|
logger.debug { "remote worker stopping (pid: #{Process.pid})" }
|
|
54
52
|
|
|
55
|
-
|
|
53
|
+
@mutex.synchronize do
|
|
54
|
+
thread = @thr
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
if thread
|
|
57
|
+
thread.kill
|
|
58
|
+
thread.join
|
|
59
|
+
end
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
@started = false
|
|
62
|
+
@thr = nil
|
|
63
|
+
@stopped = true
|
|
62
64
|
end
|
|
63
65
|
|
|
64
|
-
@started = false
|
|
65
|
-
@thr = nil
|
|
66
|
-
@stopped = true
|
|
67
|
-
|
|
68
66
|
logger.debug { 'remote worker stopped' }
|
|
69
|
-
ensure
|
|
70
|
-
release_lock
|
|
71
67
|
end
|
|
72
68
|
|
|
73
69
|
def started?
|
|
@@ -76,14 +72,6 @@ module Datadog
|
|
|
76
72
|
|
|
77
73
|
private
|
|
78
74
|
|
|
79
|
-
def acquire_lock
|
|
80
|
-
@mutex.lock
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def release_lock
|
|
84
|
-
@mutex.unlock
|
|
85
|
-
end
|
|
86
|
-
|
|
87
75
|
def poll(interval)
|
|
88
76
|
loop do
|
|
89
77
|
break unless @mutex.synchronize { @starting || @started }
|