Esempio n. 1
0
    def extract(
        self,
        getter: textmap.Getter[textmap.TextMapPropagatorT],
        carrier: textmap.TextMapPropagatorT,
        context: typing.Optional[Context] = None,
    ) -> Context:
        header = self._get_header_value(getter, carrier)

        if not header:
            return trace.set_span_in_context(trace.INVALID_SPAN, context)

        match = re.fullmatch(_TRACE_CONTEXT_HEADER_RE, header)
        if match is None:
            return trace.set_span_in_context(trace.INVALID_SPAN, context)

        trace_id = match.group("trace_id")
        span_id = match.group("span_id")
        trace_options = match.group("trace_flags")

        if trace_id == "0" * 32 or int(span_id) == 0:
            return trace.set_span_in_context(trace.INVALID_SPAN, context)

        span_context = SpanContext(
            trace_id=int(trace_id, 16),
            span_id=int(span_id),
            is_remote=True,
            trace_flags=TraceFlags(trace_options),
        )
        return trace.set_span_in_context(
            trace.DefaultSpan(span_context), context
        )
    def extract(
        self,
        get_from_carrier: httptextformat.Getter[
            httptextformat.HTTPTextFormatT],
        carrier: httptextformat.HTTPTextFormatT,
        context: typing.Optional[Context] = None,
    ) -> Context:
        header = get_from_carrier(carrier, _TRACE_CONTEXT_HEADER_NAME)

        if not header:
            return trace.set_span_in_context(trace.INVALID_SPAN, context)

        match = re.fullmatch(_TRACE_CONTEXT_HEADER_RE, header[0])
        if match is None:
            return trace.set_span_in_context(trace.INVALID_SPAN, context)

        trace_id = match.group("trace_id")
        span_id = match.group("span_id")
        trace_options = match.group("trace_flags")

        if trace_id == "0" * 32 or int(span_id) == 0:
            return trace.set_span_in_context(trace.INVALID_SPAN, context)

        span_context = SpanContext(
            trace_id=int(trace_id, 16),
            span_id=int(span_id),
            is_remote=True,
            trace_flags=TraceFlags(trace_options),
        )
        return trace.set_span_in_context(trace.DefaultSpan(span_context),
                                         context)
Esempio n. 3
0
    def extract(
        self,
        getter: Getter[TextMapPropagatorT],
        carrier: TextMapPropagatorT,
        context: typing.Optional[Context] = None,
    ) -> 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.DefaultSpan(
            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)
