def extract(self, carrier): if isinstance(carrier, dict): trace_id = carrier.get('trace_id') span_id = carrier.get('span_id') parent_id = carrier.get('parent_id') flags = carrier.get('traceflags') else: if hasattr(carrier, 'trace_id'): trace_id = getattr(carrier, 'trace_id') else: raise InvalidCarrierException('carrier has no trace_id') if hasattr(carrier, 'span_id'): span_id = getattr(carrier, 'span_id') else: raise InvalidCarrierException('carrier has no span_id') if hasattr(carrier, 'parent_id'): parent_id = getattr(carrier, 'parent_id') else: raise InvalidCarrierException('carrier has no parent_id') if hasattr(carrier, 'traceflags'): flags = getattr(carrier, 'traceflags') else: raise InvalidCarrierException('carrier has no traceflags') if not trace_id: return None return SpanContext(trace_id=trace_id, span_id=span_id, parent_id=parent_id, flags=flags, baggage=None)
def extract(self, carrier): if not hasattr(carrier, 'iteritems'): raise InvalidCarrierException('carrier not a collection') trace_id, span_id, parent_id, flags = None, None, None, None baggage = None debug_id = None for key, value in six.iteritems(carrier): uc_key = key.lower() if uc_key == self.trace_id_header: if self.url_encoding: value = urllib.parse.unquote(value) trace_id, span_id, parent_id, flags = \ span_context_from_string(value) elif uc_key.startswith(self.baggage_prefix): if self.url_encoding: value = urllib.parse.unquote(value) attr_key = key[self.prefix_length:] if baggage is None: baggage = {attr_key.lower(): value} else: baggage[attr_key.lower()] = value elif uc_key == self.debug_id_header: if self.url_encoding: value = urllib.parse.unquote(value) debug_id = value if not trace_id and baggage: raise SpanContextCorruptedException('baggage without trace ctx') if not trace_id: if debug_id is not None: return SpanContext.with_debug_id(debug_id=debug_id) return None return SpanContext(trace_id=trace_id, span_id=span_id, parent_id=parent_id, flags=flags, baggage=baggage)
def extract(self, carrier): if not isinstance(carrier, bytearray): raise InvalidCarrierException('carrier not a bytearray') ctx_len = struct.unpack('I', carrier[0:4])[0] carrier = json.loads(str(carrier[4:4 + ctx_len])) trace_id, span_id, parent_id, flags = None, None, None, None baggage = None for key, value in six.iteritems(carrier): uc_key = key.lower() if uc_key == self.trace_id_header: trace_id, span_id, parent_id, flags = \ span_context_from_string(value) else: if baggage is None: baggage = {uc_key: value} else: baggage[uc_key] = value if baggage == None or (not isinstance(baggage, dict)): raise SpanContextCorruptedException() return SpanContext(trace_id=trace_id, span_id=span_id, parent_id=parent_id, flags=flags, baggage=baggage)
def extract(self, carrier: memoryview): if type(carrier) is not memoryview: raise InvalidCarrierException() if len(carrier) < _BINARY_FORMAT_LENGTH: raise SpanContextCorruptedException() try: version = carrier[0] trace_id_bytes = bytes(carrier[1:17]) parent_id = bytes(carrier[17:25]) # flags_bytes = carrier[25] except (IndexError, ): raise SpanContextCorruptedException() else: if version == 255: raise SpanContextCorruptedException() try: trace_id = UUID(bytes=trace_id_bytes) except ValueError: raise SpanContextCorruptedException() if trace_id.variant != uuid.RFC_4122 or trace_id.version != 1: raise SpanContextCorruptedException() return SpanContext( event_reference=EventReference(trace_id=trace_id, event_id=parent_id, eu_id=None), baggage=SpanContext.EMPTY_BAGGAGE, )
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)
def inject(self, span_context, carrier): if not isinstance(carrier, dict): raise InvalidCarrierException('carrier not a dictionary') carrier['trace_id'] = span_context.trace_id carrier['span_id'] = span_context.span_id carrier['parent_id'] = span_context.parent_id carrier['traceflags'] = span_context.flags
def inject(self, span_context, carrier): if not isinstance(carrier, dict): raise InvalidCarrierException('carrier not a collection') # Note: we do not url-encode the trace ID because the ':' separator # is not a problem for HTTP header values carrier[self.trace_id_header] = span_context_to_string( trace_id=span_context.trace_id, span_id=span_context.span_id, parent_id=span_context.parent_id, flags=span_context.flags) baggage = span_context.baggage if baggage: for key, value in six.iteritems(baggage): encoded_key = key if isinstance(key, six.binary_type): encoded_key = str(key, 'utf-8') if self.url_encoding: encoded_value = urllib_parse.quote(value) else: if isinstance(value, six.binary_type): encoded_value = str(value, 'utf-8') else: encoded_value = value # Leave the below print(), you will thank me next time you debug unicode strings # print('adding baggage', key, '=>', value, 'as', encoded_key, '=>', encoded_value) header_key = '%s%s' % (self.baggage_prefix, encoded_key) carrier[header_key] = encoded_value
def extract(self, carrier): if not isinstance(carrier, dict): raise InvalidCarrierException('carrier not a dictionary') trace_id = span_id = parent_id = None flags = 0x00 for header_key, header_value in six.iteritems(carrier): if header_value is None: continue lower_key = header_key.lower() if lower_key == self._trace_header_lc: trace_id = header_to_hex(header_value) elif lower_key == self._span_header_lc: span_id = header_to_hex(header_value) elif lower_key == self._parent_span_header_lc: parent_id = header_to_hex(header_value) elif lower_key == self._sampled_header_lc and header_value == '1': flags |= SAMPLED_FLAG elif lower_key == self._flags_header_lc and header_value == '1': flags |= DEBUG_FLAG if not trace_id or not span_id: return None return SpanContext(trace_id=trace_id, span_id=span_id, parent_id=parent_id, flags=flags, baggage=None)
def extract(self, carrier): if not isinstance(carrier, bytearray): raise InvalidCarrierException('carrier not a bytearray') baggage = {} high_trace_id, low_trace_id, span_id, parent_id, flags, baggage_count = \ struct.unpack('>QQQQBI', carrier[:37]) # if high_trace_id isn't 0, then we are dealing with 128bit trace id integer, # therefore unpack into 1 number if high_trace_id: trace_id = (high_trace_id << 64) | low_trace_id else: trace_id = low_trace_id if baggage_count != 0: baggage_data = carrier[37:] for _ in range(baggage_count): key, value, bytes_read = self._unpack_baggage_item( baggage_data) baggage[key] = value baggage_data = baggage_data[bytes_read:] return SpanContext(trace_id=trace_id, span_id=span_id, parent_id=parent_id, flags=flags, baggage=baggage)
def inject(self, span_context, carrier): if not isinstance(carrier, dict): raise InvalidCarrierException('carrier not a collection') # Note: we do not url-encode the trace ID because the ':' separator # is not a problem for HTTP header values carrier[self.trace_id_header] = span_context_to_string( trace_id=span_context.trace_id, span_id=span_context.span_id, parent_id=span_context.parent_id, flags=span_context.flags) baggage = span_context.baggage if baggage: for key, value in six.iteritems(baggage): encoded_key = key if self.url_encoding: encoded_value = urllib.parse.quote(value) # we assume that self.url_encoding means we are injecting # into HTTP headers. httplib does not like unicode strings # so we convert the key to utf-8. The URL-encoded value is # already a plain string. if six.PY2 and isinstance(key, six.text_type): encoded_key = key.encode('utf-8') else: encoded_value = value header_key = '%s%s' % (self.baggage_prefix, encoded_key) carrier[header_key] = encoded_value
def inject(self, span_context: SpanContext, carrier: bytearray): if type(carrier) is not bytearray: raise InvalidCarrierException() carrier.extend(b'\00') # version carrier.extend(span_context.event_reference.trace_id.bytes) carrier.extend(span_context.event_reference.event_id) carrier.extend(b'\01') # flag sampled=true
def extract(self, carrier): if type(carrier) is not bytearray: raise InvalidCarrierException() try: span_context = pickle.loads(carrier) except (EOFError, pickle.PickleError): raise SpanContextCorruptedException() return span_context
def inject(self, span_context, format, carrier): if format in (Format.HTTP_HEADERS, Format.TEXT_MAP): if not isinstance(carrier, dict): raise InvalidCarrierException("carrier for {} format should be dict-like".format(format)) val = span_context.trace_parent.to_ascii() carrier[constants.TRACEPARENT_HEADER_NAME] = val if self._agent.config.use_elastic_traceparent_header: carrier[constants.TRACEPARENT_LEGACY_HEADER_NAME] = val return raise UnsupportedFormatException
def inject(self, span_context, carrier): if not isinstance(carrier, dict): raise InvalidCarrierException('carrier not a dictionary') carrier[self.trace_header] = format(span_context.trace_id, 'x').zfill(16) carrier[self.span_header] = format(span_context.span_id, 'x').zfill(16) if span_context.parent_id is not None: carrier[self.parent_span_header] = format(span_context.parent_id, 'x').zfill(16) carrier[self.flags_header] = str(span_context.flags)
def inject(self, span_context, carrier): if not isinstance(carrier, dict): raise InvalidCarrierException('carrier not a dictionary') carrier[self.trace_header] = format(span_context.trace_id, 'x').zfill(16) carrier[self.span_header] = format(span_context.span_id, 'x').zfill(16) if span_context.parent_id is not None: carrier[self.parent_span_header] = format(span_context.parent_id, 'x').zfill(16) if span_context.flags & DEBUG_FLAG == DEBUG_FLAG: carrier[self.flags_header] = '1' elif span_context.flags & SAMPLED_FLAG == SAMPLED_FLAG: carrier[self.sampled_header] = '1'
def inject(self, span_context, format, carrier): if format in (Format.HTTP_HEADERS, Format.TEXT_MAP): if not isinstance(carrier, dict): raise InvalidCarrierException( "carrier for {} format should be dict-like".format(format)) carrier[ constants. TRACEPARENT_HEADER_NAME] = span_context.trace_parent.to_ascii( ) return raise UnsupportedFormatException
def inject(self, span_context, carrier): if not isinstance(carrier, bytearray): raise InvalidCarrierException('carrier not a bytearray') baggage = span_context.baggage.copy() baggage[self.trace_id_header] = span_context_to_string( trace_id=span_context.trace_id, span_id=span_context.span_id, parent_id=span_context.parent_id, flags=span_context.flags) bin_baggage = bytearray(json.dumps(baggage)) carrier.extend(bytearray(struct.pack("I", len(bin_baggage)))) carrier.extend(bin_baggage)
def extract(self, carrier): if type(carrier) is not bytearray: raise InvalidCarrierException() state = TracerState() state.ParseFromString(str(carrier[_proto_size_bytes:])) baggage = {} for k in state.baggage_items: baggage[k] = state.baggage_items[k] return SpanContext( span_id=state.span_id, trace_id=state.trace_id, baggage=baggage, sampled=state.sampled)
def extract(self, carrier): if type(carrier) is not bytearray: raise InvalidCarrierException() serializedProto = standard_b64decode(carrier) state = BinaryCarrier() state.ParseFromString(bytes(serializedProto)) baggage = {} for k in state.basic_ctx.baggage_items: baggage[k] = state.basic_ctx.baggage_items[k] return SpanContext(span_id=state.basic_ctx.span_id, trace_id=state.basic_ctx.trace_id, baggage=baggage, sampled=state.basic_ctx.sampled)
def inject(self, span, carrier): if type(carrier) is not bytearray: raise InvalidCarrierException() state = TracerState() state.trace_id = span.raw.context.trace_id state.span_id = span.raw.context.span_id state.sampled = span.raw.context.sampled if span.raw.baggage is not None: for key in span.raw.baggage: state.baggage_items[key] = span.raw.baggage[key] # The binary format is {uint32}{protobuf} using big-endian for the uint carrier.extend(struct.pack(">I", state.ByteSize())) carrier.extend(state.SerializeToString())
def inject(self, span_context, carrier): if type(carrier) is not bytearray: raise InvalidCarrierException() _wstr(carrier, span_context.trace_id) _wstr(carrier, span_context.span_id) carrier.extend(struct.pack('?', span_context.sampled)) carrier.extend( struct.pack( '>I', len(span_context.baggage) if span_context.baggage is not None else 0)) if span_context.baggage is not None: for key in span_context.baggage: _wstr(carrier, key) _wstr(carrier, span_context.baggage[key])
def inject(self, span_context, carrier): if not isinstance(carrier, dict): raise InvalidCarrierException('carrier not a collection') # Note: we do not url-encode the trace ID because the ':' separator # is not a problem for HTTP header values carrier[self.trace_id_header] = span_context_to_string( trace_id=span_context.trace_id, span_id=span_context.span_id, parent_id=span_context.parent_id, flags=span_context.flags) baggage = span_context.baggage if baggage: for key, value in six.iteritems(baggage): if self.url_encoding: encoded_value = urllib.parse.quote(value) else: encoded_value = value carrier['%s%s' % (self.baggage_prefix, key)] = encoded_value
def inject(self, span_context, carrier): if type(carrier) is not bytearray: raise InvalidCarrierException() state = BinaryCarrier() basic_ctx = state.basic_ctx basic_ctx.trace_id = span_context.trace_id basic_ctx.span_id = span_context.span_id basic_ctx.sampled = span_context.sampled if span_context.baggage is not None: for key in span_context.baggage: basic_ctx.baggage_items[key] = span_context.baggage[key] serializedProto = state.SerializeToString() encoded = standard_b64encode(serializedProto) carrier.extend(encoded)
def join(self, operation_name, carrier): if type(carrier) is not bytearray: raise InvalidCarrierException() state = TracerState() state.ParseFromString(str(carrier[_proto_size_bytes:])) baggage = {} for k in state.baggage_items: baggage[k] = state.baggage_items[k] raw = RawSpan(operation_name=operation_name, baggage=baggage, start_time=time.time(), context=Context(span_id=generate_id(), parent_id=state.span_id, trace_id=state.trace_id, sampled=state.sampled)) return BasicSpan(self.tracer, raw)
def inject(self, span_context, carrier): if not isinstance(carrier, bytearray): raise InvalidCarrierException('carrier not a bytearray') # check if we have 128 bit trace_id, break it into two 64 units max_int64 = 0xFFFFFFFFFFFFFFFF if span_context.trace_id > max_int64: high = (span_context.trace_id >> 64) & max_int64 low = span_context.trace_id & max_int64 else: high = 0 low = span_context.trace_id carrier += struct.pack('>QQQQBI', high, low, span_context.span_id or 0, span_context.parent_id or 0, span_context.flags, len(span_context.baggage)) for k, v in span_context.baggage.items(): carrier += self._pack_baggage_item(k, v)
def extract(self, carrier): if not isinstance(carrier, dict): raise InvalidCarrierException('carrier not a dictionary') trace_id = header_to_hex(carrier.get(self.trace_header.lower())) span_id = header_to_hex(carrier.get(self.span_header.lower())) parent_id = header_to_hex(carrier.get(self.parent_span_header.lower())) flags = 0x00 sampled = carrier.get(self.sampled_header.lower()) if sampled == '1': flags |= SAMPLED_FLAG debug = carrier.get(self.flags_header.lower()) if debug == '1': flags |= DEBUG_FLAG return SpanContext(trace_id=trace_id, span_id=span_id, parent_id=parent_id, flags=flags, baggage=None)
def extract(self, carrier): if not isinstance(carrier, dict): raise InvalidCarrierException('carrier not a dictionary') lowercase_keys = dict([(k.lower(), k) for k in carrier]) trace_id = header_to_hex(carrier.get(lowercase_keys.get(self._trace_header_lc))) span_id = header_to_hex(carrier.get(lowercase_keys.get(self._span_header_lc))) parent_id = carrier.get(lowercase_keys.get(self._parent_span_header_lc)) if parent_id: parent_id = header_to_hex(parent_id) flags = 0x00 sampled = carrier.get(lowercase_keys.get(self._sampled_header_lc)) if sampled == '1': flags |= SAMPLED_FLAG debug = carrier.get(lowercase_keys.get(self._flags_header_lc)) if debug == '1': flags |= DEBUG_FLAG return SpanContext(trace_id=trace_id, span_id=span_id, parent_id=parent_id, flags=flags, baggage=None)
def extract(self, carrier): if type(carrier) is not bytearray: raise InvalidCarrierException() m = memoryview(carrier) m, trace_id = _rstr(m) m, span_id = _rstr(m) sampled = struct.unpack('?', m[:1])[0] m = m[1:] bl = struct.unpack('>I', m[:4])[0] m = m[4:] baggage = {} for _ in range(bl): m, k = _rstr(m) m, v = _rstr(m) baggage[k] = v return SpanContext(span_id=span_id, trace_id=trace_id, baggage=baggage, sampled=sampled)
def inject(self, span_context, carrier): if not isinstance(carrier, dict): raise InvalidCarrierException('carrier not a collection') carrier[self.trace_id_header] = span_context_to_string( trace_id=span_context.trace_id, span_id=span_context.span_id, parent_id=span_context.parent_id, flags=span_context.flags) baggage = span_context.baggage if baggage: for key, value in six.iteritems(baggage): encoded_key = key if self.url_encoding: encoded_value = urllib.parse.quote(value) if six.PY2 and isinstance(key, six.text_type): encoded_key = key.encode('utf-8') else: encoded_value = value header_key = '%s%s' % (self.baggage_prefix, encoded_key) carrier[header_key] = encoded_value
def inject(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") DDHTTPPropagator.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]