def extract( self, carrier: CarrierT, context: Optional[Context] = None, getter: Getter = default_getter, ) -> Context: if context is None: context = Context() traceid = _extract_identifier( getter.get(carrier, OT_TRACE_ID_HEADER), _valid_extract_traceid, INVALID_TRACE_ID, ) spanid = _extract_identifier( getter.get(carrier, OT_SPAN_ID_HEADER), _valid_extract_spanid, INVALID_SPAN_ID, ) sampled = _extract_first_element( getter.get(carrier, OT_SAMPLED_HEADER) ) if sampled == "true": traceflags = TraceFlags.SAMPLED else: traceflags = TraceFlags.DEFAULT if traceid != INVALID_TRACE_ID and spanid != INVALID_SPAN_ID: context = set_span_in_context( NonRecordingSpan( SpanContext( trace_id=traceid, span_id=spanid, is_remote=True, trace_flags=TraceFlags(traceflags), ) ), context, ) baggage = get_all(context) or {} for key in getter.keys(carrier): if not key.startswith(OT_BAGGAGE_PREFIX): continue baggage[ key[len(OT_BAGGAGE_PREFIX) :] ] = _extract_first_element(getter.get(carrier, key)) for key, value in baggage.items(): context = set_baggage(key, value, context) return context
def extract( self, carrier: textmap.CarrierT, context: typing.Optional[Context] = None, getter: textmap.Getter = textmap.default_getter, ) -> Context: """Extracts SpanContext from the carrier. See `opentelemetry.propagators.textmap.TextMapPropagator.extract` """ if context is None: context = Context() header = getter.get(carrier, self._TRACEPARENT_HEADER_NAME) if not header: return context match = re.search(self._TRACEPARENT_HEADER_FORMAT_RE, header[0]) if not match: return context version = match.group(1) trace_id = match.group(2) span_id = match.group(3) trace_flags = match.group(4) if trace_id == "0" * 32 or span_id == "0" * 16: return context if version == "00": if match.group(5): return context if version == "ff": return context tracestate_headers = getter.get(carrier, self._TRACESTATE_HEADER_NAME) if tracestate_headers is None: tracestate = None else: tracestate = TraceState.from_header(tracestate_headers) span_context = trace.SpanContext( trace_id=int(trace_id, 16), span_id=int(span_id, 16), is_remote=True, trace_flags=trace.TraceFlags(trace_flags), trace_state=tracestate, ) return trace.set_span_in_context(trace.NonRecordingSpan(span_context), context)
def _get_header_value( getter: textmap.Getter, carrier: textmap.CarrierT, ) -> typing.Optional[str]: # first try all lowercase header header = getter.get(carrier, _TRACE_CONTEXT_HEADER_NAME) if header: return header[0] # otherwise try to find in keys for mixed case for key in getter.keys(carrier): if key.lower() == _TRACE_CONTEXT_HEADER_NAME: header = getter.get(carrier, key) if header: return header[0] return None
def extract( self, carrier: CarrierT, context: typing.Optional[Context] = None, getter: Getter = default_getter, ) -> Context: if context is None: context = Context() header = getter.get(carrier, self.TRACE_ID_KEY) if not header: return context context = self._extract_baggage(getter, carrier, context) trace_id, span_id, flags = _parse_trace_id_header(header) if (trace_id == trace.INVALID_TRACE_ID or span_id == trace.INVALID_SPAN_ID): return context span = trace.NonRecordingSpan( trace.SpanContext( trace_id=trace_id, span_id=span_id, is_remote=True, trace_flags=trace.TraceFlags(flags & trace.TraceFlags.SAMPLED), )) return trace.set_span_in_context(span, context)
def extract( self, carrier: CarrierT, context: typing.Optional[Context] = None, getter: Getter = default_getter, ) -> Context: if context is None: context = Context() trace_id = extract_first_element(getter.get(carrier, self.TRACE_ID_KEY)) span_id = extract_first_element(getter.get(carrier, self.PARENT_ID_KEY)) sampled = extract_first_element( getter.get(carrier, self.SAMPLING_PRIORITY_KEY)) origin = extract_first_element(getter.get(carrier, self.ORIGIN_KEY)) trace_flags = trace.TraceFlags() if sampled and int(sampled) in ( constants.AUTO_KEEP, constants.USER_KEEP, ): trace_flags = trace.TraceFlags(trace.TraceFlags.SAMPLED) if trace_id is None or span_id is None: return context trace_state = [] if origin is not None: trace_state.append((constants.DD_ORIGIN, origin)) span_context = trace.SpanContext( trace_id=int(trace_id), span_id=int(span_id), is_remote=True, trace_flags=trace_flags, trace_state=trace.TraceState(trace_state), ) return set_span_in_context(trace.NonRecordingSpan(span_context), context)
def extract( self, carrier: CarrierT, context: typing.Optional[Context] = None, getter: Getter = default_getter, ) -> Context: trace_id_list = getter.get(carrier, self.TRACE_ID_KEY) span_id_list = getter.get(carrier, self.SPAN_ID_KEY) if not trace_id_list or not span_id_list: return trace.set_span_in_context(trace.INVALID_SPAN) return trace.set_span_in_context( trace.NonRecordingSpan( trace.SpanContext( trace_id=int(trace_id_list[0]), span_id=int(span_id_list[0]), is_remote=True, ) ) )
def extract( self, carrier: CarrierT, context: typing.Optional[Context] = None, getter: Getter = default_getter, ) -> Context: if context is None: context = Context() trace_header_list = getter.get(carrier, TRACE_HEADER_KEY) if not trace_header_list or len(trace_header_list) != 1: return context trace_header = trace_header_list[0] if not trace_header: return context try: ( trace_id, span_id, sampled, ) = AwsXRayPropagator._extract_span_properties(trace_header) except AwsParseTraceHeaderError as err: _logger.debug(err.message) return context options = 0 if sampled: options |= trace.TraceFlags.SAMPLED span_context = trace.SpanContext( trace_id=trace_id, span_id=span_id, is_remote=True, trace_flags=trace.TraceFlags(options), trace_state=trace.TraceState(), ) if not span_context.is_valid: _logger.debug( "Invalid Span Extracted. Inserting INVALID span into provided context." ) return context return trace.set_span_in_context( trace.NonRecordingSpan(span_context), context=context )
def extract( self, carrier: textmap.CarrierT, context: typing.Optional[Context] = None, getter: textmap.Getter = textmap.default_getter, ) -> Context: """Extract Baggage from the carrier. See `opentelemetry.propagators.textmap.TextMapPropagator.extract` """ if context is None: context = get_current() header = _extract_first_element( getter.get(carrier, self._BAGGAGE_HEADER_NAME) ) if not header or len(header) > self._MAX_HEADER_LENGTH: return context baggage_entries = header.split(",") total_baggage_entries = self._MAX_PAIRS for entry in baggage_entries: if total_baggage_entries <= 0: return context total_baggage_entries -= 1 if len(entry) > self._MAX_PAIR_LENGTH: continue try: name, value = entry.split("=", 1) except Exception: # pylint: disable=broad-except continue context = baggage.set_baggage( urllib.parse.unquote(name).strip(), urllib.parse.unquote(value).strip(), context=context, ) return context
def extract( self, carrier: CarrierT, context: typing.Optional[Context] = None, getter: Getter = default_getter, ) -> Context: if context is None: context = get_current() header = getter.get(carrier, self.TRACE_ID_KEY) if not header: return trace.set_span_in_context(trace.INVALID_SPAN, context) fields = _extract_first_element(header).split(":") context = self._extract_baggage(getter, carrier, context) if len(fields) != 4: return trace.set_span_in_context(trace.INVALID_SPAN, context) trace_id, span_id, _parent_id, flags = fields if ( trace_id == trace.INVALID_TRACE_ID or span_id == trace.INVALID_SPAN_ID ): return trace.set_span_in_context(trace.INVALID_SPAN, context) span = trace.NonRecordingSpan( trace.SpanContext( trace_id=int(trace_id, 16), span_id=int(span_id, 16), is_remote=True, trace_flags=trace.TraceFlags( int(flags, 16) & trace.TraceFlags.SAMPLED ), ) ) return trace.set_span_in_context(span, context)
def extract( self, carrier: textmap.CarrierT, context: Optional[Context] = None, getter: textmap.Getter = textmap.default_getter, ) -> Context: """Extract Baggage from the carrier. See `opentelemetry.propagators.textmap.TextMapPropagator.extract` """ if context is None: context = get_current() header = _extract_first_element( getter.get(carrier, self._BAGGAGE_HEADER_NAME) ) if not header: return context if len(header) > self._MAX_HEADER_LENGTH: _logger.warning( "Baggage header `%s` exceeded the maximum number of bytes per baggage-string", header, ) return context baggage_entries = split(_DELIMITER_PATTERN, header) total_baggage_entries = self._MAX_PAIRS if len(baggage_entries) > self._MAX_PAIRS: _logger.warning( "Baggage header `%s` exceeded the maximum number of list-members", header, ) for entry in baggage_entries: if len(entry) > self._MAX_PAIR_LENGTH: _logger.warning( "Baggage entry `%s` exceeded the maximum number of bytes per list-member", entry, ) continue if not entry: # empty string continue try: name, value = entry.split("=", 1) except Exception: # pylint: disable=broad-except _logger.warning( "Baggage list-member `%s` doesn't match the format", entry ) continue name = unquote_plus(name).strip().lower() value = unquote_plus(value).strip() if not _is_valid_pair(name, value): _logger.warning("Invalid baggage entry: `%s`", entry) continue context = set_baggage( name, value, context=context, ) total_baggage_entries -= 1 if total_baggage_entries == 0: break return context
def extract( self, carrier: CarrierT, context: typing.Optional[Context] = None, getter: Getter = default_getter, ) -> Context: if context is None: context = Context() trace_id = trace.INVALID_TRACE_ID span_id = trace.INVALID_SPAN_ID sampled = "0" flags = None single_header = _extract_first_element( getter.get(carrier, self.SINGLE_HEADER_KEY)) if single_header: # The b3 spec calls for the sampling state to be # "deferred", which is unspecified. This concept does not # translate to SpanContext, so we set it as recorded. sampled = "1" fields = single_header.split("-", 4) if len(fields) == 1: sampled = fields[0] elif len(fields) == 2: trace_id, span_id = fields elif len(fields) == 3: trace_id, span_id, sampled = fields elif len(fields) == 4: trace_id, span_id, sampled, _ = fields else: trace_id = (_extract_first_element( getter.get(carrier, self.TRACE_ID_KEY)) or trace_id) span_id = (_extract_first_element( getter.get(carrier, self.SPAN_ID_KEY)) or span_id) sampled = (_extract_first_element( getter.get(carrier, self.SAMPLED_KEY)) or sampled) flags = (_extract_first_element(getter.get( carrier, self.FLAGS_KEY)) or flags) if (trace_id == trace.INVALID_TRACE_ID or span_id == trace.INVALID_SPAN_ID or self._trace_id_regex.fullmatch(trace_id) is None or self._span_id_regex.fullmatch(span_id) is None): return context trace_id = int(trace_id, 16) span_id = int(span_id, 16) options = 0 # The b3 spec provides no defined behavior for both sample and # flag values set. Since the setting of at least one implies # the desire for some form of sampling, propagate if either # header is set to allow. if sampled in self._SAMPLE_PROPAGATE_VALUES or flags == "1": options |= trace.TraceFlags.SAMPLED return trace.set_span_in_context( trace.NonRecordingSpan( trace.SpanContext( # trace an span ids are encoded in hex, so must be converted trace_id=trace_id, span_id=span_id, is_remote=True, trace_flags=trace.TraceFlags(options), trace_state=trace.TraceState(), )), context, )