Esempio n. 4
0
    def extract(
        self,
        get_from_carrier: Getter[HTTPTextFormatT],
        carrier: HTTPTextFormatT,
        context: typing.Optional[Context] = None,
    ) -> Context:
        trace_id = format_trace_id(trace.INVALID_TRACE_ID)
        span_id = format_span_id(trace.INVALID_SPAN_ID)
        sampled = "0"
        flags = None

        single_header = _extract_first_element(
            get_from_carrier(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:
                return trace.set_span_in_context(trace.INVALID_SPAN)
        else:
            trace_id = (_extract_first_element(
                get_from_carrier(carrier, self.TRACE_ID_KEY)) or trace_id)
            span_id = (_extract_first_element(
                get_from_carrier(carrier, self.SPAN_ID_KEY)) or span_id)
            sampled = (_extract_first_element(
                get_from_carrier(carrier, self.SAMPLED_KEY)) or sampled)
            flags = (_extract_first_element(
                get_from_carrier(carrier, self.FLAGS_KEY)) or flags)

        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.DefaultSpan(
                trace.SpanContext(
                    # trace an span ids are encoded in hex, so must be converted
                    trace_id=int(trace_id, 16),
                    span_id=int(span_id, 16),
                    is_remote=True,
                    trace_flags=trace.TraceFlags(options),
                    trace_state=trace.TraceState(),
                )))
    def extract(
        self,
        getter: Getter[TextMapPropagatorT],
        carrier: TextMapPropagatorT,
        context: typing.Optional[Context] = None,
    ) -> Context:
        trace_header_list = getter.get(carrier, TRACE_HEADER_KEY)

        if not trace_header_list or len(trace_header_list) != 1:
            return trace.set_span_in_context(
                trace.INVALID_SPAN, context=context
            )

        trace_header = trace_header_list[0]

        if not trace_header:
            return trace.set_span_in_context(
                trace.INVALID_SPAN, context=context
            )

        try:
            (
                trace_id,
                span_id,
                sampled,
            ) = AwsXRayFormat._extract_span_properties(trace_header)
        except AwsParseTraceHeaderError as err:
            _logger.debug(err.message)
            return trace.set_span_in_context(
                trace.INVALID_SPAN, context=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. Insertting INVALID span into provided context."
            )
            return trace.set_span_in_context(
                trace.INVALID_SPAN, context=context
            )

        return trace.set_span_in_context(
            trace.DefaultSpan(span_context), context=context
        )
Esempio n. 6
0
def get_context_new_carrier(old_carrier, carrier_baggage=None):

    ctx = FORMAT.extract(carrier_getter, old_carrier)
    if carrier_baggage:
        for key, value in carrier_baggage.items():
            ctx = baggage.set_baggage(key, value, ctx)
    parent_span_context = trace_api.get_current_span(ctx).get_span_context()

    parent = trace._Span("parent", parent_span_context)
    child = trace._Span(
        "child",
        trace_api.SpanContext(
            parent_span_context.trace_id,
            id_generator.RandomIdGenerator().generate_span_id(),
            is_remote=False,
            trace_flags=parent_span_context.trace_flags,
            trace_state=parent_span_context.trace_state,
        ),
        parent=parent.get_span_context(),
    )

    new_carrier = {}
    ctx = trace_api.set_span_in_context(child, ctx)

    FORMAT.inject(dict.__setitem__, new_carrier, context=ctx)

    return ctx, new_carrier
Esempio n. 7
0
    def test_inject_invalid_baggage_values(self):
        """Test that invalid baggage values are not set"""

        carrier = {}

        self.ot_trace_propagator.inject(
            carrier,
            set_baggage(
                "key",
                "α",
                context=set_span_in_context(
                    _Span(
                        "child",
                        SpanContext(
                            trace_id=int("80f198ee56343ba864fe8b2a57d3eff7",
                                         16),
                            span_id=int("e457b5a2e4d86bd1", 16),
                            is_remote=True,
                            trace_flags=TraceFlags.SAMPLED,
                        ),
                    )),
            ),
        )

        self.assertNotIn("".join([OT_BAGGAGE_PREFIX, "key"]), carrier.keys())
Esempio n. 8
0
    def test_inject_set_baggage(self):
        """Test that baggage is set"""

        carrier = {}

        self.ot_trace_propagator.inject(
            carrier,
            set_baggage(
                "key",
                "value",
                context=set_span_in_context(
                    _Span(
                        "child",
                        SpanContext(
                            trace_id=int("80f198ee56343ba864fe8b2a57d3eff7",
                                         16),
                            span_id=int("e457b5a2e4d86bd1", 16),
                            is_remote=True,
                            trace_flags=TraceFlags.SAMPLED,
                        ),
                    )),
            ),
        )

        self.assertEqual(carrier["".join([OT_BAGGAGE_PREFIX, "key"])], "value")
Esempio n. 9
0
 def on_validation_start(self):
     ctx = trace.set_span_in_context(
         self._span_holder[RequestStage.REQUEST])
     self._span_holder[RequestStage.VALIDATION] = self._tracer.start_span(
         "GraphQL Validation",
         context=ctx,
     )
Esempio n. 10
0
    async def on_request_start(
        unused_session: aiohttp.ClientSession,
        trace_config_ctx: types.SimpleNamespace,
        params: aiohttp.TraceRequestStartParams,
    ):
        http_method = params.method.upper()
        if trace_config_ctx.span_name is None:
            request_span_name = "HTTP {}".format(http_method)
        elif callable(trace_config_ctx.span_name):
            request_span_name = str(trace_config_ctx.span_name(params))
        else:
            request_span_name = str(trace_config_ctx.span_name)

        trace_config_ctx.span = trace_config_ctx.tracer.start_span(
            request_span_name,
            kind=SpanKind.CLIENT,
        )

        if trace_config_ctx.span.is_recording():
            attributes = {
                "component":
                "http",
                "http.method":
                http_method,
                "http.url":
                trace_config_ctx.url_filter(params.url)
                if callable(trace_config_ctx.url_filter) else str(params.url),
            }
            for key, value in attributes.items():
                trace_config_ctx.span.set_attribute(key, value)

        trace_config_ctx.token = context_api.attach(
            trace.set_span_in_context(trace_config_ctx.span))

        propagators.inject(type(params.headers).__setitem__, params.headers)
    def extract(
        self,
        carrier: textmap.CarrierT,
        context: typing.Optional[Context] = None,
        getter: textmap.Getter = textmap.default_getter,
    ) -> Context:
        if context is None:
            context = Context()

        header = self._get_header_value(getter, carrier)

        if not header:
            return context

        match = re.fullmatch(_TRACE_CONTEXT_HEADER_RE, header)
        if match is None:
            return context

        trace_id = match.group("trace_id")
        span_id = match.group("span_id")
        trace_options = match.group("trace_flags")

        if trace_id == "0" * 32 or int(span_id) == 0:
            return context

        span_context = SpanContext(
            trace_id=int(trace_id, 16),
            span_id=int(span_id),
            is_remote=True,
            trace_flags=TraceFlags(trace_options),
        )
        return trace.set_span_in_context(trace.NonRecordingSpan(span_context),
                                         context)
Esempio n. 12
0
    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)
