Esempio n. 1
0
 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)
Esempio n. 2
0
 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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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,
            )
Esempio n. 5
0
    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)
Esempio n. 6
0
 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
Esempio n. 7
0
 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
Esempio n. 8
0
 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)
Esempio n. 9
0
    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)
Esempio n. 10
0
 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
Esempio n. 11
0
    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
Esempio n. 12
0
    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
Esempio n. 13
0
 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
Esempio n. 14
0
 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)
Esempio n. 15
0
 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'
Esempio n. 16
0
 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
Esempio n. 17
0
    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)
Esempio n. 18
0
    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)
Esempio n. 20
0
    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())
Esempio n. 21
0
 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])
Esempio n. 22
0
 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)
Esempio n. 24
0
    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)
Esempio n. 25
0
    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)
Esempio n. 26
0
 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)
Esempio n. 27
0
 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)
Esempio n. 28
0
    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)
Esempio n. 29
0
 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
Esempio n. 30
0
    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]