Skip to content

Commit

Permalink
Revert "feat: support w3c trace context" (#4295)
Browse files Browse the repository at this point in the history
Reverts #4170
The RFC for this feature is not yet approved and future changes are likely.
  • Loading branch information
ZStriker19 committed Oct 7, 2022
1 parent eb9cba1 commit 54764b6
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 178 deletions.
3 changes: 1 addition & 2 deletions ddtrace/internal/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
PROPAGATION_STYLE_DATADOG = "datadog"
PROPAGATION_STYLE_B3 = "b3"
PROPAGATION_STYLE_B3_SINGLE_HEADER = "b3 single header"
PROPAGATION_STYLE_W3C = "w3c"
PROPAGATION_STYLE_ALL = frozenset(
[PROPAGATION_STYLE_DATADOG, PROPAGATION_STYLE_B3, PROPAGATION_STYLE_B3_SINGLE_HEADER, PROPAGATION_STYLE_W3C]
[PROPAGATION_STYLE_DATADOG, PROPAGATION_STYLE_B3, PROPAGATION_STYLE_B3_SINGLE_HEADER]
) # type: FrozenSet[str]


Expand Down
132 changes: 12 additions & 120 deletions ddtrace/propagation/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from ..internal.constants import PROPAGATION_STYLE_B3
from ..internal.constants import PROPAGATION_STYLE_B3_SINGLE_HEADER
from ..internal.constants import PROPAGATION_STYLE_DATADOG
from ..internal.constants import PROPAGATION_STYLE_W3C
from ..internal.logger import get_logger
from ..internal.sampling import validate_sampling_decision
from ..span import _MetaDictType
Expand All @@ -42,7 +41,6 @@
_HTTP_HEADER_B3_SAMPLED = "x-b3-sampled"
_HTTP_HEADER_B3_FLAGS = "x-b3-flags"
_HTTP_HEADER_TAGS = "x-datadog-tags"
_HTTP_HEADER_W3C_TRACEPARENT = "traceparent"


def _possible_header(header):
Expand All @@ -62,7 +60,6 @@ def _possible_header(header):
_POSSIBLE_HTTP_HEADER_B3_SPAN_IDS = _possible_header(_HTTP_HEADER_B3_SPAN_ID)
_POSSIBLE_HTTP_HEADER_B3_SAMPLEDS = _possible_header(_HTTP_HEADER_B3_SAMPLED)
_POSSIBLE_HTTP_HEADER_B3_FLAGS = _possible_header(_HTTP_HEADER_B3_FLAGS)
_POSSIBLE_HTTP_HEADER_W3C_TRACEPARENT = _possible_header(_HTTP_HEADER_W3C_TRACEPARENT)


def _extract_header_value(possible_header_names, headers, default=None):
Expand All @@ -74,20 +71,20 @@ def _extract_header_value(possible_header_names, headers, default=None):
return default


def _hex_id_to_dd_id(hex_id):
def _b3_id_to_dd_id(b3_id):
# type: (str) -> int
"""Helper to convert hexadecimal trace/span hex ids into Datadog compatible ints
"""Helper to convert B3 trace/span hex ids into Datadog compatible ints
If the id is > 64 bit then truncate the trailing 64 bit.
"463ac35c9f6413ad48485a3953bb6124" -> "48485a3953bb6124" -> 5208512171318403364
"""
return int(hex_id[-16:], 16)
return int(b3_id[-16:], 16)


def _dd_id_to_hex_id(dd_id):
def _dd_id_to_b3_id(dd_id):
# type: (int) -> str
"""Helper to convert Datadog trace/span int ids into hexadecimal compatible ids"""
"""Helper to convert Datadog trace/span int ids into B3 compatible hex ids"""
# DEV: `hex(dd_id)` will give us `0xDEADBEEF`
# DEV: this gives us lowercase hex, which is what we want
return "{:x}".format(dd_id)
Expand Down Expand Up @@ -300,8 +297,8 @@ def _inject(span_context, headers):
log.debug("tried to inject invalid context %r", span_context)
return

headers[_HTTP_HEADER_B3_TRACE_ID] = _dd_id_to_hex_id(span_context.trace_id)
headers[_HTTP_HEADER_B3_SPAN_ID] = _dd_id_to_hex_id(span_context.span_id)
headers[_HTTP_HEADER_B3_TRACE_ID] = _dd_id_to_b3_id(span_context.trace_id)
headers[_HTTP_HEADER_B3_SPAN_ID] = _dd_id_to_b3_id(span_context.span_id)
sampling_priority = span_context.sampling_priority
# Propagate priority only if defined
if sampling_priority is not None:
Expand Down Expand Up @@ -342,9 +339,9 @@ def _extract(headers):
trace_id = None
span_id = None
if trace_id_val is not None:
trace_id = _hex_id_to_dd_id(trace_id_val) or None
trace_id = _b3_id_to_dd_id(trace_id_val) or None
if span_id_val is not None:
span_id = _hex_id_to_dd_id(span_id_val) or None
span_id = _b3_id_to_dd_id(span_id_val) or None

sampling_priority = None
if sampled is not None:
Expand Down Expand Up @@ -417,7 +414,7 @@ def _inject(span_context, headers):
log.debug("tried to inject invalid context %r", span_context)
return

single_header = "-".join((_dd_id_to_hex_id(span_context.trace_id), _dd_id_to_hex_id(span_context.span_id)))
single_header = "{}-{}".format(_dd_id_to_b3_id(span_context.trace_id), _dd_id_to_b3_id(span_context.span_id))
sampling_priority = span_context.sampling_priority
if sampling_priority is not None:
if sampling_priority <= 0:
Expand Down Expand Up @@ -460,9 +457,9 @@ def _extract(headers):
# DEV: We are allowed to have only x-b3-sampled/flags
# DEV: Do not allow `0` for trace id or span id, use None instead
if trace_id_val is not None:
trace_id = _hex_id_to_dd_id(trace_id_val) or None
trace_id = _b3_id_to_dd_id(trace_id_val) or None
if span_id_val is not None:
span_id = _hex_id_to_dd_id(span_id_val) or None
span_id = _b3_id_to_dd_id(span_id_val) or None

sampling_priority = None
if sampled is not None:
Expand All @@ -486,105 +483,6 @@ def _extract(headers):
return None


class _W3CTraceContext:
"""Helper class to inject/extract W3C Trace Context
https://www.w3.org/TR/trace-context/
Overview:
- ``traceparent`` describes the position of the incoming request in its
trace graph in a portable, fixed-length format. Its design focuses on
fast parsing. Every tracing tool MUST properly set traceparent even when
it only relies on vendor-specific information in tracestate
- ``tracestate`` extends traceparent with vendor-specific data represented
by a set of name/value pairs. Storing information in tracestate is
optional. [Unsupported]
The format for ``traceparent`` is::
HEXDIGLC = DIGIT / "a" / "b" / "c" / "d" / "e" / "f"
value = version "-" version-format
version = 2HEXDIGLC
version-format = trace-id "-" parent-id "-" trace-flags
trace-id = 32HEXDIGLC
parent-id = 16HEXDIGLC
trace-flags = 2HEXDIGLC
Example value of HTTP ``traceparent`` header::
value = 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
base16(version) = 00
base16(trace-id) = 4bf92f3577b34da6a3ce929d0e0e4736
base16(parent-id) = 00f067aa0ba902b7
base16(trace-flags) = 01 // sampled
Implementation details:
- Datadog Trace and Span IDs are 64-bit unsigned integers.
- The W3C Trace Context Trace ID is a 16-byte hexadecimal string. This is
transformed for propagation between Datadog by taking the lower
8-bytes.
- The tracestate header will be supported in a future release.
"""

@staticmethod
def _inject(span_context, headers):
# type: (Context, Dict[str, str]) -> None
# use hex to convert back, the trace id will be pre-pended with a bunch of 0s to fill in for previous values
trace_id = span_context.trace_id
span_id = span_context.span_id
if trace_id is None or span_id is None:
log.debug("tried to inject invalid context %r", span_context)
return

sampling_priority = span_context.sampling_priority
trace_flags = 1 if sampling_priority and sampling_priority >= AUTO_KEEP else 0

# There is currently only a single version so we always start with 00
traceparent = "00-{:032x}-{:016x}-{:02x}".format(trace_id, span_id, trace_flags)
headers[_HTTP_HEADER_W3C_TRACEPARENT] = traceparent

@staticmethod
def _extract(headers):
# type: (Dict[str, str]) -> Optional[Context]
tp = _extract_header_value(_POSSIBLE_HTTP_HEADER_W3C_TRACEPARENT, headers)
if tp is None:
return None

version, trace_id_hex, span_id_hex, trace_flags_hex = tp.split("-")

try:
# currently 00 is the only version format, but if future versions come up we may need to add changes
if version != "00":
log.warning("unsupported traceparent version:%s . Will still attempt to parse.", (version))

if len(trace_id_hex) == 32 and len(span_id_hex) == 16 and len(trace_flags_hex) >= 2:
trace_id = _hex_id_to_dd_id(trace_id_hex)
span_id = _hex_id_to_dd_id(span_id_hex)

# All 0s are invalid values
assert trace_id != 0
assert span_id != 0

trace_flags = _hex_id_to_dd_id(trace_flags_hex)
# there's currently only one trace flag, which denotes sampling priority was set to keep
sampling_priority = float(trace_flags & 0x1)

else:
log.debug("W3C traceparent hex length incorrect: %s", tp)

return Context(
trace_id=trace_id,
span_id=span_id,
sampling_priority=sampling_priority,
)
except (ValueError, AssertionError):
log.exception("received invalid w3c traceparent: %s.", tp)
return None


class HTTPPropagator(object):
"""A HTTP Propagator using HTTP headers as carrier."""

Expand Down Expand Up @@ -619,8 +517,6 @@ def parent_call():
_B3MultiHeader._inject(span_context, headers)
if PROPAGATION_STYLE_B3_SINGLE_HEADER in config._propagation_style_inject:
_B3SingleHeader._inject(span_context, headers)
if PROPAGATION_STYLE_W3C in config._propagation_style_inject:
_W3CTraceContext._inject(span_context, headers)

@staticmethod
def extract(headers):
Expand Down Expand Up @@ -661,10 +557,6 @@ def my_controller(url, headers):
context = _B3SingleHeader._extract(normalized_headers)
if context is not None:
return context
if PROPAGATION_STYLE_W3C in config._propagation_style_extract:
context = _W3CTraceContext._extract(normalized_headers)
if context is not None:
return context
except Exception:
log.debug("error while extracting context propagation headers", exc_info=True)
return Context()
1 change: 0 additions & 1 deletion docs/spelling_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ subdomains
submodule
submodules
timestamp
traceparent
tweens
uWSGI
unbuffered
Expand Down

This file was deleted.

45 changes: 0 additions & 45 deletions tests/tracer/test_propagation.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from ddtrace.internal.constants import PROPAGATION_STYLE_B3
from ddtrace.internal.constants import PROPAGATION_STYLE_B3_SINGLE_HEADER
from ddtrace.internal.constants import PROPAGATION_STYLE_DATADOG
from ddtrace.internal.constants import PROPAGATION_STYLE_W3C
from ddtrace.propagation._utils import get_wsgi_header
from ddtrace.propagation.http import HTTPPropagator
from ddtrace.propagation.http import HTTP_HEADER_ORIGIN
Expand All @@ -22,7 +21,6 @@
from ddtrace.propagation.http import _HTTP_HEADER_B3_SPAN_ID
from ddtrace.propagation.http import _HTTP_HEADER_B3_TRACE_ID
from ddtrace.propagation.http import _HTTP_HEADER_TAGS
from ddtrace.propagation.http import _HTTP_HEADER_W3C_TRACEPARENT

from ..utils import override_global_config

Expand Down Expand Up @@ -404,19 +402,12 @@ def test_get_wsgi_header(tracer):
B3_SINGLE_HEADERS_INVALID = {
_HTTP_HEADER_B3_SINGLE: "NON_HEX_VALUE-e457b5a2e4d86bd1-1",
}
W3C_HEADERS_VALID = {
_HTTP_HEADER_W3C_TRACEPARENT: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
}
W3C_HEADERS_INVALID = {
_HTTP_HEADER_W3C_TRACEPARENT: "00-a3ce929d0e0e4736-00f067aa0ba902b7-01",
}


ALL_HEADERS = {}
ALL_HEADERS.update(DATADOG_HEADERS_VALID)
ALL_HEADERS.update(B3_HEADERS_VALID)
ALL_HEADERS.update(B3_SINGLE_HEADERS_VALID)
ALL_HEADERS.update(W3C_HEADERS_VALID)

EXTRACT_FIXTURES = [
# Datadog headers
Expand Down Expand Up @@ -701,24 +692,6 @@ def test_get_wsgi_header(tracer):
B3_SINGLE_HEADERS_VALID,
CONTEXT_EMPTY,
),
# w3c headers
(
"valid_w3c_simple",
[PROPAGATION_STYLE_W3C],
W3C_HEADERS_VALID,
{
"trace_id": 11803532876627986230,
"span_id": 67667974448284343,
"sampling_priority": 1,
"dd_origin": None,
},
),
(
"invalid_w3c",
[PROPAGATION_STYLE_W3C],
W3C_HEADERS_INVALID,
CONTEXT_EMPTY,
),
# All valid headers
(
"valid_all_headers_default_style",
Expand Down Expand Up @@ -876,7 +849,6 @@ def test_propagation_extract(name, styles, headers, expected_context, run_python
env["DD_TRACE_PROPAGATION_STYLE_EXTRACT"] = ",".join(styles)
stdout, stderr, status, _ = run_python_code_in_subprocess(code=code, env=env)
assert status == 0, (stdout, stderr)
print(stderr)
assert stderr == b"", (stdout, stderr)

result = json.loads(stdout.decode())
Expand Down Expand Up @@ -1093,19 +1065,6 @@ def test_propagation_extract(name, styles, headers, expected_context, run_python
},
{_HTTP_HEADER_B3_SINGLE: "b5a2814f70060771-7197677932a62370"},
),
# w3c only
(
"valid_w3c_simple",
[PROPAGATION_STYLE_W3C],
VALID_DATADOG_CONTEXT,
{_HTTP_HEADER_W3C_TRACEPARENT: "00-0000000000000000b5a2814f70060771-7197677932a62370-01"},
),
(
"invalid_w3c_style",
[PROPAGATION_STYLE_W3C],
{},
{},
),
# All styles
(
"valid_all_styles",
Expand All @@ -1120,7 +1079,6 @@ def test_propagation_extract(name, styles, headers, expected_context, run_python
_HTTP_HEADER_B3_SPAN_ID: "7197677932a62370",
_HTTP_HEADER_B3_SAMPLED: "1",
_HTTP_HEADER_B3_SINGLE: "b5a2814f70060771-7197677932a62370-1",
_HTTP_HEADER_W3C_TRACEPARENT: "00-0000000000000000b5a2814f70060771-7197677932a62370-01",
},
),
(
Expand All @@ -1135,7 +1093,6 @@ def test_propagation_extract(name, styles, headers, expected_context, run_python
_HTTP_HEADER_B3_SPAN_ID: "7197677932a62370",
_HTTP_HEADER_B3_FLAGS: "1",
_HTTP_HEADER_B3_SINGLE: "b5a2814f70060771-7197677932a62370-d",
_HTTP_HEADER_W3C_TRACEPARENT: "00-0000000000000000b5a2814f70060771-7197677932a62370-01",
},
),
(
Expand All @@ -1150,7 +1107,6 @@ def test_propagation_extract(name, styles, headers, expected_context, run_python
_HTTP_HEADER_B3_SPAN_ID: "7197677932a62370",
_HTTP_HEADER_B3_SAMPLED: "0",
_HTTP_HEADER_B3_SINGLE: "b5a2814f70060771-7197677932a62370-0",
_HTTP_HEADER_W3C_TRACEPARENT: "00-0000000000000000b5a2814f70060771-7197677932a62370-00",
},
),
(
Expand All @@ -1166,7 +1122,6 @@ def test_propagation_extract(name, styles, headers, expected_context, run_python
_HTTP_HEADER_B3_TRACE_ID: "b5a2814f70060771",
_HTTP_HEADER_B3_SPAN_ID: "7197677932a62370",
_HTTP_HEADER_B3_SINGLE: "b5a2814f70060771-7197677932a62370",
_HTTP_HEADER_W3C_TRACEPARENT: "00-0000000000000000b5a2814f70060771-7197677932a62370-00",
},
),
]
Expand Down

0 comments on commit 54764b6

Please sign in to comment.