Esempio n. 13
0
    def test_propagation(self):
        traceparent_value = "00-{trace_id}-{span_id}-00".format(
            trace_id=format(self.TRACE_ID, "032x"),
            span_id=format(self.SPAN_ID, "016x"),
        )
        tracestate_value = "foo=1,bar=2,baz=3"
        headers = {
            "otcorrelationcontext": ["key1=val1,key2=val2"],
            "traceparent": [traceparent_value],
            "tracestate": [tracestate_value],
        }
        ctx = extract(get_as_list, headers)
        correlations = correlationcontext.get_correlations(context=ctx)
        expected = {"key1": "val1", "key2": "val2"}
        self.assertEqual(correlations, expected)
        span_context = get_current_span(context=ctx).get_context()

        self.assertEqual(span_context.trace_id, self.TRACE_ID)
        self.assertEqual(span_context.span_id, self.SPAN_ID)

        span = trace.DefaultSpan(span_context)
        ctx = correlationcontext.set_correlation("key3", "val3")
        ctx = correlationcontext.set_correlation("key4", "val4", context=ctx)
        ctx = set_span_in_context(span, context=ctx)
        output = {}
        inject(dict.__setitem__, output, context=ctx)
        self.assertEqual(traceparent_value, output["traceparent"])
        self.assertIn("key3=val3", output["otcorrelationcontext"])
        self.assertIn("key4=val4", output["otcorrelationcontext"])
        self.assertIn("foo=1", output["tracestate"])
        self.assertIn("bar=2", output["tracestate"])
        self.assertIn("baz=3", output["tracestate"])
        async def otel_send(message):
            with self.tracer.start_as_current_span(" ".join(
                (server_span_name, scope["type"], "send"))) as send_span:
                if callable(self.client_response_hook):
                    self.client_response_hook(send_span, message)
                if send_span.is_recording():
                    if message["type"] == "http.response.start":
                        status_code = message["status"]
                        set_status_code(server_span, status_code)
                        set_status_code(send_span, status_code)
                    elif message["type"] == "websocket.send":
                        set_status_code(server_span, 200)
                        set_status_code(send_span, 200)
                    send_span.set_attribute("type", message["type"])

                propagator = get_global_response_propagator()
                if propagator:
                    propagator.inject(
                        message,
                        context=set_span_in_context(
                            server_span, trace.context_api.Context()),
                        setter=asgi_setter,
                    )

                await send(message)
    async def on_request_start(
        unused_session: aiohttp.ClientSession,
        trace_config_ctx: types.SimpleNamespace,
        params: aiohttp.TraceRequestStartParams,
    ):
        if context_api.get_value(_SUPPRESS_INSTRUMENTATION_KEY):
            trace_config_ctx.span = None
            return

        http_method = params.method.upper()
        request_span_name = f"HTTP {http_method}"
        request_url = (remove_url_credentials(
            trace_config_ctx.url_filter(params.url)) if callable(
                trace_config_ctx.url_filter) else remove_url_credentials(
                    str(params.url)))

        span_attributes = {
            SpanAttributes.HTTP_METHOD: http_method,
            SpanAttributes.HTTP_URL: request_url,
        }

        trace_config_ctx.span = trace_config_ctx.tracer.start_span(
            request_span_name,
            kind=SpanKind.CLIENT,
            attributes=span_attributes)

        if callable(request_hook):
            request_hook(trace_config_ctx.span, params)

        trace_config_ctx.token = context_api.attach(
            trace.set_span_in_context(trace_config_ctx.span))

        inject(params.headers)
