Skip to content

Commit bda528c

Browse files
authored
fix(tracing): avoid truncating b3 and w3c trace ids to 64bits (#5509)
Builds on: #5434 Previously the trace id in b3 and w3c trace headers were truncated from 128 bits to 64 bits if `DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED=False`. This behavior is incorrect. The trace ids in b3 and w3c headers should NEVER be truncated. Note - This PR does not require a release note. It is a fix for an [unreleased](a1e27bb) change. Note - A regression test is not required. This issue was detected by system-tests: [ex](https://github.com/DataDog/system-tests/blob/6168fa7e6f485e2655f81801a677356624409620/parametric/test_128_bit_traceids.py#L230). ### Background The implementation of 128 bit trace ids is compatible with all versions of the agent. Trace ids are always sent to the agent as 64 bits (ex: [v05 encoder](https://github.com/DataDog/dd-trace-py/blob/v1.11.2/ddtrace/internal/_encoding.pyx#L721)). The higher order bits are stored in a tag in the [tracetagsprocessor](https://github.com/DataDog/dd-trace-py/blob/v1.11.2/ddtrace/internal/processor/trace.py#L136). - If the datadog agent only support 64bit trace ids, the agent will ignore the tag and the original 128 bit trace id will be truncated to 64bits. This preserves the current behavior. - If the datadog agent supports 128bit trace ids the agent will reconstruct the full 128 bit trace id using the encoded trace_id field and the _dd.p.tid tag. ## Checklist - [x] Change(s) are motivated and described in the PR description. - [x] Testing strategy is described if automated tests are not included in the PR. - [x] Risk is outlined (performance impact, potential for breakage, maintainability, etc). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] [Library release note guidelines](https://ddtrace.readthedocs.io/en/stable/contributing.html#Release-Note-Guidelines) are followed. - [x] Documentation is included (in-code, generated user docs, [public corp docs](https://github.com/DataDog/documentation/)). - [x] PR description includes explicit acknowledgement/acceptance of the performance implications of this PR as reported in the benchmarks PR comment. ## Reviewer Checklist - [ ] Title is accurate. - [ ] No unnecessary changes are introduced. - [ ] Description motivates each change. - [ ] Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [ ] Testing strategy adequately addresses listed risk(s). - [ ] Change is maintainable (easy to change, telemetry, documentation). - [ ] Release note makes sense to a user of the library. - [ ] Reviewer has explicitly acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment.
1 parent 9c1cbde commit bda528c

File tree

2 files changed

+11
-34
lines changed

2 files changed

+11
-34
lines changed

ddtrace/propagation/http.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,8 @@ def _extract_header_value(possible_header_names, headers, default=None):
106106

107107
def _hex_id_to_dd_id(hex_id):
108108
# type: (str) -> int
109-
"""Helper to convert hex ids into Datadog compatible ints
110-
If the id is > 64 bit and 128bit trace_id generation is disabled then truncate the trailing 64 bit.
111-
"463ac35c9f6413ad48485a3953bb6124" -> "48485a3953bb6124" -> 5208512171318403364
112-
Otherwise convert the full trace id into lower case hex values.
113-
"""
114-
if config._128_bit_trace_id_enabled:
115-
return int(hex_id, 16)
116-
return int(hex_id[-16:], 16)
109+
"""Helper to convert hex ids into Datadog compatible ints."""
110+
return int(hex_id, 16)
117111

118112

119113
_b3_id_to_dd_id = _hex_id_to_dd_id

tests/tracer/test_propagation.py

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from ddtrace.internal.constants import PROPAGATION_STYLE_DATADOG
1212
from ddtrace.internal.constants import _PROPAGATION_STYLE_NONE
1313
from ddtrace.internal.constants import _PROPAGATION_STYLE_W3C_TRACECONTEXT
14-
from ddtrace.internal.utils.formats import asbool
1514
from ddtrace.propagation._utils import get_wsgi_header
1615
from ddtrace.propagation.http import HTTPPropagator
1716
from ddtrace.propagation.http import HTTP_HEADER_ORIGIN
@@ -79,7 +78,7 @@ def test_inject_128bit_trace_id_datadog():
7978

8079

8180
@pytest.mark.subprocess(
82-
env=dict(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED="true", DD_TRACE_PROPAGATION_STYLE=PROPAGATION_STYLE_B3),
81+
env=dict(DD_TRACE_PROPAGATION_STYLE=PROPAGATION_STYLE_B3),
8382
)
8483
def test_inject_128bit_trace_id_b3multi():
8584
from ddtrace.context import Context
@@ -101,10 +100,7 @@ def test_inject_128bit_trace_id_b3multi():
101100

102101

103102
@pytest.mark.subprocess(
104-
env=dict(
105-
DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED="true",
106-
DD_TRACE_PROPAGATION_STYLE=PROPAGATION_STYLE_B3_SINGLE_HEADER,
107-
),
103+
env=dict(DD_TRACE_PROPAGATION_STYLE=PROPAGATION_STYLE_B3_SINGLE_HEADER),
108104
)
109105
def test_inject_128bit_trace_id_b3_single_header():
110106
from ddtrace.context import Context
@@ -126,10 +122,7 @@ def test_inject_128bit_trace_id_b3_single_header():
126122

127123

128124
@pytest.mark.subprocess(
129-
env=dict(
130-
DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED="true",
131-
DD_TRACE_PROPAGATION_STYLE=_PROPAGATION_STYLE_W3C_TRACECONTEXT,
132-
),
125+
env=dict(DD_TRACE_PROPAGATION_STYLE=_PROPAGATION_STYLE_W3C_TRACECONTEXT),
133126
)
134127
def test_inject_128bit_trace_id_tracecontext():
135128
from ddtrace.context import Context
@@ -317,7 +310,7 @@ def test_extract_128bit_trace_ids_datadog():
317310

318311

319312
@pytest.mark.subprocess(
320-
env=dict(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED="true", DD_TRACE_PROPAGATION_STYLE=PROPAGATION_STYLE_B3),
313+
env=dict(DD_TRACE_PROPAGATION_STYLE=PROPAGATION_STYLE_B3),
321314
)
322315
def test_extract_128bit_trace_ids_b3multi():
323316
from ddtrace.propagation.http import HTTPPropagator
@@ -344,10 +337,7 @@ def test_extract_128bit_trace_ids_b3multi():
344337

345338

346339
@pytest.mark.subprocess(
347-
env=dict(
348-
DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED="true",
349-
DD_TRACE_PROPAGATION_STYLE=PROPAGATION_STYLE_B3_SINGLE_HEADER,
350-
),
340+
env=dict(DD_TRACE_PROPAGATION_STYLE=PROPAGATION_STYLE_B3_SINGLE_HEADER),
351341
)
352342
def test_extract_128bit_trace_ids_b3_single_header():
353343
from ddtrace.propagation.http import HTTPPropagator
@@ -373,10 +363,7 @@ def test_extract_128bit_trace_ids_b3_single_header():
373363

374364

375365
@pytest.mark.subprocess(
376-
env=dict(
377-
DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED="true",
378-
DD_TRACE_PROPAGATION_STYLE=_PROPAGATION_STYLE_W3C_TRACECONTEXT,
379-
),
366+
env=dict(DD_TRACE_PROPAGATION_STYLE=_PROPAGATION_STYLE_W3C_TRACECONTEXT),
380367
)
381368
def test_extract_128bit_trace_ids_tracecontext():
382369
from ddtrace.propagation.http import HTTPPropagator
@@ -596,6 +583,9 @@ def test_get_wsgi_header(tracer):
596583
assert get_wsgi_header("x-datadog-trace-id") == "HTTP_X_DATADOG_TRACE_ID"
597584

598585

586+
TRACE_ID = 171395628812617415352188477958425669623
587+
TRACE_ID_HEX = "80f198ee56343ba864fe8b2a57d3eff7"
588+
599589
# for testing with other propagation styles
600590
TRACECONTEXT_HEADERS_VALID_BASIC = {
601591
_HTTP_HEADER_TRACEPARENT: "00-80f198ee56343ba864fe8b2a57d3eff7-00f067aa0ba902b7-01",
@@ -607,13 +597,6 @@ def test_get_wsgi_header(tracer):
607597
_HTTP_HEADER_TRACESTATE: "dd=s:2;o:rum;t.dm:-4;t.usr.id:baz64,congo=t61rcWkgMzE",
608598
}
609599

610-
if asbool(os.getenv("DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED")):
611-
TRACE_ID = 171395628812617415352188477958425669623
612-
TRACE_ID_HEX = "80f198ee56343ba864fe8b2a57d3eff7"
613-
else:
614-
TRACE_ID = 7277407061855694839
615-
TRACE_ID_HEX = "000000000000000064fe8b2a57d3eff7"
616-
617600

618601
@pytest.mark.parametrize(
619602
"sampling_priority_tp,sampling_priority_ts,expected_sampling_priority",

0 commit comments

Comments
 (0)