Files
2020-04-08 10:39:44 -07:00

80 lines
2.8 KiB
Python

from opentracing import InvalidCarrierException, SpanContextCorruptedException
from ddtrace.propagation.http import HTTPPropagator as DDHTTPPropagator
from ...internal.logger import get_logger
from ..span_context import SpanContext
from .propagator import Propagator
log = get_logger(__name__)
HTTP_BAGGAGE_PREFIX = 'ot-baggage-'
HTTP_BAGGAGE_PREFIX_LEN = len(HTTP_BAGGAGE_PREFIX)
class HTTPPropagator(Propagator):
"""OpenTracing compatible HTTP_HEADER and TEXT_MAP format propagator.
`HTTPPropagator` provides compatibility by using existing OpenTracing
compatible methods from the ddtracer along with new logic supporting the
outstanding OpenTracing-defined functionality.
"""
__slots__ = ['_dd_propagator']
def __init__(self):
self._dd_propagator = DDHTTPPropagator()
def inject(self, span_context, carrier):
"""Inject a span context into a carrier.
*span_context* is injected into the carrier by first using an
:class:`ddtrace.propagation.http.HTTPPropagator` to inject the ddtracer
specific fields.
Then the baggage is injected into *carrier*.
:param span_context: span context to inject.
:param carrier: carrier to inject into.
"""
if not isinstance(carrier, dict):
raise InvalidCarrierException('propagator expects carrier to be a dict')
self._dd_propagator.inject(span_context._dd_context, carrier)
# Add the baggage
if span_context.baggage is not None:
for key in span_context.baggage:
carrier[HTTP_BAGGAGE_PREFIX + key] = span_context.baggage[key]
def extract(self, carrier):
"""Extract a span context from a carrier.
:class:`ddtrace.propagation.http.HTTPPropagator` is used to extract
ddtracer supported fields into a `ddtrace.Context` context which is
combined with new logic to extract the baggage which is returned in an
OpenTracing compatible span context.
:param carrier: carrier to extract from.
:return: extracted span context.
"""
if not isinstance(carrier, dict):
raise InvalidCarrierException('propagator expects carrier to be a dict')
ddspan_ctx = self._dd_propagator.extract(carrier)
# if the dd propagator fails then it will return a new empty span
# context (with trace_id=None), we however want to raise an exception
# if this occurs.
if not ddspan_ctx.trace_id:
raise SpanContextCorruptedException('failed to extract span context')
baggage = {}
for key in carrier:
if key.startswith(HTTP_BAGGAGE_PREFIX):
baggage[key[HTTP_BAGGAGE_PREFIX_LEN:]] = carrier[key]
return SpanContext(ddcontext=ddspan_ctx, baggage=baggage)