Esempio n. 16
0
    def inject(self, span_context, format: object, carrier: object):
        """Injects ``span_context`` into ``carrier``.

        See base class for more details.

        Args:
            span_context: The ``opentracing.SpanContext`` to inject.
            format: a Python object instance that represents a given
                carrier format. `format` may be of any type, and `format`
                equality is defined by Python ``==`` operator.
            carrier: the format-specific carrier object to inject into
        """

        # pylint: disable=redefined-builtin
        # This implementation does not perform the injecting by itself but
        # uses the configured propagators in opentelemetry.propagators.
        # TODO: Support Format.BINARY once it is supported in
        # opentelemetry-python.

        if format not in self._supported_formats:
            raise UnsupportedFormatException

        propagator = propagators.get_global_textmap()

        ctx = set_span_in_context(DefaultSpan(span_context.unwrap()))
        propagator.inject(type(carrier).__setitem__, carrier, context=ctx)
    def test_sampling_priority_auto_reject(self):
        """Test sampling priority rejected."""
        parent_span_context = get_current_span(
            FORMAT.extract(
                {
                    FORMAT.TRACE_ID_KEY: self.serialized_trace_id,
                    FORMAT.PARENT_ID_KEY: self.serialized_parent_id,
                    FORMAT.SAMPLING_PRIORITY_KEY: str(constants.AUTO_REJECT),
                }, )).get_span_context()

        self.assertEqual(parent_span_context.trace_flags,
                         constants.AUTO_REJECT)

        child = trace._Span(
            "child",
            trace_api.SpanContext(
                parent_span_context.trace_id,
                RandomIdGenerator().generate_span_id(),
                is_remote=False,
                trace_flags=parent_span_context.trace_flags,
                trace_state=parent_span_context.trace_state,
            ),
            parent=parent_span_context,
        )

        child_carrier = {}
        child_context = set_span_in_context(child)
        FORMAT.inject(child_carrier, context=child_context)

        self.assertEqual(
            child_carrier[FORMAT.SAMPLING_PRIORITY_KEY],
            str(constants.AUTO_REJECT),
        )
