cw-datadog 2.23.0.5 → 2.23.0.6
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/lib/datadog/core/cloudwise/client.rb +47 -37
- data/lib/datadog/core/cloudwise/component.rb +40 -39
- data/lib/datadog/core/cloudwise/docc_heartbeat_worker.rb +0 -1
- data/lib/datadog/core/cloudwise/docc_operation_worker.rb +5 -10
- data/lib/datadog/core/cloudwise/docc_registration_worker.rb +0 -1
- data/lib/datadog/core/cloudwise/probe_state.rb +9 -11
- data/lib/datadog/core/cloudwise/time_sync_worker.rb +2 -6
- data/lib/datadog/core/configuration/components.rb +1 -3
- data/lib/datadog/core/configuration/settings.rb +25 -31
- data/lib/datadog/core/environment/agent_info.rb +18 -0
- data/lib/datadog/core/remote/negotiation.rb +14 -0
- data/lib/datadog/core/transport/http/adapters/net.rb +8 -6
- data/lib/datadog/tracing/contrib/cloudwise/propagation.rb +80 -162
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +2 -6
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_batch.rb +0 -26
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_message.rb +0 -26
- data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +26 -114
- data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +21 -50
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +82 -83
- data/lib/datadog/tracing/tracer.rb +10 -33
- data/lib/datadog/tracing/transport/http/api.rb +2 -4
- data/lib/datadog/tracing/transport/http/traces.rb +2 -2
- data/lib/datadog/tracing/transport/trace_formatter.rb +25 -22
- data/lib/datadog/tracing.rb +3 -3
- data/lib/datadog/version.rb +2 -2
- metadata +4 -4
|
@@ -1,132 +1,44 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative '../../cloudwise/propagation'
|
|
4
|
-
|
|
5
3
|
module Datadog
|
|
6
4
|
module Tracing
|
|
7
5
|
module Contrib
|
|
8
6
|
module Kafka
|
|
9
7
|
module Instrumentation
|
|
10
8
|
# Instrumentation for Kafka::Consumer
|
|
11
|
-
# 这个模块直接 prepend 到 ::Kafka::Consumer,实例方法直接定义在模块中
|
|
12
9
|
module Consumer
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
# 获取 Thread-local 中存储的 CLOUDWISE headers(不清除)
|
|
26
|
-
# 用于 on_finish 中获取 headers
|
|
27
|
-
def peek_cloudwise_headers
|
|
28
|
-
Thread.current[CLOUDWISE_HEADERS_KEY]
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# 获取并清除 Thread-local 中存储的 CLOUDWISE headers
|
|
32
|
-
def fetch_cloudwise_headers
|
|
33
|
-
headers = Thread.current[CLOUDWISE_HEADERS_KEY]
|
|
34
|
-
Thread.current[CLOUDWISE_HEADERS_KEY] = nil
|
|
35
|
-
headers
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# 清除 Thread-local 中存储的 CLOUDWISE headers
|
|
39
|
-
def clear_cloudwise_headers
|
|
40
|
-
Thread.current[CLOUDWISE_HEADERS_KEY] = nil
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# 实例方法直接定义在模块中,会被 prepend 到 ::Kafka::Consumer
|
|
45
|
-
def each_message(**kwargs, &block)
|
|
46
|
-
return super unless block
|
|
47
|
-
|
|
48
|
-
original_block = block
|
|
49
|
-
wrapped_block = proc do |message|
|
|
50
|
-
headers = message.headers || {}
|
|
51
|
-
|
|
52
|
-
# 处理 DSM checkpoint
|
|
53
|
-
if Datadog::DataStreams.enabled?
|
|
54
|
-
Datadog.logger.debug { "Kafka each_message: DSM enabled for topic #{message.topic}" }
|
|
55
|
-
|
|
56
|
-
begin
|
|
57
|
-
Datadog::DataStreams.set_consume_checkpoint(
|
|
58
|
-
type: 'kafka',
|
|
59
|
-
source: message.topic,
|
|
60
|
-
auto_instrumentation: true
|
|
61
|
-
) { |key| headers[key] }
|
|
62
|
-
rescue => e
|
|
63
|
-
Datadog.logger.debug("Error setting DSM checkpoint: #{e.class}: #{e}")
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# 存储 CLOUDWISE headers 到 Thread-local
|
|
68
|
-
# 这会在 process_message 事件的 on_start 之后、on_finish 之前执行
|
|
69
|
-
# 所以 on_finish 可以获取到正确的 headers
|
|
70
|
-
Datadog::Tracing::Contrib::Kafka::Instrumentation::Consumer.store_cloudwise_headers(headers)
|
|
71
|
-
|
|
72
|
-
# 调用原始 block
|
|
73
|
-
original_block.call(message)
|
|
10
|
+
def each_message(**kwargs, &block)
|
|
11
|
+
if Datadog::DataStreams.enabled?
|
|
12
|
+
super do |message|
|
|
13
|
+
headers = message.headers || {}
|
|
14
|
+
|
|
15
|
+
Datadog::DataStreams.set_consume_checkpoint(
|
|
16
|
+
type: 'kafka',
|
|
17
|
+
source: message.topic,
|
|
18
|
+
auto_instrumentation: true
|
|
19
|
+
) { |key| headers[key] }
|
|
20
|
+
|
|
21
|
+
block.call(message)
|
|
74
22
|
end
|
|
75
|
-
|
|
76
|
-
super
|
|
23
|
+
else
|
|
24
|
+
super
|
|
77
25
|
end
|
|
26
|
+
end
|
|
78
27
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
begin
|
|
89
|
-
Datadog::DataStreams.set_consume_checkpoint(
|
|
90
|
-
type: 'kafka',
|
|
91
|
-
source: batch.topic,
|
|
92
|
-
auto_instrumentation: true
|
|
93
|
-
)
|
|
94
|
-
rescue => e
|
|
95
|
-
Datadog.logger.debug("Error setting DSM checkpoint: #{e.class}: #{e}")
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
# 从批量消息的第一条消息中提取 headers 并存储到 Thread-local
|
|
100
|
-
store_batch_cloudwise_headers!(batch)
|
|
28
|
+
def each_batch(**kwargs, &block)
|
|
29
|
+
if Datadog::DataStreams.enabled?
|
|
30
|
+
super do |batch|
|
|
31
|
+
Datadog::DataStreams.set_consume_checkpoint(
|
|
32
|
+
type: 'kafka',
|
|
33
|
+
source: batch.topic,
|
|
34
|
+
auto_instrumentation: true
|
|
35
|
+
)
|
|
101
36
|
|
|
102
|
-
|
|
103
|
-
original_block.call(batch)
|
|
37
|
+
block.call(batch)
|
|
104
38
|
end
|
|
105
|
-
|
|
106
|
-
super
|
|
39
|
+
else
|
|
40
|
+
super
|
|
107
41
|
end
|
|
108
|
-
|
|
109
|
-
private
|
|
110
|
-
|
|
111
|
-
# 从批量消息的第一条消息中提取 headers 并存储到 Thread-local
|
|
112
|
-
# @param batch [Object] 批量消息对象
|
|
113
|
-
def store_batch_cloudwise_headers!(batch)
|
|
114
|
-
return unless batch
|
|
115
|
-
|
|
116
|
-
# 获取批量消息中的消息列表
|
|
117
|
-
messages = batch.respond_to?(:messages) ? batch.messages : nil
|
|
118
|
-
return unless messages && !messages.empty?
|
|
119
|
-
|
|
120
|
-
# 从第一条消息中提取 headers
|
|
121
|
-
first_message = messages.first
|
|
122
|
-
return unless first_message
|
|
123
|
-
|
|
124
|
-
headers = first_message.respond_to?(:headers) ? first_message.headers : nil
|
|
125
|
-
return unless headers
|
|
126
|
-
|
|
127
|
-
Datadog::Tracing::Contrib::Kafka::Instrumentation::Consumer.store_cloudwise_headers(headers)
|
|
128
|
-
rescue => e
|
|
129
|
-
Datadog.logger.debug("Error storing CLOUDWISE headers from batch: #{e.class}: #{e}")
|
|
130
42
|
end
|
|
131
43
|
end
|
|
132
44
|
end
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative '../../cloudwise/propagation'
|
|
4
|
-
|
|
5
3
|
module Datadog
|
|
6
4
|
module Tracing
|
|
7
5
|
module Contrib
|
|
@@ -15,71 +13,44 @@ module Datadog
|
|
|
15
13
|
|
|
16
14
|
module InstanceMethods
|
|
17
15
|
def deliver_messages(**kwargs)
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
if Datadog::DataStreams.enabled?
|
|
17
|
+
pending_messages = instance_variable_get(:@pending_message_queue)
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
if pending_messages && !pending_messages.empty?
|
|
20
|
+
pending_messages.each do |message|
|
|
21
|
+
message.headers ||= {}
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
) do |key, value|
|
|
32
|
-
message.headers[key] = value
|
|
33
|
-
end
|
|
23
|
+
Datadog::DataStreams.set_produce_checkpoint(
|
|
24
|
+
type: 'kafka',
|
|
25
|
+
destination: message.topic,
|
|
26
|
+
auto_instrumentation: true
|
|
27
|
+
) do |key, value|
|
|
28
|
+
message.headers[key] = value
|
|
34
29
|
end
|
|
35
|
-
|
|
36
|
-
# 注入 CLOUDWISE header
|
|
37
|
-
inject_cloudwise_headers!(message.headers, message.topic)
|
|
38
30
|
end
|
|
39
31
|
end
|
|
40
|
-
rescue => e
|
|
41
|
-
Datadog.logger.debug("Error in Kafka producer instrumentation: #{e.class}: #{e}")
|
|
42
32
|
end
|
|
43
33
|
|
|
44
34
|
super
|
|
45
35
|
end
|
|
46
36
|
|
|
47
37
|
def send_messages(messages, **kwargs)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
) do |key, value|
|
|
59
|
-
message[:headers][key] = value
|
|
60
|
-
end
|
|
38
|
+
if Datadog::DataStreams.enabled?
|
|
39
|
+
messages.each do |message|
|
|
40
|
+
message[:headers] ||= {}
|
|
41
|
+
|
|
42
|
+
Datadog::DataStreams.set_produce_checkpoint(
|
|
43
|
+
type: 'kafka',
|
|
44
|
+
destination: message[:topic],
|
|
45
|
+
auto_instrumentation: true
|
|
46
|
+
) do |key, value|
|
|
47
|
+
message[:headers][key] = value
|
|
61
48
|
end
|
|
62
|
-
|
|
63
|
-
# 注入 CLOUDWISE header
|
|
64
|
-
inject_cloudwise_headers!(message[:headers], message[:topic])
|
|
65
49
|
end
|
|
66
|
-
rescue => e
|
|
67
|
-
Datadog.logger.debug("Error in Kafka producer instrumentation: #{e.class}: #{e}")
|
|
68
50
|
end
|
|
69
51
|
|
|
70
52
|
super
|
|
71
53
|
end
|
|
72
|
-
|
|
73
|
-
private
|
|
74
|
-
|
|
75
|
-
# 注入 CLOUDWISE headers 到 Kafka 消息
|
|
76
|
-
# @param headers [Hash] 消息 headers
|
|
77
|
-
# @param topic [String] Kafka topic 名称
|
|
78
|
-
def inject_cloudwise_headers!(headers, topic)
|
|
79
|
-
Cloudwise::Propagation.inject_kafka_headers!(headers, topic)
|
|
80
|
-
rescue => e
|
|
81
|
-
Datadog.logger.debug("Error injecting CLOUDWISE headers: #{e.class}: #{e}")
|
|
82
|
-
end
|
|
83
54
|
end
|
|
84
55
|
end
|
|
85
56
|
end
|
|
@@ -29,7 +29,9 @@ module Datadog
|
|
|
29
29
|
# information available at the Rack level.
|
|
30
30
|
class TraceMiddleware
|
|
31
31
|
# ✅ 优化:缓存 ENV 配置为常量,避免每次请求读取操作系统环境变量
|
|
32
|
+
# rubocop:disable CustomCops/EnvUsageCop
|
|
32
33
|
CLOUDWISE_JS_ENABLED = ENV.fetch('CLOUDWISE_JS_CONFIG', 'false') == 'true'
|
|
34
|
+
# rubocop:enable CustomCops/EnvUsageCop
|
|
33
35
|
|
|
34
36
|
def initialize(app)
|
|
35
37
|
@app = app
|
|
@@ -50,113 +52,109 @@ module Datadog
|
|
|
50
52
|
Tracing.continue_trace!(trace_digest) if trace_digest
|
|
51
53
|
end
|
|
52
54
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
# 需要在创建 span 之前提取信息
|
|
56
|
+
request_headers = Header::RequestHeaderCollection.new(env)
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
# 处理 CLOUDWISEREQUESTINFO(前端调用)
|
|
59
|
+
cloudwise_info = request_headers.get('CLOUDWISEREQUESTINFO')
|
|
60
|
+
request_id = nil
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
if cloudwise_info
|
|
63
|
+
# 提取 request_id
|
|
64
|
+
request_id = extract_request_id(cloudwise_info)
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
if request_id
|
|
67
|
+
Datadog.logger.debug do
|
|
68
|
+
"Extracted request_id from CLOUDWISEREQUESTINFO: #{request_id}"
|
|
69
|
+
end
|
|
67
70
|
end
|
|
68
71
|
end
|
|
69
|
-
end
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
# 处理 CLOUDWISE(外部服务调用,如 Java/PHP)
|
|
74
|
+
cloudwise_header = request_headers.get('CLOUDWISE')
|
|
73
75
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
TraceProxyMiddleware.call(env, configuration) do
|
|
77
|
+
trace_options = {type: Tracing::Metadata::Ext::HTTP::TYPE_INBOUND}
|
|
78
|
+
trace_options[:service] = configuration[:service_name] if configuration[:service_name]
|
|
77
79
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
# start a new request span and attach it to the current Rack environment;
|
|
81
|
+
# we must ensure that the span `resource` is set later
|
|
82
|
+
request_span = Tracing.trace(Ext::SPAN_REQUEST, **trace_options)
|
|
83
|
+
request_span.resource = nil
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
# 如果存在 request_id,将其作为 span 的 cwsa_trace 字段
|
|
86
|
+
if request_id
|
|
87
|
+
request_span.set_tag('cwsa_trace', request_id)
|
|
88
|
+
Datadog.logger.debug do
|
|
89
|
+
"Set cwsa_trace tag on span: #{request_id}"
|
|
90
|
+
end
|
|
88
91
|
end
|
|
89
|
-
end
|
|
90
92
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
# 如果存在 CLOUDWISE 头(外部服务调用),提取并设置字段到 span
|
|
94
|
+
if cloudwise_header
|
|
95
|
+
require_relative '../cloudwise/propagation'
|
|
96
|
+
Cloudwise::Propagation.extract_and_tag_from_header!(request_span, cloudwise_header)
|
|
97
|
+
end
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
# 提取 CLOUDWISE-OTHER 头并添加到根 span
|
|
100
|
+
require_relative '../cloudwise/propagation'
|
|
101
|
+
Cloudwise::Propagation.extract_other_from_request!(request_span, request_headers)
|
|
100
102
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
# When tracing and distributed tracing are both disabled, `.active_trace` will be `nil`,
|
|
104
|
+
# Return a null object to continue operation
|
|
105
|
+
request_trace = Tracing.active_trace || TraceOperation.new
|
|
106
|
+
env[Ext::RACK_ENV_REQUEST_SPAN] = request_span
|
|
105
107
|
|
|
106
|
-
|
|
108
|
+
Datadog::Core::Remote::Tie::Tracing.tag(boot, request_span)
|
|
107
109
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
# Copy the original env, before the rest of the stack executes.
|
|
111
|
+
# Values may change; we want values before that happens.
|
|
112
|
+
original_env = env.dup
|
|
111
113
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
# call the rest of the stack
|
|
115
|
+
status, headers, response = @app.call(env)
|
|
114
116
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
# 如果存在 cloudwise_info,在响应头中添加 CLOUDWISETRACE
|
|
118
|
+
if cloudwise_info
|
|
119
|
+
headers ||= {}
|
|
120
|
+
headers['CLOUDWISETRACE'] = 'true'
|
|
121
|
+
Datadog.logger.debug do
|
|
122
|
+
"Added CLOUDWISETRACE response header"
|
|
123
|
+
end
|
|
121
124
|
end
|
|
122
|
-
end
|
|
123
125
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
# 如果启用了 CLOUDWISE_JS_CONFIG,在响应头中添加 CLOUDWISE(用于 RUM 追踪)
|
|
127
|
+
# 默认关闭,可通过环境变量 CLOUDWISE_JS_CONFIG=true 开启
|
|
128
|
+
# 使用常量替代每次 ENV 读取
|
|
129
|
+
if CLOUDWISE_JS_ENABLED
|
|
130
|
+
headers ||= {}
|
|
131
|
+
require_relative '../cloudwise/propagation'
|
|
132
|
+
|
|
133
|
+
# 构建 CLOUDWISE 响应头值
|
|
134
|
+
# Only add CLOUDWISE header if Cloudwise is active (not suspended)
|
|
135
|
+
service_name = Datadog.configuration.service
|
|
136
|
+
if service_name && request_span
|
|
137
|
+
cloudwise_value = Cloudwise::Propagation.build_cloudwise_value(
|
|
138
|
+
span: request_span,
|
|
139
|
+
trace: request_trace,
|
|
140
|
+
service_name: service_name,
|
|
141
|
+
target_url: nil # 响应头不需要 target_url
|
|
142
|
+
)
|
|
130
143
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
cloudwise_value = Cloudwise::Propagation.build_cloudwise_value(
|
|
136
|
-
span: request_span,
|
|
137
|
-
trace: request_trace,
|
|
138
|
-
service_name: service_name,
|
|
139
|
-
target_url: nil # 响应头不需要 target_url
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
headers['CLOUDWISE'] = cloudwise_value
|
|
143
|
-
Datadog.logger.debug do
|
|
144
|
-
"Added CLOUDWISE response header for RUM: #{cloudwise_value}"
|
|
145
|
-
end
|
|
146
|
-
elsif service_name && request_span
|
|
147
|
-
Datadog.logger.debug do
|
|
148
|
-
"Skipped CLOUDWISE response header: Cloudwise probe suspended"
|
|
144
|
+
headers['CLOUDWISE'] = cloudwise_value
|
|
145
|
+
Datadog.logger.debug do
|
|
146
|
+
"Added CLOUDWISE response header for RUM: #{cloudwise_value}"
|
|
147
|
+
end
|
|
149
148
|
end
|
|
150
149
|
end
|
|
151
|
-
end
|
|
152
150
|
|
|
153
|
-
|
|
151
|
+
[status, headers, response]
|
|
154
152
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
153
|
+
# Here we really want to catch *any* exception, not only StandardError,
|
|
154
|
+
# as we really have no clue of what is in the block,
|
|
155
|
+
# and it is user code which should be executed no matter what.
|
|
156
|
+
# It's not a problem since we re-raise it afterwards so for example a
|
|
157
|
+
# SignalException::Interrupt would still bubble up.
|
|
160
158
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
161
159
|
# catch exceptions that may be raised in the middleware chain
|
|
162
160
|
# Note: if a middleware catches an Exception without re raising,
|
|
@@ -205,6 +203,7 @@ module Datadog
|
|
|
205
203
|
end
|
|
206
204
|
nil
|
|
207
205
|
end
|
|
206
|
+
|
|
208
207
|
# rubocop:disable Metrics/AbcSize
|
|
209
208
|
# rubocop:disable Metrics/CyclomaticComplexity
|
|
210
209
|
# rubocop:disable Metrics/PerceivedComplexity
|
|
@@ -145,7 +145,7 @@ module Datadog
|
|
|
145
145
|
&block
|
|
146
146
|
)
|
|
147
147
|
return skip_trace(name, &block) unless enabled
|
|
148
|
-
|
|
148
|
+
|
|
149
149
|
# Check Cloudwise probe state - if suspended, don't create spans
|
|
150
150
|
return skip_trace(name, &block) if cloudwise_probe_suspended?
|
|
151
151
|
|
|
@@ -599,43 +599,20 @@ module Datadog
|
|
|
599
599
|
|
|
600
600
|
# Check if Cloudwise probe is suspended
|
|
601
601
|
# If suspended, we should not create any spans
|
|
602
|
+
# rubocop:disable Metrics/MethodLength
|
|
602
603
|
def cloudwise_probe_suspended?
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
# If no components reference, try global Datadog.components
|
|
607
|
-
if components.nil? && defined?(Datadog.components)
|
|
608
|
-
components = Datadog.components
|
|
609
|
-
end
|
|
610
|
-
|
|
611
|
-
unless components
|
|
612
|
-
logger.debug { "Cloudwise check: No components available" }
|
|
613
|
-
return false
|
|
614
|
-
end
|
|
615
|
-
|
|
616
|
-
unless components.respond_to?(:cloudwise)
|
|
617
|
-
logger.debug { "Cloudwise check: Components doesn't respond to cloudwise" }
|
|
618
|
-
return false
|
|
619
|
-
end
|
|
620
|
-
|
|
604
|
+
components = @components || (defined?(Datadog.components) && Datadog.components)
|
|
605
|
+
return false unless components&.respond_to?(:cloudwise)
|
|
606
|
+
|
|
621
607
|
cloudwise = components.cloudwise
|
|
622
|
-
unless cloudwise&.enabled?
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
end
|
|
626
|
-
|
|
627
|
-
suspended = cloudwise.probe_state.suspended?
|
|
628
|
-
logger.debug { "Cloudwise check: suspended? = #{suspended}" }
|
|
629
|
-
|
|
630
|
-
suspended
|
|
608
|
+
return false unless cloudwise&.enabled?
|
|
609
|
+
|
|
610
|
+
cloudwise.probe_state.suspended?
|
|
631
611
|
rescue => e
|
|
632
|
-
|
|
633
|
-
# Log error only once to avoid log spam
|
|
634
|
-
CLOUDWISE_CHECK_LOG_ONLY_ONCE.run do
|
|
635
|
-
logger.debug { "Cloudwise probe check error: #{e.message}" }
|
|
636
|
-
end
|
|
612
|
+
CLOUDWISE_CHECK_LOG_ONLY_ONCE.run { logger.debug { "Cloudwise probe check error: #{e.message}" } }
|
|
637
613
|
false
|
|
638
614
|
end
|
|
615
|
+
# rubocop:enable Metrics/MethodLength
|
|
639
616
|
|
|
640
617
|
CLOUDWISE_CHECK_LOG_ONLY_ONCE = Core::Utils::OnlyOnce.new
|
|
641
618
|
private_constant :CLOUDWISE_CHECK_LOG_ONLY_ONCE
|
|
@@ -47,7 +47,7 @@ module Datadog
|
|
|
47
47
|
base_path = '/api/v2/traces'
|
|
48
48
|
|
|
49
49
|
return base_path unless defined?(Datadog.configuration) &&
|
|
50
|
-
|
|
50
|
+
Datadog.configuration.respond_to?(:cloudwise)
|
|
51
51
|
|
|
52
52
|
# 优先级 1: api_prefix_mode 模式配置(最高优先级,简化配置)
|
|
53
53
|
if Datadog.configuration.cloudwise.respond_to?(:api_prefix_mode)
|
|
@@ -94,15 +94,13 @@ module Datadog
|
|
|
94
94
|
end
|
|
95
95
|
end
|
|
96
96
|
nil
|
|
97
|
-
else
|
|
98
|
-
nil
|
|
99
97
|
end
|
|
100
98
|
end
|
|
101
99
|
|
|
102
100
|
# 检查是否启用 integrated_mode
|
|
103
101
|
def cloudwise_integrated_mode?
|
|
104
102
|
return false unless defined?(Datadog.configuration) &&
|
|
105
|
-
|
|
103
|
+
Datadog.configuration.respond_to?(:cloudwise)
|
|
106
104
|
|
|
107
105
|
integrated_mode = Datadog.configuration.cloudwise.integrated_mode
|
|
108
106
|
token = Datadog.configuration.cloudwise.token
|
|
@@ -100,7 +100,7 @@ module Datadog
|
|
|
100
100
|
# Add routing key header
|
|
101
101
|
env.headers['routingKey'] = 'rubyTopic'
|
|
102
102
|
|
|
103
|
-
env.headers['AccountId'] =
|
|
103
|
+
env.headers['AccountId'] = DATADOG_ENV['CLOUDWISE_ACCOUNT_ID'] || '110'
|
|
104
104
|
|
|
105
105
|
# Encode body & type
|
|
106
106
|
env.headers[HEADER_CONTENT_TYPE] = encoder.content_type
|
|
@@ -142,7 +142,7 @@ module Datadog
|
|
|
142
142
|
def build_mock_response(env)
|
|
143
143
|
# Create a mock HTTP response
|
|
144
144
|
mock_http_response = Struct.new(:code, :payload).new(200, '{}')
|
|
145
|
-
response_options = {
|
|
145
|
+
response_options = {trace_count: env.request.parcel.trace_count}
|
|
146
146
|
Traces::Response.new(mock_http_response, response_options)
|
|
147
147
|
end
|
|
148
148
|
end
|
|
@@ -207,47 +207,50 @@ module Datadog
|
|
|
207
207
|
end
|
|
208
208
|
|
|
209
209
|
def tag_cloudwise_metadata!
|
|
210
|
+
# ✅ 优化:使用 set_tags 批量设置,减少锁竞争
|
|
211
|
+
tags = {}
|
|
212
|
+
|
|
210
213
|
# Get all Cloudwise metadata from environment variables (set by Cloudwise client during registration)
|
|
211
|
-
account_id =
|
|
212
|
-
host_id =
|
|
213
|
-
agent_id =
|
|
214
|
-
host_name =
|
|
215
|
-
instance_id =
|
|
216
|
-
|
|
217
|
-
#
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
214
|
+
account_id = DATADOG_ENV['CLOUDWISE_ACCOUNT_ID']
|
|
215
|
+
host_id = DATADOG_ENV['CLOUDWISE_HOST_ID']
|
|
216
|
+
agent_id = DATADOG_ENV['CLOUDWISE_AGENT_ID']
|
|
217
|
+
host_name = DATADOG_ENV['CLOUDWISE_HOST_NAME']
|
|
218
|
+
instance_id = DATADOG_ENV['CLOUDWISE_INSTANCE_ID']
|
|
219
|
+
|
|
220
|
+
# Collect all metadata tags
|
|
221
|
+
tags['account_id'] = account_id if account_id && !account_id.empty?
|
|
222
|
+
tags['host_id'] = host_id if host_id && !host_id.empty?
|
|
223
|
+
tags['agent_id'] = agent_id if agent_id && !agent_id.empty?
|
|
224
|
+
tags['host_name'] = host_name if host_name && !host_name.empty?
|
|
225
|
+
tags['instance_id'] = instance_id if instance_id && !instance_id.empty?
|
|
223
226
|
|
|
224
227
|
# Add host_ip (server IP address)
|
|
225
228
|
require_relative '../contrib/cloudwise/propagation'
|
|
226
229
|
host_ip = Contrib::Cloudwise::Propagation.get_host_ip
|
|
227
|
-
|
|
230
|
+
tags['host_ip'] = host_ip if host_ip && !host_ip.empty?
|
|
228
231
|
|
|
229
232
|
# Generate and set app_id based on service name
|
|
230
233
|
service_name = Datadog.configuration.service
|
|
231
234
|
if service_name && !service_name.empty?
|
|
232
235
|
app_id = Contrib::Cloudwise::Propagation.generate_app_id(service_name)
|
|
233
|
-
|
|
236
|
+
tags['app_id'] = app_id if app_id
|
|
234
237
|
end
|
|
235
238
|
|
|
236
239
|
# Add new Cloudwise fields: service_instance_id, service_type_from, parent_sys, sys
|
|
237
240
|
# Generate service_instance_id based on IP + process path + PID
|
|
238
241
|
service_instance_id = Contrib::Cloudwise::Propagation.generate_service_instance_id
|
|
239
|
-
|
|
242
|
+
tags['service_instance_id'] = service_instance_id if service_instance_id
|
|
240
243
|
|
|
241
244
|
# Get sys from environment variable (default: 'default')
|
|
242
245
|
sys = Contrib::Cloudwise::Propagation.get_sys
|
|
243
|
-
|
|
246
|
+
tags['sys'] = sys if sys
|
|
244
247
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
248
|
+
# 如果 service_type_from 和 parent_sys 不存在,设置为空字符串
|
|
249
|
+
tags['service_type_from'] = '' unless root_span.get_tag('service_type_from')
|
|
250
|
+
tags['parent_sys'] = '' unless root_span.get_tag('parent_sys')
|
|
251
|
+
|
|
252
|
+
# 批量设置所有 tags
|
|
253
|
+
root_span.set_tags(tags) unless tags.empty?
|
|
251
254
|
end
|
|
252
255
|
|
|
253
256
|
def tag_git_repository_url!
|