ddtrace 1.7.0 → 1.9.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 +100 -1
- data/README.md +2 -2
- data/ext/ddtrace_profiling_loader/extconf.rb +4 -1
- data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +1 -1
- data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +3 -2
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +24 -50
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.h +1 -1
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +284 -74
- data/ext/ddtrace_profiling_native_extension/collectors_dynamic_sampling_rate.c +142 -0
- data/ext/ddtrace_profiling_native_extension/collectors_dynamic_sampling_rate.h +14 -0
- data/ext/ddtrace_profiling_native_extension/collectors_idle_sampling_helper.c +241 -0
- data/ext/ddtrace_profiling_native_extension/collectors_idle_sampling_helper.h +3 -0
- data/ext/ddtrace_profiling_native_extension/collectors_stack.c +32 -32
- data/ext/ddtrace_profiling_native_extension/collectors_stack.h +2 -2
- data/ext/ddtrace_profiling_native_extension/extconf.rb +21 -7
- data/ext/ddtrace_profiling_native_extension/helpers.h +5 -0
- data/ext/ddtrace_profiling_native_extension/http_transport.c +50 -49
- data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +5 -1
- data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +42 -12
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +116 -22
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +9 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +205 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +86 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +28 -6
- data/ext/ddtrace_profiling_native_extension/setup_signal_handler.c +23 -4
- data/ext/ddtrace_profiling_native_extension/setup_signal_handler.h +4 -0
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +47 -50
- data/ext/ddtrace_profiling_native_extension/stack_recorder.h +4 -4
- data/ext/ddtrace_profiling_native_extension/time_helpers.c +17 -0
- data/ext/ddtrace_profiling_native_extension/time_helpers.h +10 -0
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +75 -8
- data/lib/datadog/appsec/assets/waf_rules/risky.json +1 -1
- data/lib/datadog/appsec/assets/waf_rules/strict.json +1 -1
- data/lib/datadog/appsec/assets.rb +1 -1
- data/lib/datadog/appsec/configuration/settings.rb +35 -22
- data/lib/datadog/appsec/configuration.rb +4 -2
- data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
- data/lib/datadog/appsec/contrib/configuration/settings.rb +1 -1
- data/lib/datadog/appsec/contrib/integration.rb +1 -1
- data/lib/datadog/appsec/contrib/patcher.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/configuration/settings.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/ext.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/request.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/response.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/configuration/settings.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/ext.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/framework.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/request.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/request_middleware.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/configuration/settings.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/ext.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/framework.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/request_middleware.rb +1 -1
- data/lib/datadog/appsec/event.rb +1 -1
- data/lib/datadog/appsec/extensions.rb +36 -26
- data/lib/datadog/appsec/instrumentation/gateway.rb +3 -3
- data/lib/datadog/appsec/processor.rb +15 -19
- data/lib/datadog/appsec/rate_limiter.rb +1 -1
- data/lib/datadog/appsec/reactive/address_hash.rb +1 -1
- data/lib/datadog/appsec/reactive/engine.rb +1 -1
- data/lib/datadog/appsec/reactive/operation.rb +2 -2
- data/lib/datadog/appsec/reactive/subscriber.rb +1 -1
- data/lib/datadog/appsec/response.rb +18 -9
- data/lib/datadog/appsec/utils/http/media_range.rb +201 -0
- data/lib/datadog/appsec/utils/http/media_type.rb +87 -0
- data/lib/datadog/appsec/utils/http.rb +9 -0
- data/lib/datadog/appsec/utils.rb +7 -0
- data/lib/datadog/appsec.rb +1 -1
- data/lib/datadog/ci/ext/environment.rb +57 -13
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +2 -2
- data/lib/datadog/core/configuration/base.rb +3 -0
- data/lib/datadog/core/configuration/components.rb +27 -6
- data/lib/datadog/core/configuration/ext.rb +26 -0
- data/lib/datadog/core/configuration/option_definition.rb +11 -2
- data/lib/datadog/core/configuration/settings.rb +16 -341
- data/lib/datadog/core/diagnostics/environment_logger.rb +4 -3
- data/lib/datadog/core/diagnostics/health.rb +4 -22
- data/lib/datadog/core/environment/variable_helpers.rb +58 -10
- data/lib/datadog/core/metrics/client.rb +3 -2
- data/lib/datadog/core/metrics/ext.rb +0 -2
- data/lib/datadog/core/telemetry/collector.rb +1 -0
- data/lib/datadog/core/utils.rb +0 -21
- data/lib/datadog/core.rb +21 -1
- data/lib/datadog/kit/appsec/events.rb +75 -0
- data/lib/datadog/kit/enable_core_dumps.rb +1 -0
- data/lib/datadog/kit/identity.rb +8 -7
- data/lib/datadog/opentelemetry/api/context.rb +187 -0
- data/lib/datadog/opentelemetry/api/trace/span.rb +15 -0
- data/lib/datadog/opentelemetry/sdk/configurator.rb +38 -0
- data/lib/datadog/opentelemetry/sdk/id_generator.rb +27 -0
- data/lib/datadog/opentelemetry/sdk/propagator.rb +91 -0
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +92 -0
- data/lib/datadog/opentelemetry.rb +48 -0
- data/lib/datadog/opentracer/distributed_headers.rb +2 -2
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +16 -5
- data/lib/datadog/profiling/collectors/dynamic_sampling_rate.rb +14 -0
- data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +68 -0
- data/lib/datadog/profiling/stack_recorder.rb +14 -0
- data/lib/datadog/profiling.rb +2 -0
- data/lib/datadog/tracing/configuration/ext.rb +33 -4
- data/lib/datadog/tracing/configuration/settings.rb +433 -0
- data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/aws/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +9 -4
- data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +11 -1
- data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +10 -3
- data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +9 -4
- data/lib/datadog/tracing/contrib/http/ext.rb +2 -0
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +3 -6
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +11 -1
- data/lib/datadog/tracing/contrib/httpclient/ext.rb +2 -0
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +3 -4
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +11 -1
- data/lib/datadog/tracing/contrib/httprb/ext.rb +2 -0
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +3 -4
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +5 -1
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/patcher.rb +3 -2
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/pg/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +56 -33
- data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/presto/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +10 -12
- data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +4 -1
- data/lib/datadog/tracing/contrib/redis/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/redis/instrumentation.rb +30 -23
- data/lib/datadog/tracing/contrib/redis/integration.rb +34 -2
- data/lib/datadog/tracing/contrib/redis/patcher.rb +18 -14
- data/lib/datadog/tracing/contrib/redis/quantize.rb +12 -9
- data/lib/datadog/tracing/contrib/redis/tags.rb +4 -6
- data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +72 -0
- data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +33 -0
- data/lib/datadog/tracing/contrib/stripe/ext.rb +26 -0
- data/lib/datadog/tracing/contrib/stripe/integration.rb +43 -0
- data/lib/datadog/tracing/contrib/stripe/patcher.rb +29 -0
- data/lib/datadog/tracing/contrib/stripe/request.rb +67 -0
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/{core → tracing}/diagnostics/ext.rb +1 -6
- data/lib/datadog/tracing/diagnostics/health.rb +40 -0
- data/lib/datadog/tracing/distributed/{b3.rb → b3_multi.rb} +2 -2
- data/lib/datadog/tracing/distributed/helpers.rb +2 -1
- data/lib/datadog/tracing/distributed/none.rb +19 -0
- data/lib/datadog/tracing/distributed/trace_context.rb +378 -0
- data/lib/datadog/tracing/metadata/ext.rb +1 -1
- data/lib/datadog/tracing/metadata/tagging.rb +6 -0
- data/lib/datadog/tracing/sampling/priority_sampler.rb +11 -0
- data/lib/datadog/tracing/sampling/rate_sampler.rb +3 -3
- data/lib/datadog/tracing/span.rb +3 -19
- data/lib/datadog/tracing/span_operation.rb +5 -4
- data/lib/datadog/tracing/trace_digest.rb +85 -2
- data/lib/datadog/tracing/trace_operation.rb +13 -4
- data/lib/datadog/tracing/utils.rb +50 -0
- data/lib/ddtrace/version.rb +1 -1
- metadata +41 -9
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: false
|
|
3
|
+
|
|
4
|
+
module Datadog
|
|
5
|
+
module Tracing
|
|
6
|
+
module Distributed
|
|
7
|
+
# W3C Trace Context propagator implementation, version 00.
|
|
8
|
+
# The trace is propagated through two fields: `traceparent` and `tracestate`.
|
|
9
|
+
# @see https://www.w3.org/TR/trace-context/
|
|
10
|
+
class TraceContext
|
|
11
|
+
TRACEPARENT_KEY = 'traceparent'
|
|
12
|
+
TRACESTATE_KEY = 'tracestate'
|
|
13
|
+
SPEC_VERSION = '00'
|
|
14
|
+
|
|
15
|
+
def initialize(
|
|
16
|
+
fetcher:,
|
|
17
|
+
traceparent_key: TRACEPARENT_KEY,
|
|
18
|
+
tracestate_key: TRACESTATE_KEY
|
|
19
|
+
)
|
|
20
|
+
@fetcher = fetcher
|
|
21
|
+
@traceparent_key = traceparent_key
|
|
22
|
+
@tracestate_key = tracestate_key
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def inject!(digest, data)
|
|
26
|
+
return if digest.nil?
|
|
27
|
+
|
|
28
|
+
if (traceparent = build_traceparent(digest))
|
|
29
|
+
data[@traceparent_key] = traceparent
|
|
30
|
+
|
|
31
|
+
if (tracestate = build_tracestate(digest))
|
|
32
|
+
data[@tracestate_key] = tracestate
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
data
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def extract(data)
|
|
40
|
+
fetcher = @fetcher.new(data)
|
|
41
|
+
|
|
42
|
+
trace_id, dd_trace_id, parent_id, sampled, trace_flags = extract_traceparent(fetcher[@traceparent_key])
|
|
43
|
+
|
|
44
|
+
return unless trace_id # Could not parse traceparent
|
|
45
|
+
|
|
46
|
+
tracestate, sampling_priority, origin, tags, unknown_fields = extract_tracestate(fetcher[@tracestate_key])
|
|
47
|
+
|
|
48
|
+
sampling_priority = parse_priority_sampling(sampled, sampling_priority)
|
|
49
|
+
|
|
50
|
+
TraceDigest.new(
|
|
51
|
+
span_id: parent_id,
|
|
52
|
+
trace_id: dd_trace_id,
|
|
53
|
+
trace_origin: origin,
|
|
54
|
+
trace_sampling_priority: sampling_priority,
|
|
55
|
+
trace_distributed_tags: tags,
|
|
56
|
+
trace_distributed_id: trace_id,
|
|
57
|
+
trace_flags: trace_flags,
|
|
58
|
+
trace_state: tracestate,
|
|
59
|
+
trace_state_unknown_fields: unknown_fields,
|
|
60
|
+
)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
# Refinements to ensure newer rubies do not suffer performance impact
|
|
66
|
+
# by needing to use older APIs.
|
|
67
|
+
module Refine
|
|
68
|
+
# Backport `Regexp::match?` because it is measurably the most performant
|
|
69
|
+
# way to check if a string matches a regular expression.
|
|
70
|
+
unless Regexp.method_defined?(:match?)
|
|
71
|
+
refine ::Regexp do
|
|
72
|
+
def match?(*args)
|
|
73
|
+
!match(*args).nil?
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
unless String.method_defined?(:delete_prefix)
|
|
79
|
+
refine ::String do
|
|
80
|
+
def delete_prefix(prefix)
|
|
81
|
+
prefix = prefix.to_s
|
|
82
|
+
if rindex(prefix, 0)
|
|
83
|
+
self[prefix.length..-1]
|
|
84
|
+
else
|
|
85
|
+
dup
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
using Refine
|
|
92
|
+
|
|
93
|
+
# @see https://www.w3.org/TR/trace-context/#traceparent-header
|
|
94
|
+
def build_traceparent(digest)
|
|
95
|
+
build_traceparent_string(
|
|
96
|
+
digest.trace_distributed_id || digest.trace_id,
|
|
97
|
+
digest.span_id,
|
|
98
|
+
build_trace_flags(digest)
|
|
99
|
+
)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# For the current version (00), the traceparent has the following format:
|
|
103
|
+
#
|
|
104
|
+
# `"#{version}-#{trace_id}-#{parent_id}-#{trace_flags}"`
|
|
105
|
+
#
|
|
106
|
+
# Where:
|
|
107
|
+
# * `version`: 2 hex-encoded digits, zero padded.
|
|
108
|
+
# * `trace_id`: 32 hex-encoded digits, zero padded.
|
|
109
|
+
# * `parent_id`: 16 hex-encoded digits, zero padded.
|
|
110
|
+
# * `trace_flags`: 2 hex-encoded digits, zero padded.
|
|
111
|
+
#
|
|
112
|
+
# All hex values should be lowercase.
|
|
113
|
+
#
|
|
114
|
+
# @param trace_id [Integer] 128-bit
|
|
115
|
+
# @param parent_id [Integer] 64-bit
|
|
116
|
+
# @param trace_flags [Integer] 8-bit
|
|
117
|
+
def build_traceparent_string(trace_id, parent_id, trace_flags)
|
|
118
|
+
"00-#{format('%032x', trace_id)}-#{format('%016x', parent_id)}-#{format('%02x', trace_flags)}"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Sets the trace flag to an existing `trace_flags`.
|
|
122
|
+
def build_trace_flags(digest)
|
|
123
|
+
trace_flags = digest.trace_flags || DEFAULT_TRACE_FLAGS
|
|
124
|
+
|
|
125
|
+
if digest.trace_sampling_priority
|
|
126
|
+
if Tracing::Sampling::PrioritySampler.sampled?(digest.trace_sampling_priority)
|
|
127
|
+
trace_flags |= TRACE_FLAGS_SAMPLED
|
|
128
|
+
else
|
|
129
|
+
trace_flags &= ~TRACE_FLAGS_SAMPLED
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
trace_flags
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# @see https://www.w3.org/TR/trace-context/#tracestate-header
|
|
137
|
+
def build_tracestate(digest)
|
|
138
|
+
tracestate = String.new('dd=')
|
|
139
|
+
tracestate << "s:#{digest.trace_sampling_priority};" if digest.trace_sampling_priority
|
|
140
|
+
tracestate << "o:#{serialize_origin(digest.trace_origin)};" if digest.trace_origin
|
|
141
|
+
|
|
142
|
+
if digest.trace_distributed_tags
|
|
143
|
+
digest.trace_distributed_tags.each do |name, value|
|
|
144
|
+
tag = "t.#{serialize_tag_key(name)}:#{serialize_tag_value(value)};"
|
|
145
|
+
|
|
146
|
+
# If tracestate size limit is exceed, drop the remaining data.
|
|
147
|
+
# String#bytesize is used because only ASCII characters are allowed.
|
|
148
|
+
#
|
|
149
|
+
# We add 1 to the limit because of the trailing comma, which will be removed before returning.
|
|
150
|
+
break if tracestate.bytesize + tag.bytesize > (TRACESTATE_VALUE_SIZE_LIMIT + 1)
|
|
151
|
+
|
|
152
|
+
tracestate << tag
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
tracestate << digest.trace_state_unknown_fields if digest.trace_state_unknown_fields
|
|
157
|
+
|
|
158
|
+
# Is there any Datadog-specific information to propagate.
|
|
159
|
+
# Check for > 3 size because the empty prefix `dd=` has 3 characters.
|
|
160
|
+
if tracestate.size > 3
|
|
161
|
+
# Propagate upstream tracestate with `dd=...` appended to the list
|
|
162
|
+
tracestate.chop! # Removes trailing `;` from Datadog trace state string.
|
|
163
|
+
|
|
164
|
+
if digest.trace_state
|
|
165
|
+
# Delete existing `dd=` tracestate fields, if present.
|
|
166
|
+
vendors = split_tracestate(digest.trace_state)
|
|
167
|
+
vendors.reject! { |v| v.start_with?('dd=') }
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
if vendors && !vendors.empty?
|
|
171
|
+
# Ensure the list has at most 31 elements, as we need to prepend Datadog's
|
|
172
|
+
# entry and the limit is 32 elements total.
|
|
173
|
+
vendors = vendors[0..30]
|
|
174
|
+
"#{tracestate},#{vendors.join(',')}"
|
|
175
|
+
else
|
|
176
|
+
tracestate.to_s
|
|
177
|
+
end
|
|
178
|
+
else
|
|
179
|
+
digest.trace_state # Propagate upstream tracestate with no Datadog changes
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# If any characters in <origin_value> are invalid, replace each invalid character with 0x5F (underscore).
|
|
184
|
+
# Invalid characters are: characters outside the ASCII range 0x20 to 0x7E, 0x2C (comma), and 0x3D (equals).
|
|
185
|
+
def serialize_origin(value)
|
|
186
|
+
# DEV: It's unlikely that characters will be out of range, as they mostly
|
|
187
|
+
# DEV: come from Datadog-controlled sources.
|
|
188
|
+
# DEV: Trying to `match?` is measurably faster than a `gsub` that does not match.
|
|
189
|
+
if INVALID_ORIGIN_CHARS.match?(value)
|
|
190
|
+
value.gsub(INVALID_ORIGIN_CHARS, '_')
|
|
191
|
+
else
|
|
192
|
+
value
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Serialize `_dd.p.{key}` by first removing the `_dd.p.` prefix.
|
|
197
|
+
# Then replacing invalid characters with `_`.
|
|
198
|
+
def serialize_tag_key(name)
|
|
199
|
+
key = name.delete_prefix(Tracing::Metadata::Ext::Distributed::TAGS_PREFIX)
|
|
200
|
+
|
|
201
|
+
# DEV: It's unlikely that characters will be out of range, as they mostly
|
|
202
|
+
# DEV: come from Datadog-controlled sources.
|
|
203
|
+
# DEV: Trying to `match?` is measurably faster than a `gsub` that does not match.
|
|
204
|
+
if INVALID_TAG_KEY_CHARS.match?(key)
|
|
205
|
+
key.gsub(INVALID_TAG_KEY_CHARS, '_')
|
|
206
|
+
else
|
|
207
|
+
key
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Replaces invalid characters with `_`, then replaces `=` with `:`.
|
|
212
|
+
def serialize_tag_value(value)
|
|
213
|
+
# DEV: It's unlikely that characters will be out of range, as they mostly
|
|
214
|
+
# DEV: come from Datadog-controlled sources.
|
|
215
|
+
# DEV: Trying to `match?` is measurably faster than a `gsub` that does not match.
|
|
216
|
+
ret = if INVALID_TAG_VALUE_CHARS.match?(value)
|
|
217
|
+
value.gsub(INVALID_TAG_VALUE_CHARS, '_')
|
|
218
|
+
else
|
|
219
|
+
value
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# DEV: Checking for an unlikely '=' is faster than a no-op `tr!`.
|
|
223
|
+
ret.tr!('=', ':') if ret.include?('=')
|
|
224
|
+
ret
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def extract_traceparent(traceparent)
|
|
228
|
+
trace_id, parent_id, trace_flags = parse_traceparent_string(traceparent)
|
|
229
|
+
|
|
230
|
+
# Return unless all traceparent fields are valid.
|
|
231
|
+
return unless trace_id && !trace_id.zero? && parent_id && !parent_id.zero? && trace_flags
|
|
232
|
+
|
|
233
|
+
dd_trace_id = parse_datadog_trace_id(trace_id)
|
|
234
|
+
sampled = parse_sampled_flag(trace_flags)
|
|
235
|
+
|
|
236
|
+
[trace_id, dd_trace_id, parent_id, sampled, trace_flags]
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def parse_traceparent_string(traceparent)
|
|
240
|
+
return unless traceparent
|
|
241
|
+
|
|
242
|
+
version, trace_id, parent_id, trace_flags, extra = traceparent.strip.split('-')
|
|
243
|
+
|
|
244
|
+
return if version == INVALID_VERSION
|
|
245
|
+
|
|
246
|
+
# Extra fields are not allowed in version 00, but we have to be lenient for future versions.
|
|
247
|
+
return if version == SPEC_VERSION && extra
|
|
248
|
+
|
|
249
|
+
# Invalid field sizes
|
|
250
|
+
return if version.size != 2 || trace_id.size != 32 || parent_id.size != 16 || trace_flags.size != 2
|
|
251
|
+
|
|
252
|
+
[Integer(trace_id, 16), Integer(parent_id, 16), Integer(trace_flags, 16)]
|
|
253
|
+
rescue ArgumentError # Conversion to integer failed
|
|
254
|
+
nil
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Datadog only allows 64 bits for the trace id.
|
|
258
|
+
# We extract the lower 64 bits from the original 128-bit id.
|
|
259
|
+
def parse_datadog_trace_id(trace_id)
|
|
260
|
+
trace_id & 0xFFFFFFFFFFFFFFFF
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def parse_sampled_flag(trace_flags)
|
|
264
|
+
trace_flags & TRACE_FLAGS_SAMPLED
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
# @return [Array<String,Integer,String,Hash>] returns 4 values: tracestate, sampling_priority, origin, tags.
|
|
268
|
+
def extract_tracestate(tracestate)
|
|
269
|
+
return unless tracestate
|
|
270
|
+
|
|
271
|
+
vendors = split_tracestate(tracestate)
|
|
272
|
+
|
|
273
|
+
# Find Datadog's `dd=` tracestate field.
|
|
274
|
+
idx = vendors.index { |v| v.start_with?('dd=') }
|
|
275
|
+
return tracestate unless idx
|
|
276
|
+
|
|
277
|
+
# Delete `dd=` prefix
|
|
278
|
+
dd_tracestate = vendors.delete_at(idx)
|
|
279
|
+
dd_tracestate.slice!(0..2)
|
|
280
|
+
|
|
281
|
+
origin, sampling_priority, tags, unknown_fields = extract_datadog_fields(dd_tracestate)
|
|
282
|
+
|
|
283
|
+
[vendors.join(','), sampling_priority, origin, tags, unknown_fields]
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def extract_datadog_fields(dd_tracestate)
|
|
287
|
+
sampling_priority = nil
|
|
288
|
+
origin = nil
|
|
289
|
+
tags = nil
|
|
290
|
+
unknown_fields = nil
|
|
291
|
+
|
|
292
|
+
# DEV: Since Ruby 2.6 `split` can receive a block, so `each` can be removed then.
|
|
293
|
+
dd_tracestate.split(';').each do |pair|
|
|
294
|
+
key, value = pair.split(':', 2)
|
|
295
|
+
case key
|
|
296
|
+
when 's'
|
|
297
|
+
sampling_priority = Integer(value) rescue nil
|
|
298
|
+
when 'o'
|
|
299
|
+
origin = value
|
|
300
|
+
when /^t\./
|
|
301
|
+
key.slice!(0..1) # Delete `t.` prefix
|
|
302
|
+
|
|
303
|
+
value = deserialize_tag_value(value)
|
|
304
|
+
|
|
305
|
+
tags ||= {}
|
|
306
|
+
tags["#{Tracing::Metadata::Ext::Distributed::TAGS_PREFIX}#{key}"] = value
|
|
307
|
+
else
|
|
308
|
+
unknown_fields ||= String.new
|
|
309
|
+
unknown_fields << pair
|
|
310
|
+
unknown_fields << ';'
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
[origin, sampling_priority, tags, unknown_fields]
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# Restore `:` back to `=`.
|
|
318
|
+
def deserialize_tag_value(value)
|
|
319
|
+
value.tr!(':', '=')
|
|
320
|
+
value
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
# If `sampled` and `sampling_priority` disagree, `sampled` overrides the decision.
|
|
324
|
+
# @return [Integer] one of the {Datadog::Tracing::Sampling::Ext::Priority} values
|
|
325
|
+
def parse_priority_sampling(sampled, sampling_priority)
|
|
326
|
+
# If both fields agree
|
|
327
|
+
if sampling_priority &&
|
|
328
|
+
(!Tracing::Sampling::PrioritySampler.sampled?(sampling_priority) && sampled == 0 || # Both drop
|
|
329
|
+
Tracing::Sampling::PrioritySampler.sampled?(sampling_priority) && sampled == 1) # Both keep
|
|
330
|
+
|
|
331
|
+
return sampling_priority # Return the richer `sampling_priority`
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
sampled # Sampled flag trumps `sampling_priority` on conflict
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def split_tracestate(tracestate)
|
|
338
|
+
tracestate.split(/[ \t]*,[ \t]*/)[0..31]
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# Version 0xFF is invalid as per spec
|
|
342
|
+
# @see https://www.w3.org/TR/trace-context/#version
|
|
343
|
+
INVALID_VERSION = 'ff'
|
|
344
|
+
private_constant :INVALID_VERSION
|
|
345
|
+
|
|
346
|
+
# Empty 8-bit `trace-flags`.
|
|
347
|
+
# @see https://www.w3.org/TR/trace-context/#trace-flags
|
|
348
|
+
DEFAULT_TRACE_FLAGS = 0b00000000
|
|
349
|
+
private_constant :DEFAULT_TRACE_FLAGS
|
|
350
|
+
|
|
351
|
+
# Bit-mask for `trace-flags` that represents a sampled span (sampled==true).
|
|
352
|
+
# @see https://www.w3.org/TR/trace-context/#trace-flags
|
|
353
|
+
TRACE_FLAGS_SAMPLED = 0b00000001
|
|
354
|
+
private_constant :TRACE_FLAGS_SAMPLED
|
|
355
|
+
|
|
356
|
+
# The limit is inclusive: sizes *greater* than 256 are disallowed.
|
|
357
|
+
# @see https://www.w3.org/TR/trace-context/#value
|
|
358
|
+
TRACESTATE_VALUE_SIZE_LIMIT = 256
|
|
359
|
+
private_constant :TRACESTATE_VALUE_SIZE_LIMIT
|
|
360
|
+
|
|
361
|
+
# Replace all characters with `_`, except ASCII characters 0x20-0x7E.
|
|
362
|
+
# Additionally, `,`, ';', and `=` must also be replaced by `_`.
|
|
363
|
+
INVALID_ORIGIN_CHARS = /[\u0000-\u0019,;=\u007F-\u{10FFFF}]/.freeze
|
|
364
|
+
private_constant :INVALID_ORIGIN_CHARS
|
|
365
|
+
|
|
366
|
+
# Replace all characters with `_`, except ASCII characters 0x21-0x7E.
|
|
367
|
+
# Additionally, `,` and `=` must also be replaced by `_`.
|
|
368
|
+
INVALID_TAG_KEY_CHARS = /[\u0000-\u0020,=\u007F-\u{10FFFF}]/.freeze
|
|
369
|
+
private_constant :INVALID_TAG_KEY_CHARS
|
|
370
|
+
|
|
371
|
+
# Replace all characters with `_`, except ASCII characters 0x20-0x7E.
|
|
372
|
+
# Additionally, `,`, ':' and `;` must also be replaced by `_`.
|
|
373
|
+
INVALID_TAG_VALUE_CHARS = /[\u0000-\u001F,:;\u007F-\u{10FFFF}]/.freeze
|
|
374
|
+
private_constant :INVALID_TAG_VALUE_CHARS
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
end
|
|
@@ -85,6 +85,17 @@ module Datadog
|
|
|
85
85
|
@priority_sampler.update(rate_by_service, decision: decision)
|
|
86
86
|
end
|
|
87
87
|
|
|
88
|
+
# Check if the Priority Sampling decision is to keep or drop the trace.
|
|
89
|
+
# Other factors can influence the sampling decision; this method is only
|
|
90
|
+
# responsible for interpreting the Sampling Priority decision.
|
|
91
|
+
#
|
|
92
|
+
# @param priority_sampling [Integer] priority sampling number
|
|
93
|
+
# @return [Boolean] true if trace is "kept" by priority sampling
|
|
94
|
+
# @return [Boolean] false if trace is "dropped" by priority sampling
|
|
95
|
+
def self.sampled?(priority_sampling)
|
|
96
|
+
priority_sampling >= Ext::Priority::AUTO_KEEP
|
|
97
|
+
end
|
|
98
|
+
|
|
88
99
|
private
|
|
89
100
|
|
|
90
101
|
def pre_sample?(trace)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require_relative '../../core'
|
|
4
4
|
|
|
5
5
|
require_relative 'sampler'
|
|
6
|
-
require_relative '../
|
|
6
|
+
require_relative '../utils'
|
|
7
7
|
|
|
8
8
|
module Datadog
|
|
9
9
|
module Tracing
|
|
@@ -49,11 +49,11 @@ module Datadog
|
|
|
49
49
|
|
|
50
50
|
def sample_rate=(sample_rate)
|
|
51
51
|
@sample_rate = sample_rate
|
|
52
|
-
@sampling_id_threshold = sample_rate * Tracing::
|
|
52
|
+
@sampling_id_threshold = sample_rate * Tracing::Utils::EXTERNAL_MAX_ID
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def sample?(trace)
|
|
56
|
-
((trace.id * KNUTH_FACTOR) % Tracing::
|
|
56
|
+
((trace.id * KNUTH_FACTOR) % Tracing::Utils::EXTERNAL_MAX_ID) <= @sampling_id_threshold
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def sample!(trace)
|
data/lib/datadog/tracing/span.rb
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
# typed: true
|
|
4
4
|
|
|
5
|
-
require_relative '../core/utils'
|
|
6
5
|
require_relative '../core/utils/safe_dup'
|
|
6
|
+
require_relative 'utils'
|
|
7
7
|
|
|
8
8
|
require_relative 'metadata/ext'
|
|
9
9
|
require_relative 'metadata'
|
|
@@ -19,22 +19,6 @@ module Datadog
|
|
|
19
19
|
class Span
|
|
20
20
|
include Metadata
|
|
21
21
|
|
|
22
|
-
# The max value for a {Datadog::Tracing::Span} identifier.
|
|
23
|
-
# Span and trace identifiers should be strictly positive and strictly inferior to this limit.
|
|
24
|
-
#
|
|
25
|
-
# Limited to +2<<62-1+ positive integers, as Ruby is able to represent such numbers "inline",
|
|
26
|
-
# inside a +VALUE+ scalar, thus not requiring memory allocation.
|
|
27
|
-
#
|
|
28
|
-
# The range of IDs also has to consider portability across different languages and platforms.
|
|
29
|
-
RUBY_MAX_ID = (1 << 62) - 1
|
|
30
|
-
|
|
31
|
-
# Excludes zero from possible values
|
|
32
|
-
RUBY_ID_RANGE = (1..RUBY_MAX_ID).freeze
|
|
33
|
-
|
|
34
|
-
# While we only generate 63-bit integers due to limitations in other languages, we support
|
|
35
|
-
# parsing 64-bit integers for distributed tracing since an upstream system may generate one
|
|
36
|
-
EXTERNAL_MAX_ID = 1 << 64
|
|
37
|
-
|
|
38
22
|
attr_accessor \
|
|
39
23
|
:end_time,
|
|
40
24
|
:id,
|
|
@@ -90,9 +74,9 @@ module Datadog
|
|
|
90
74
|
@resource = Core::Utils::SafeDup.frozen_or_dup(resource)
|
|
91
75
|
@type = Core::Utils::SafeDup.frozen_or_dup(type)
|
|
92
76
|
|
|
93
|
-
@id = id ||
|
|
77
|
+
@id = id || Tracing::Utils.next_id
|
|
94
78
|
@parent_id = parent_id || 0
|
|
95
|
-
@trace_id = trace_id ||
|
|
79
|
+
@trace_id = trace_id || Tracing::Utils.next_id
|
|
96
80
|
|
|
97
81
|
@meta = meta || {}
|
|
98
82
|
@metrics = metrics || {}
|
|
@@ -7,10 +7,11 @@ require_relative '../core/environment/identity'
|
|
|
7
7
|
require_relative '../core/utils'
|
|
8
8
|
require_relative '../core/utils/time'
|
|
9
9
|
|
|
10
|
-
require_relative 'metadata/ext'
|
|
11
10
|
require_relative 'event'
|
|
12
|
-
require_relative 'span'
|
|
13
11
|
require_relative 'metadata'
|
|
12
|
+
require_relative 'metadata/ext'
|
|
13
|
+
require_relative 'span'
|
|
14
|
+
require_relative 'utils'
|
|
14
15
|
|
|
15
16
|
module Datadog
|
|
16
17
|
module Tracing
|
|
@@ -61,9 +62,9 @@ module Datadog
|
|
|
61
62
|
self.type = type
|
|
62
63
|
self.resource = resource
|
|
63
64
|
|
|
64
|
-
@id =
|
|
65
|
+
@id = Tracing::Utils.next_id
|
|
65
66
|
@parent_id = parent_id || 0
|
|
66
|
-
@trace_id = trace_id ||
|
|
67
|
+
@trace_id = trace_id || Tracing::Utils.next_id
|
|
67
68
|
|
|
68
69
|
@status = 0
|
|
69
70
|
|
|
@@ -6,6 +6,77 @@ module Datadog
|
|
|
6
6
|
# Used to propagate context and continue traces across execution boundaries.
|
|
7
7
|
# @public_api
|
|
8
8
|
class TraceDigest
|
|
9
|
+
# @!attribute [r] span_id
|
|
10
|
+
# Datadog id for the currently active span.
|
|
11
|
+
# @return [Integer]
|
|
12
|
+
# @!attribute [r] span_name
|
|
13
|
+
# The operation name of the currently active span.
|
|
14
|
+
# @return [String]
|
|
15
|
+
# @!attribute [r] span_resource
|
|
16
|
+
# The resource name of the currently active span.
|
|
17
|
+
# @return [String]
|
|
18
|
+
# @!attribute [r] span_service
|
|
19
|
+
# The service of the currently active span.
|
|
20
|
+
# @return [String]
|
|
21
|
+
# @!attribute [r] span_type
|
|
22
|
+
# The type of the currently active span.
|
|
23
|
+
# @return [String]
|
|
24
|
+
# @!attribute [r] trace_distributed_tags
|
|
25
|
+
# Datadog-specific tags that support richer distributed tracing association.
|
|
26
|
+
# @return [Hash<String,String>]
|
|
27
|
+
# @!attribute [r] trace_hostname
|
|
28
|
+
# The hostname of the currently active trace. Use to attribute traces to hosts.
|
|
29
|
+
# @return [String]
|
|
30
|
+
# @!attribute [r] trace_id
|
|
31
|
+
# Datadog id for the currently active trace.
|
|
32
|
+
# @return [Integer]
|
|
33
|
+
# @!attribute [r] trace_name
|
|
34
|
+
# Operation name for the currently active trace.
|
|
35
|
+
# @return [Integer]
|
|
36
|
+
# @!attribute [r] trace_origin
|
|
37
|
+
# Datadog-specific attribution of this trace's creation.
|
|
38
|
+
# @return [String]
|
|
39
|
+
# @!attribute [r] trace_process_id
|
|
40
|
+
# The OS-specific process id.
|
|
41
|
+
# @return [Integer]
|
|
42
|
+
# @!attribute [r] trace_resource
|
|
43
|
+
# The resource name of the currently active trace.
|
|
44
|
+
# @return [String]
|
|
45
|
+
# @!attribute [r] trace_runtime_id
|
|
46
|
+
# Unique id to this Ruby process. Used to differentiate traces coming from
|
|
47
|
+
# child processes forked from same parent process.
|
|
48
|
+
# @return [String]
|
|
49
|
+
# @!attribute [r] trace_sampling_priority
|
|
50
|
+
# Datadog-specific sampling decision for the currently active trace.
|
|
51
|
+
# @return [Integer]
|
|
52
|
+
# @!attribute [r] trace_service
|
|
53
|
+
# The service of the currently active trace.
|
|
54
|
+
# @return [String]
|
|
55
|
+
# @!attribute [r] trace_distributed_id
|
|
56
|
+
# The trace id extracted from a distributed context, if different from `trace_id`.
|
|
57
|
+
#
|
|
58
|
+
# The current use case is when the distributed context has a trace id integer larger than 64-bit:
|
|
59
|
+
# This attribute will preserve the original id, while `trace_id` will only contain the lower 64 bits.
|
|
60
|
+
# @return [Integer]
|
|
61
|
+
# @see https://www.w3.org/TR/trace-context/#trace-id
|
|
62
|
+
# @!attribute [r] trace_flags
|
|
63
|
+
# The W3C "trace-flags" extracted from a distributed context. This field is an 8-bit unsigned integer.
|
|
64
|
+
# @return [Integer]
|
|
65
|
+
# @see https://www.w3.org/TR/trace-context/#trace-flags
|
|
66
|
+
# @!attribute [r] trace_state
|
|
67
|
+
# The W3C "tracestate" extracted from a distributed context.
|
|
68
|
+
# This field is a string representing vendor-specific distribution data.
|
|
69
|
+
# The `dd=` entry is removed from `trace_state` as its value is dynamically calculated
|
|
70
|
+
# on every propagation injection.
|
|
71
|
+
# @return [String]
|
|
72
|
+
# @see https://www.w3.org/TR/trace-context/#tracestate-header
|
|
73
|
+
# @!attribute [r] trace_state_unknown_fields
|
|
74
|
+
# From W3C "tracestate"'s `dd=` entry, when keys are not recognized they are stored here long with their values.
|
|
75
|
+
# This allows later propagation to include those unknown fields, as they can represent future versions of the spec
|
|
76
|
+
# sending data through this service. This value ends in a trailing `;` to facilitate serialization.
|
|
77
|
+
# @return [String]
|
|
78
|
+
# TODO: The documentation for the last attribute above won't be rendered.
|
|
79
|
+
# TODO: This might be a YARD bug as adding an attribute, making it now second-last attribute, renders correctly.
|
|
9
80
|
attr_reader \
|
|
10
81
|
:span_id,
|
|
11
82
|
:span_name,
|
|
@@ -21,7 +92,11 @@ module Datadog
|
|
|
21
92
|
:trace_resource,
|
|
22
93
|
:trace_runtime_id,
|
|
23
94
|
:trace_sampling_priority,
|
|
24
|
-
:trace_service
|
|
95
|
+
:trace_service,
|
|
96
|
+
:trace_distributed_id,
|
|
97
|
+
:trace_flags,
|
|
98
|
+
:trace_state,
|
|
99
|
+
:trace_state_unknown_fields
|
|
25
100
|
|
|
26
101
|
def initialize(
|
|
27
102
|
span_id: nil,
|
|
@@ -38,7 +113,11 @@ module Datadog
|
|
|
38
113
|
trace_resource: nil,
|
|
39
114
|
trace_runtime_id: nil,
|
|
40
115
|
trace_sampling_priority: nil,
|
|
41
|
-
trace_service: nil
|
|
116
|
+
trace_service: nil,
|
|
117
|
+
trace_distributed_id: nil,
|
|
118
|
+
trace_flags: nil,
|
|
119
|
+
trace_state: nil,
|
|
120
|
+
trace_state_unknown_fields: nil
|
|
42
121
|
)
|
|
43
122
|
@span_id = span_id
|
|
44
123
|
@span_name = span_name && span_name.dup.freeze
|
|
@@ -55,6 +134,10 @@ module Datadog
|
|
|
55
134
|
@trace_runtime_id = trace_runtime_id && trace_runtime_id.dup.freeze
|
|
56
135
|
@trace_sampling_priority = trace_sampling_priority
|
|
57
136
|
@trace_service = trace_service && trace_service.dup.freeze
|
|
137
|
+
@trace_distributed_id = trace_distributed_id
|
|
138
|
+
@trace_flags = trace_flags
|
|
139
|
+
@trace_state = trace_state && trace_state.dup.freeze
|
|
140
|
+
@trace_state_unknown_fields = trace_state_unknown_fields && trace_state_unknown_fields.dup.freeze
|
|
58
141
|
|
|
59
142
|
freeze
|
|
60
143
|
end
|
|
@@ -4,12 +4,13 @@ require_relative '../core'
|
|
|
4
4
|
require_relative '../core/environment/identity'
|
|
5
5
|
require_relative '../core/utils'
|
|
6
6
|
|
|
7
|
-
require_relative 'sampling/ext'
|
|
8
7
|
require_relative 'event'
|
|
8
|
+
require_relative 'metadata/tagging'
|
|
9
|
+
require_relative 'sampling/ext'
|
|
9
10
|
require_relative 'span_operation'
|
|
10
|
-
require_relative 'trace_segment'
|
|
11
11
|
require_relative 'trace_digest'
|
|
12
|
-
require_relative '
|
|
12
|
+
require_relative 'trace_segment'
|
|
13
|
+
require_relative 'utils'
|
|
13
14
|
|
|
14
15
|
module Datadog
|
|
15
16
|
module Tracing
|
|
@@ -70,7 +71,7 @@ module Datadog
|
|
|
70
71
|
metrics: nil
|
|
71
72
|
)
|
|
72
73
|
# Attributes
|
|
73
|
-
@id = id ||
|
|
74
|
+
@id = id || Tracing::Utils.next_id
|
|
74
75
|
@max_length = max_length || DEFAULT_MAX_LENGTH
|
|
75
76
|
@parent_span_id = parent_span_id
|
|
76
77
|
@sampled = sampled.nil? ? true : sampled
|
|
@@ -462,6 +463,14 @@ module Datadog
|
|
|
462
463
|
def distributed_tags
|
|
463
464
|
meta.select { |name, _| name.start_with?(Metadata::Ext::Distributed::TAGS_PREFIX) }
|
|
464
465
|
end
|
|
466
|
+
|
|
467
|
+
def reset
|
|
468
|
+
@root_span = nil
|
|
469
|
+
@active_span = nil
|
|
470
|
+
@active_span_count = 0
|
|
471
|
+
@finished = false
|
|
472
|
+
@spans = []
|
|
473
|
+
end
|
|
465
474
|
end
|
|
466
475
|
end
|
|
467
476
|
end
|