Esempio n. 18
0
    def test_headers_with_tracestate(self):
        """When there is a traceparent and tracestate header, data from
        both should be addded to the SpanContext.
        """
        traceparent_value = "00-{trace_id}-{span_id}-00".format(
            trace_id=format(self.TRACE_ID, "032x"),
            span_id=format(self.SPAN_ID, "016x"),
        )
        tracestate_value = "foo=1,bar=2,baz=3"
        span_context = trace.get_current_span(
            FORMAT.extract(
                {
                    "traceparent": [traceparent_value],
                    "tracestate": [tracestate_value],
                },
            )
        ).get_span_context()
        self.assertEqual(span_context.trace_id, self.TRACE_ID)
        self.assertEqual(span_context.span_id, self.SPAN_ID)
        self.assertEqual(
            span_context.trace_state, {"foo": "1", "bar": "2", "baz": "3"}
        )
        self.assertTrue(span_context.is_remote)
        output = {}  # type:typing.Dict[str, str]
        span = trace.NonRecordingSpan(span_context)

        ctx = trace.set_span_in_context(span)
        FORMAT.inject(output, context=ctx)
        self.assertEqual(output["traceparent"], traceparent_value)
        for pair in ["foo=1", "bar=2", "baz=3"]:
            self.assertIn(pair, output["tracestate"])
        self.assertEqual(output["tracestate"].count(","), 2)
    def test_start_span_explicit(self):
        tracer = new_tracer()

        other_parent = trace._Span(
            "name",
            trace_api.SpanContext(
                trace_id=0x000000000000000000000000DEADBEEF,
                span_id=0x00000000DEADBEF0,
                is_remote=False,
                trace_flags=trace_api.TraceFlags(trace_api.TraceFlags.SAMPLED),
            ),
        )

        other_parent_context = trace_api.set_span_in_context(other_parent)

        self.assertEqual(trace_api.get_current_span(), trace_api.INVALID_SPAN)

        root = tracer.start_span("root")
        self.assertIsNotNone(root.start_time)
        self.assertIsNone(root.end_time)

        # Test with the implicit root span
        with tracer.use_span(root, True):
            self.assertIs(trace_api.get_current_span(), root)

            with tracer.start_span("stepchild", other_parent_context) as child:
                # The child's parent should be the one passed in,
                # not the current span.
                self.assertNotEqual(child.parent, root)
                self.assertIs(child.parent, other_parent.get_span_context())

                self.assertIsNotNone(child.start_time)
                self.assertIsNone(child.end_time)

                # The child should inherit its context from the explicit
                # parent, not the current span.
                child_context = child.get_span_context()
                self.assertEqual(
                    other_parent.get_span_context().trace_id,
                    child_context.trace_id,
                )
                self.assertNotEqual(
                    other_parent.get_span_context().span_id,
                    child_context.span_id,
                )
                self.assertEqual(
                    other_parent.get_span_context().trace_state,
                    child_context.trace_state,
                )
                self.assertEqual(
                    other_parent.get_span_context().trace_flags,
                    child_context.trace_flags,
                )

                # Verify start_span() did not set the current span.
                self.assertIs(trace_api.get_current_span(), root)

            # Verify ending the child did not set the current span.
            self.assertIs(trace_api.get_current_span(), root)
            self.assertIsNotNone(child.end_time)
Esempio n. 20
0
    def test_propagation(self):
        traceparent_value = "00-{trace_id}-{span_id}-00".format(
            trace_id=format(self.TRACE_ID, "032x"),
            span_id=format(self.SPAN_ID, "016x"),
        )
        tracestate_value = "foo=1,bar=2,baz=3"
        headers = {
            "baggage": ["key1=val1,key2=val2"],
            "traceparent": [traceparent_value],
            "tracestate": [tracestate_value],
        }
        ctx = extract(carrier_getter, headers)
        baggage_entries = baggage.get_all(context=ctx)
        expected = {"key1": "val1", "key2": "val2"}
        self.assertEqual(baggage_entries, expected)
        span_context = get_current_span(context=ctx).get_span_context()

        self.assertEqual(span_context.trace_id, self.TRACE_ID)
        self.assertEqual(span_context.span_id, self.SPAN_ID)

        span = trace.NonRecordingSpan(span_context)
        ctx = baggage.set_baggage("key3", "val3")
        ctx = baggage.set_baggage("key4", "val4", context=ctx)
        ctx = set_span_in_context(span, context=ctx)
        output = {}
        inject(dict.__setitem__, output, context=ctx)
        self.assertEqual(traceparent_value, output["traceparent"])
        self.assertIn("key3=val3", output["baggage"])
        self.assertIn("key4=val4", output["baggage"])
        self.assertIn("foo=1", output["tracestate"])
        self.assertIn("bar=2", output["tracestate"])
        self.assertIn("baz=3", output["tracestate"])
