From 93d79d149b6b9821347fca78fa3e65178eee7356 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Wed, 22 Jul 2020 17:22:07 -0600 Subject: [PATCH] Handle B3 trace_id and span_id correctly Fixes #933 These fields are not being handled correctly when one or both of them receive invalid values. --- .../sdk/trace/propagation/b3_format.py | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/b3_format.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/b3_format.py index c1f71d4d87e..540e3f3bdd4 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/b3_format.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/propagation/b3_format.py @@ -13,8 +13,10 @@ # limitations under the License. import typing +from re import fullmatch import opentelemetry.trace as trace +from opentelemetry.sdk.trace import generate_trace_id, generate_span_id from opentelemetry.context import Context from opentelemetry.trace.propagation.httptextformat import ( Getter, @@ -95,6 +97,13 @@ def extract( or flags ) + if ( + fullmatch(r"[\da-fA-F]{16}|[\da-fA-F]{32}", trace_id) is None or + fullmatch(r"[\da-fA-F]{16}", span_id) is None + ): + trace_id = generate_trace_id() + span_id = generate_span_id() + options = 0 # The b3 spec provides no defined behavior for both sample and # flag values set. Since the setting of at least one implies @@ -102,12 +111,19 @@ def extract( # header is set to allow. if sampled in self._SAMPLE_PROPAGATE_VALUES or flags == "1": options |= trace.TraceFlags.SAMPLED + + if isinstance(trace_id, str): + trace_id = int(trace_id, 16) + + if isinstance(span_id, str): + span_id = int(span_id, 16) + return trace.set_span_in_context( trace.DefaultSpan( trace.SpanContext( # trace an span ids are encoded in hex, so must be converted - trace_id=int(trace_id, 16), - span_id=int(span_id, 16), + trace_id=trace_id, + span_id=span_id, is_remote=True, trace_flags=trace.TraceFlags(options), trace_state=trace.TraceState(), @@ -123,7 +139,7 @@ def inject( ) -> None: span = trace.get_current_span(context=context) - if span.get_context() == trace.INVALID_SPAN_CONTEXT: + if span is None: return sampled = (trace.TraceFlags.SAMPLED & span.context.trace_flags) != 0