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.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/ext/datadog_profiling_native_extension/extconf.rb +4 -2
  3. data/ext/libdatadog_api/library_config.c +12 -11
  4. data/ext/libdatadog_extconf_helpers.rb +1 -1
  5. data/lib/datadog/appsec/api_security/route_extractor.rb +20 -5
  6. data/lib/datadog/appsec/api_security/sampler.rb +3 -1
  7. data/lib/datadog/appsec/assets/blocked.html +8 -0
  8. data/lib/datadog/appsec/assets/blocked.json +1 -1
  9. data/lib/datadog/appsec/assets/blocked.text +3 -1
  10. data/lib/datadog/appsec/assets.rb +1 -1
  11. data/lib/datadog/appsec/remote.rb +4 -0
  12. data/lib/datadog/appsec/response.rb +18 -4
  13. data/lib/datadog/core/cloudwise/client.rb +364 -25
  14. data/lib/datadog/core/cloudwise/component.rb +197 -52
  15. data/lib/datadog/core/cloudwise/docc_heartbeat_worker.rb +105 -0
  16. data/lib/datadog/core/cloudwise/docc_operation_worker.rb +191 -0
  17. data/lib/datadog/core/cloudwise/docc_registration_worker.rb +89 -0
  18. data/lib/datadog/core/cloudwise/license_worker.rb +3 -1
  19. data/lib/datadog/core/cloudwise/probe_state.rb +134 -12
  20. data/lib/datadog/core/configuration/components.rb +10 -9
  21. data/lib/datadog/core/configuration/settings.rb +28 -0
  22. data/lib/datadog/core/configuration/supported_configurations.rb +5 -2
  23. data/lib/datadog/core/remote/client/capabilities.rb +7 -0
  24. data/lib/datadog/core/remote/component.rb +2 -2
  25. data/lib/datadog/core/remote/transport/config.rb +2 -10
  26. data/lib/datadog/core/remote/transport/http/config.rb +9 -9
  27. data/lib/datadog/core/remote/transport/http/negotiation.rb +17 -8
  28. data/lib/datadog/core/remote/transport/http.rb +2 -0
  29. data/lib/datadog/core/remote/transport/negotiation.rb +2 -18
  30. data/lib/datadog/core/remote/worker.rb +23 -35
  31. data/lib/datadog/core/telemetry/component.rb +26 -13
  32. data/lib/datadog/core/telemetry/event/app_started.rb +67 -49
  33. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +27 -4
  34. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +5 -6
  35. data/lib/datadog/core/telemetry/transport/telemetry.rb +1 -2
  36. data/lib/datadog/core/telemetry/worker.rb +51 -6
  37. data/lib/datadog/core/transport/http/adapters/net.rb +2 -0
  38. data/lib/datadog/core/transport/http/client.rb +69 -0
  39. data/lib/datadog/core/utils/only_once_successful.rb +6 -2
  40. data/lib/datadog/data_streams/transport/http/client.rb +4 -32
  41. data/lib/datadog/data_streams/transport/stats.rb +1 -1
  42. data/lib/datadog/di/probe_notification_builder.rb +35 -13
  43. data/lib/datadog/di/transport/diagnostics.rb +2 -2
  44. data/lib/datadog/di/transport/http/diagnostics.rb +2 -4
  45. data/lib/datadog/di/transport/http/input.rb +2 -4
  46. data/lib/datadog/di/transport/input.rb +2 -2
  47. data/lib/datadog/open_feature/component.rb +60 -0
  48. data/lib/datadog/open_feature/configuration.rb +27 -0
  49. data/lib/datadog/open_feature/evaluation_engine.rb +59 -0
  50. data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
  51. data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
  52. data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
  53. data/lib/datadog/open_feature/exposures/event.rb +60 -0
  54. data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
  55. data/lib/datadog/open_feature/exposures/worker.rb +116 -0
  56. data/lib/datadog/open_feature/ext.rb +13 -0
  57. data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
  58. data/lib/datadog/open_feature/provider.rb +134 -0
  59. data/lib/datadog/open_feature/remote.rb +74 -0
  60. data/lib/datadog/open_feature/resolution_details.rb +35 -0
  61. data/lib/datadog/open_feature/transport.rb +72 -0
  62. data/lib/datadog/open_feature.rb +19 -0
  63. data/lib/datadog/profiling/component.rb +6 -0
  64. data/lib/datadog/profiling/profiler.rb +4 -0
  65. data/lib/datadog/profiling.rb +1 -2
  66. data/lib/datadog/single_step_instrument.rb +1 -1
  67. data/lib/datadog/tracing/contrib/cloudwise/propagation.rb +164 -7
  68. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +22 -17
  69. data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
  70. data/lib/datadog/tracing/contrib/karafka/patcher.rb +14 -0
  71. data/lib/datadog/tracing/contrib/rack/middlewares.rb +6 -2
  72. data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +27 -0
  73. data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +48 -0
  74. data/lib/datadog/tracing/contrib/waterdrop/ext.rb +17 -0
  75. data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
  76. data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
  77. data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +46 -0
  78. data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
  79. data/lib/datadog/tracing/contrib/waterdrop.rb +37 -0
  80. data/lib/datadog/tracing/contrib.rb +1 -0
  81. data/lib/datadog/tracing/transport/http/api.rb +40 -1
  82. data/lib/datadog/tracing/transport/http/client.rb +12 -26
  83. data/lib/datadog/tracing/transport/http/traces.rb +4 -2
  84. data/lib/datadog/tracing/transport/trace_formatter.rb +16 -0
  85. data/lib/datadog/version.rb +2 -2
  86. data/lib/datadog.rb +1 -0
  87. metadata +38 -15
  88. data/lib/datadog/core/cloudwise/IMPLEMENTATION_V2.md +0 -517
  89. data/lib/datadog/core/cloudwise/QUICKSTART.md +0 -398
  90. data/lib/datadog/core/cloudwise/README.md +0 -722
  91. data/lib/datadog/core/remote/transport/http/client.rb +0 -49
  92. data/lib/datadog/core/telemetry/transport/http/client.rb +0 -49
  93. 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
- # 探针是否可以采集数据:需要 Host ID + 心跳 + License 都正常
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
- @host_id_ready && @heartbeat_active && @license_valid
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 @host_id_ready && @heartbeat_active && @license_valid
147
- Cloudwise.log_debug { 'Cloudwise: Probe ACTIVE - data collection enabled' }
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
- reasons = []
150
- reasons << 'Host ID not ready' unless @host_id_ready
151
- reasons << 'Heartbeat inactive' unless @heartbeat_active
152
- reasons << 'License invalid' unless @license_valid
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
- Cloudwise.log_debug { "Cloudwise: Probe SUSPENDED - data collection disabled (#{reasons.join(', ')})" }
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 '../config'
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
- # Extensions for HTTP client
178
- module Client
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 '../negotiation'
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
- # Extensions for HTTP client
35
- module Client
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
- acquire_lock
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
- if @stopped
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
- @starting = true
36
+ @starting = true
38
37
 
39
- thread = Thread.new { poll(@interval) }
40
- thread.name = self.class.name
41
- thread.thread_variable_set(:fork_safe, true)
42
- @thr = thread
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
- @started = true
45
- @starting = false
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
- acquire_lock
53
+ @mutex.synchronize do
54
+ thread = @thr
56
55
 
57
- thread = @thr
56
+ if thread
57
+ thread.kill
58
+ thread.join
59
+ end
58
60
 
59
- if thread
60
- thread.kill
61
- thread.join
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 }