Esempio n. 21
0
    def _traced_send(func, instance, args, kwargs):
        headers = KafkaPropertiesExtractor.extract_send_headers(args, kwargs)
        if headers is None:
            headers = []
            kwargs["headers"] = headers

        topic = KafkaPropertiesExtractor.extract_send_topic(args)
        bootstrap_servers = KafkaPropertiesExtractor.extract_bootstrap_servers(
            instance)
        partition = KafkaPropertiesExtractor.extract_send_partition(
            instance, args, kwargs)
        span_name = _get_span_name("send", topic)
        with tracer.start_as_current_span(
                span_name, kind=trace.SpanKind.PRODUCER) as span:
            _enrich_span(span, bootstrap_servers, topic, partition)
            propagate.inject(
                headers,
                context=trace.set_span_in_context(span),
                setter=_kafka_setter,
            )
            try:
                if callable(produce_hook):
                    produce_hook(span, args, kwargs)
            except Exception as hook_exception:  # pylint: disable=W0703
                _LOG.exception(hook_exception)

        return func(*args, **kwargs)
Esempio n. 22
0
    def test_parent_based(self):
        sampler = sampling.ParentBased(sampling.ALWAYS_ON)
        context = trace.set_span_in_context(
            trace.DefaultSpan(
                trace.SpanContext(
                    0xDEADBEF0,
                    0xDEADBEF1,
                    is_remote=False,
                    trace_flags=TO_DEFAULT,
                )))
        # Check that the sampling decision matches the parent context if given
        self.assertFalse(
            sampler.should_sample(
                context,
                0x7FFFFFFFFFFFFFFF,
                0xDEADBEEF,
                "span name",
            ).decision.is_sampled())

        context = trace.set_span_in_context(
            trace.DefaultSpan(
                trace.SpanContext(
                    0xDEADBEF0,
                    0xDEADBEF1,
                    is_remote=False,
                    trace_flags=TO_SAMPLED,
                )))
        sampler2 = sampling.ParentBased(sampling.ALWAYS_OFF)
        self.assertTrue(
            sampler2.should_sample(
                context,
                0x8000000000000000,
                0xDEADBEEF,
                "span name",
            ).decision.is_sampled())

        # root span always sampled for parentbased
        context = trace.set_span_in_context(trace.INVALID_SPAN)
        sampler3 = sampling.ParentBased(sampling.ALWAYS_OFF)
        self.assertTrue(
            sampler3.should_sample(
                context,
                0x8000000000000000,
                0xDEADBEEF,
                "span name",
            ).decision.is_sampled())
 def _inject(self, span=None):
     """Test helper"""
     ctx = get_current()
     if span is not None:
         ctx = trace.set_span_in_context(span, ctx)
     output = {}
     self.propagator.inject(dict.__setitem__, output, context=ctx)
     return output.get(_TRACE_CONTEXT_HEADER_NAME)
 def _create_parent(
     self, trace_flags: trace.TraceFlags, is_remote=False
 ) -> typing.Optional[context_api.Context]:
     if trace_flags is None:
         return None
     return trace.set_span_in_context(
         self._create_parent_span(trace_flags, is_remote)
     )
    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
