def make_context(cls, headers: Headers) -> Optional[BaseTraceContext]: """Converts available headers to BaseTraceContext, if headers mapping does not contain zipkin headers, function returns None. """ # TODO: add validation for trace_id/span_id/parent_id # normalize header names just in case someone passed regular dict # instead dict with case insensitive keys headers = {k.lower(): v for k, v in headers.items()} required = (cls.TRACE_ID_HEADER.lower(), cls.SPAN_ID_HEADER.lower()) has_b3 = all(h in headers for h in required) has_b3_single = cls.SINGLE_HEADER in headers debug = cls.parse_debug_header(headers) sampled = debug if debug else cls.parse_sampled_header(headers) if not (has_b3_single or has_b3): return None if has_b3: try: parent_id = int(headers[cls.PARENT_ID_HEADER.lower()], 16) except KeyError: parent_id = 0 context = ZipkinTraceContext( trace_id=int(headers[cls.TRACE_ID_HEADER.lower()], 16), parent_id=parent_id, span_id=int(headers[cls.SPAN_ID_HEADER.lower()], 16), sampled=sampled, debug=debug, shared=False, ) return context return cls._parse_single_header(headers)
async def create_task( self, channel_name: str, kwargs: Dict[Any, Any] = None, **message_kwargs: Headers, ) -> None: headers: Headers = message_kwargs.pop("headers", {}) with self._producer(channel_name, headers) as msg_headers: return await super().create_task(channel_name, kwargs, headers=msg_headers, **message_kwargs)
def make_context(cls, headers: Headers) -> Optional[BaseTraceContext]: # TODO: add validation for trace_id/span_id/parent_id headers = {k.lower(): v for k, v in headers.items()} try: # TODO: flags. debug and sampled trace_id, span_id, parent_id, flags = cls.parse_trace_id( headers[cls.TRACE_ID_HEADER]) except (ValueError, KeyError): return None return JaegerTraceContext( trace_id=trace_id, parent_id=parent_id, span_id=span_id, sampled=bool(flags & cls.SAMPLED_FLAG), debug=bool(flags & cls.DEBUG_FLAG), shared=False, )
def parse_debug_header(cls, headers: Headers) -> bool: return headers.get(cls.FLAGS_HEADER, "0") == "1"
def parse_sampled_header(cls, headers: Headers) -> Optional[bool]: sampled = headers.get(cls.SAMPLED_ID_HEADER.lower(), None) if not bool(sampled): return None return sampled == "1"