Module: Datadog::Trace
- Defined in:
- lib/datadog/lambda/trace/xray.rb,
lib/datadog/lambda/trace/context.rb,
lib/datadog/lambda/trace/ddtrace.rb,
lib/datadog/lambda/trace/listener.rb,
lib/datadog/lambda/trace/constants.rb,
lib/datadog/lambda/trace/patch_http.rb
Overview
Trace contains methods to help with patching Net/HTTP
Defined Under Namespace
Modules: NetExtensions
Classes: Listener
Constant Summary
collapse
- SAMPLE_MODE_USER_REJECT =
-1
- SAMPLE_MODE_AUTO_REJECT =
0
- SAMPLE_MODE_AUTO_KEEP =
1
- SAMPLE_MODE_USER_KEEP =
2
'x-datadog-trace-id'
'x-datadog-parent-id'
'x-datadog-sampling-priority'
- DD_ORIGIN =
'x-datadog-origin'
- DD_XRAY_SUBSEGMENT_NAME =
'datadog-metadata'
- DD_XRAY_SUBSEGMENT_KEY =
'trace'
- DD_XRAY_SUBSEGMENT_NAMESPACE =
'datadog'
- DD_TRACE_MANAGED_SERVICES =
'DD_TRACE_MANAGED_SERVICES'
- SOURCE_XRAY =
'XRAY'
- SOURCE_EVENT =
'EVENT'
- XRAY_ENV_VAR =
'_X_AMZN_TRACE_ID'
- XRAY_UDP_PORT =
2000
- LOCAL_HOST =
'127.0.0.1'
- AWS_XRAY_DAEMON_ADDRESS_ENV_VAR =
'AWS_XRAY_DAEMON_ADDRESS'
Class Method Summary
collapse
Class Method Details
.add_trace_context_to_xray(context) ⇒ Object
40
41
42
43
44
|
# File 'lib/datadog/lambda/trace/xray.rb', line 40
def add_trace_context_to_xray(context)
data = generate_xray_metadata_subsegment(context)
send_xray_daemon_data(data)
Datadog::Utils.logger.debug("sent metadata to xray #{data}")
end
|
.apply_datadog_trace_context(context) ⇒ Object
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
# File 'lib/datadog/lambda/trace/ddtrace.rb', line 14
def apply_datadog_trace_context(context)
unless context.nil?
trace_id = context[:trace_id].to_i
span_id = context[:parent_id].to_i
sampling_priority = context[:sample_mode]
trace_digest = Datadog::Tracing::TraceDigest.new(
span_id:,
trace_id:,
trace_sampling_priority: sampling_priority
)
Datadog::Tracing.continue_trace!(trace_digest)
end
rescue StandardError
Datadog::Utils.logger.debug 'dd-trace unavailable'
end
|
.convert_to_apm_parent_id(xray_parent_id) ⇒ Object
128
129
130
131
132
133
134
|
# File 'lib/datadog/lambda/trace/xray.rb', line 128
def convert_to_apm_parent_id(xray_parent_id)
return nil if xray_parent_id.length != 16
return nil if xray_parent_id.upcase[/\H/]
hex = xray_parent_id.to_i(16)
hex.to_s(10)
end
|
.convert_to_apm_trace_id(xray_trace_id) ⇒ Object
114
115
116
117
118
119
120
121
122
123
124
125
126
|
# File 'lib/datadog/lambda/trace/xray.rb', line 114
def convert_to_apm_trace_id(xray_trace_id)
parts = xray_trace_id.split('-')
return nil if parts.length < 3
last_part = parts[2]
return nil if last_part.length != 24
return nil if last_part.upcase[/\H/]
hex = last_part.to_i(16)
last_63_bits = hex & 0x7fffffffffffffff
last_63_bits.to_s(10)
end
|
.convert_to_sample_mode(xray_sampled) ⇒ Object
.current_trace_context(trace_context) ⇒ Object
70
71
72
73
74
75
76
77
78
79
80
|
# File 'lib/datadog/lambda/trace/xray.rb', line 70
def current_trace_context(trace_context)
trace_context = Hash[trace_context]
begin
entity = XRay.recorder.current_entity
trace_context[:parent_id] = convert_to_apm_parent_id(entity.id)
rescue StandardError
Datadog::Utils.logger.debug("couldn't fetch xray entity")
end
trace_context
end
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
# File 'lib/datadog/lambda/trace/context.rb', line 20
def (event, merge_xray_traces)
context = read_trace_context_from_event(event)
unless context.nil?
begin
add_trace_context_to_xray(context)
rescue StandardError => e
Datadog::Utils.logger.debug("couldn't add metadata to xray #{e}")
end
return context
end
return nil unless merge_xray_traces
read_trace_context_from_xray
end
|
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
# File 'lib/datadog/lambda/trace/xray.rb', line 46
def generate_xray_metadata_subsegment(context)
= ENV[XRAY_ENV_VAR]
segment = ()
{
"id": SecureRandom.hex(8),
"trace_id": segment[:xray_trace_id],
"parent_id": segment[:xray_parent_id],
"name": DD_XRAY_SUBSEGMENT_NAME,
"start_time": Time.now.to_f,
"end_time": Time.now.to_f,
"type": 'subsegment',
"metadata": {
"datadog": {
"trace": {
"parent-id": context[:parent_id],
"sampling-priority": context[:sample_mode].to_s,
"trace-id": context[:trace_id]
}
}
}
}.to_json
end
|
50
51
52
53
|
# File 'lib/datadog/lambda/trace/context.rb', line 50
def (event)
event.is_a?(Hash) && event.key?('headers') &&
event['headers'].is_a?(Hash)
end
|
.parse_assignment(value) ⇒ Object
107
108
109
110
111
112
|
# File 'lib/datadog/lambda/trace/xray.rb', line 107
def parse_assignment(value)
return nil if value.nil?
_, raw_value, * = value.split('=')
raw_value
end
|
93
94
95
96
97
98
99
100
101
102
103
104
105
|
# File 'lib/datadog/lambda/trace/xray.rb', line 93
def ()
Datadog::Utils.logger.debug("Reading trace context from env #{}")
trace_id, parent_id, sampled = .split(';')
.map { |v| parse_assignment(v) }
return nil if trace_id.nil? || parent_id.nil? || sampled.nil?
{
xray_trace_id: trace_id,
xray_parent_id: parent_id,
xray_sample_mode: sampled
}
end
|
.patch_http ⇒ Object
25
26
27
28
|
# File 'lib/datadog/lambda/trace/patch_http.rb', line 25
def self.patch_http
Net::HTTP.prepend NetExtensions unless @patched
@patched = true
end
|
.read_trace_context_from_event(event) ⇒ Object
.read_trace_context_from_xray ⇒ Object
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
# File 'lib/datadog/lambda/trace/xray.rb', line 21
def read_trace_context_from_xray
= ENV[XRAY_ENV_VAR]
segment = ()
trace_id = convert_to_apm_trace_id(segment[:xray_trace_id])
parent_id = convert_to_apm_parent_id(segment[:xray_parent_id])
sample_mode = convert_to_sample_mode(segment[:xray_sample_mode])
if trace_id.nil? || parent_id.nil? || sample_mode.nil?
Datadog::Utils.logger.error("couldn't read xray header #{}")
return nil
end
{
trace_id:,
parent_id:,
sample_mode:,
source: SOURCE_XRAY
}
end
|
.send_xray_daemon_data(data) ⇒ Object
82
83
84
85
86
87
88
89
90
91
|
# File 'lib/datadog/lambda/trace/xray.rb', line 82
def send_xray_daemon_data(data)
xray_daemon_env = ENV[AWS_XRAY_DAEMON_ADDRESS_ENV_VAR]
socket = XRAY_UDP_PORT
address = LOCAL_HOST
address, socket = xray_daemon_env.split(':') unless xray_daemon_env.nil?
sock = UDPSocket.open
message = "{\"format\": \"json\", \"version\": 1}\n#{data}"
sock.send(message, 0, address, socket)
end
|
.trace_context ⇒ Object
16
17
18
|
# File 'lib/datadog/lambda/trace/patch_http.rb', line 16
def self.trace_context
@trace_context
end
|
.trace_context=(val) ⇒ Object
20
21
22
|
# File 'lib/datadog/lambda/trace/patch_http.rb', line 20
def self.trace_context=(val)
@trace_context = val
end
|
.wrap_datadog(options, &block) ⇒ Object
30
31
32
33
34
35
36
37
38
39
|
# File 'lib/datadog/lambda/trace/ddtrace.rb', line 30
def wrap_datadog(options, &block)
unless Datadog::Tracing.enabled?
Datadog::Utils.logger.debug 'dd-trace unavailable'
return block.call
end
Datadog::Tracing.trace('aws.lambda', **options) do |_span|
block.call
end
end
|