Esempio n. 26
0
    def test_default_on(self):
        context = trace.set_span_in_context(
            trace.DefaultSpan(
                trace.SpanContext(
                    0xDEADBEEF,
                    0xDEADBEF0,
                    is_remote=False,
                    trace_flags=TO_DEFAULT,
                )))
        no_record_default_on = sampling.DEFAULT_ON.should_sample(
            context,
            0xDEADBEF1,
            0xDEADBEF2,
            "unsampled parent, sampling on",
        )
        self.assertFalse(no_record_default_on.decision.is_sampled())
        self.assertEqual(no_record_default_on.attributes, {})

        context = trace.set_span_in_context(
            trace.DefaultSpan(
                trace.SpanContext(
                    0xDEADBEEF,
                    0xDEADBEF0,
                    is_remote=False,
                    trace_flags=TO_SAMPLED,
                )))
        sampled_default_on = sampling.DEFAULT_ON.should_sample(
            context,
            0xDEADBEF1,
            0xDEADBEF2,
            {"sampled parent": "sampling on"},
        )
        self.assertTrue(sampled_default_on.decision.is_sampled())
        self.assertEqual(sampled_default_on.attributes,
                         {"sampled parent": "sampling on"})

        default_on = sampling.DEFAULT_ON.should_sample(
            None,
            0xDEADBEF1,
            0xDEADBEF2,
            {"sampled parent": "sampling on"},
        )
        self.assertTrue(default_on.decision.is_sampled())
        self.assertEqual(default_on.attributes,
                         {"sampled parent": "sampling on"})
    def test_context_propagation(self):
        """Test the propagation of Datadog headers."""
        parent_span_context = get_current_span(
            FORMAT.extract(
                carrier_getter,
                {
                    FORMAT.TRACE_ID_KEY: self.serialized_trace_id,
                    FORMAT.PARENT_ID_KEY: self.serialized_parent_id,
                    FORMAT.SAMPLING_PRIORITY_KEY: str(constants.AUTO_KEEP),
                    FORMAT.ORIGIN_KEY: self.serialized_origin,
                },
            )
        ).get_span_context()

        self.assertEqual(
            parent_span_context.trace_id, int(self.serialized_trace_id)
        )
        self.assertEqual(
            parent_span_context.span_id, int(self.serialized_parent_id)
        )
        self.assertEqual(parent_span_context.trace_flags, constants.AUTO_KEEP)
        self.assertEqual(
            parent_span_context.trace_state.get(constants.DD_ORIGIN),
            self.serialized_origin,
        )
        self.assertTrue(parent_span_context.is_remote)

        child = trace._Span(
            "child",
            trace_api.SpanContext(
                parent_span_context.trace_id,
                trace_api.RandomIdsGenerator().generate_span_id(),
                is_remote=False,
                trace_flags=parent_span_context.trace_flags,
                trace_state=parent_span_context.trace_state,
            ),
            parent=parent_span_context,
        )

        child_carrier = {}
        child_context = set_span_in_context(child)
        FORMAT.inject(dict.__setitem__, child_carrier, context=child_context)

        self.assertEqual(
            child_carrier[FORMAT.TRACE_ID_KEY], self.serialized_trace_id
        )
        self.assertEqual(
            child_carrier[FORMAT.PARENT_ID_KEY], str(child.context.span_id)
        )
        self.assertEqual(
            child_carrier[FORMAT.SAMPLING_PRIORITY_KEY],
            str(constants.AUTO_KEEP),
        )
        self.assertEqual(
            child_carrier.get(FORMAT.ORIGIN_KEY), self.serialized_origin
        )
    def extract(
        self,
        get_from_carrier: Getter[HTTPTextFormatT],
        carrier: HTTPTextFormatT,
        context: typing.Optional[Context] = None,
    ) -> Context:
        trace_id_list = get_from_carrier(carrier, self.TRACE_ID_KEY)
        span_id_list = get_from_carrier(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.DefaultSpan(
                trace.SpanContext(
                    trace_id=int(trace_id_list[0]),
                    span_id=int(span_id_list[0]),
                    is_remote=True,
                )))
Esempio n. 29
0
    def extract(
        self,
        getter: Getter[TextMapPropagatorT],
        carrier: TextMapPropagatorT,
        context: typing.Optional[Context] = None,
    ) -> 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 build_test_current_context(
    trace_id=int(TRACE_ID_BASE16, 16),
    span_id=int(SPAN_ID_BASE16, 16),
    is_remote=True,
    trace_flags=DEFAULT_TRACE_OPTIONS,
    trace_state=DEFAULT_TRACE_STATE,
):
    return set_span_in_context(
        trace_api.NonRecordingSpan(
            build_test_span_context(trace_id, span_id, is_remote, trace_flags,
                                    trace_state)))