mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-08-06 14:59:11 +08:00
80 lines
2.8 KiB
Python
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)
|