Esempio n. 1
0
        def gen_wrapper(*args: P.args,
                        **kwargs: P.kwargs) -> T:  # type: ignore[misc]
            LOGGER.debug("Spanned Generator Function")
            span = setup(args, kwargs)

            # CASE 1 ----------------------------------------------------------
            if scond.behavior == SpanBehavior.ONLY_END_ON_EXCEPTION:
                try:
                    with use_span(span, end_on_exit=False):
                        for val in func(
                                *args, **kwargs):  # type: ignore[attr-defined]
                            yield val
                except:  # noqa: E722 # pylint: disable=bare-except
                    span.end()
                    raise
            # CASES 2 & 3 -----------------------------------------------------
            elif scond.behavior in (SpanBehavior.END_ON_EXIT,
                                    SpanBehavior.DONT_END):
                end_on_exit = bool(scond.behavior == SpanBehavior.END_ON_EXIT)
                with use_span(span, end_on_exit=end_on_exit):
                    for val in func(*args,
                                    **kwargs):  # type: ignore[attr-defined]
                        yield val
            # ELSE ------------------------------------------------------------
            else:
                raise InvalidSpanBehavior(scond.behavior)
    def test_use_span_end_on_exit(self):

        test_span = TestSpan(trace.INVALID_SPAN_CONTEXT)

        with trace.use_span(test_span):
            pass
        self.assertFalse(test_span.has_ended)

        with trace.use_span(test_span, end_on_exit=True):
            pass
        self.assertTrue(test_span.has_ended)
    def _trace_before_publish(self, *args, **kwargs):
        task = utils.retrieve_task_from_sender(kwargs)
        task_id = utils.retrieve_task_id_from_message(kwargs)

        if task is None or task_id is None:
            return

        operation_name = f"{_TASK_APPLY_ASYNC}/{task.name}"
        span = self._tracer.start_span(
            operation_name, kind=trace.SpanKind.PRODUCER
        )

        # apply some attributes here because most of the data is not available
        if span.is_recording():
            span.set_attribute(_TASK_TAG_KEY, _TASK_APPLY_ASYNC)
            span.set_attribute(SpanAttributes.MESSAGING_MESSAGE_ID, task_id)
            span.set_attribute(_TASK_NAME_KEY, task.name)
            utils.set_attributes_from_context(span, kwargs)

        activation = trace.use_span(span, end_on_exit=True)
        activation.__enter__()  # pylint: disable=E1101

        utils.attach_span(task, task_id, (span, activation), is_publish=True)

        headers = kwargs.get("headers")
        if headers:
            inject(headers)
Esempio n. 4
0
def fetch_async(tracer, func, _, args, kwargs):
    start_time = _time_ns()

    # Return immediately if no args were provided (error)
    # or original_request is set (meaning we are in a redirect step).
    if len(args) == 0 or hasattr(args[0], "original_request"):
        return func(*args, **kwargs)

    # Force the creation of a HTTPRequest object if needed,
    # so we can inject the context into the headers.
    args, kwargs = _normalize_request(args, kwargs)
    request = args[0]

    span = tracer.start_span(
        request.method,
        kind=trace.SpanKind.CLIENT,
        start_time=start_time,
    )

    if span.is_recording():
        attributes = {
            "http.url": request.url,
            "http.method": request.method,
        }
        for key, value in attributes.items():
            span.set_attribute(key, value)

    with trace.use_span(span):
        inject(request.headers)
        future = func(*args, **kwargs)
        future.add_done_callback(
            functools.partial(_finish_tracing_callback, span=span))
        return future
 def decorated_function(
     exchange: str,
     routing_key: str,
     body: bytes,
     properties: BasicProperties = None,
     mandatory: bool = False,
 ) -> Any:
     if not properties:
         properties = BasicProperties(headers={})
     ctx = context.get_current()
     span = _get_span(
         tracer,
         channel,
         properties,
         span_kind=SpanKind.PRODUCER,
         task_name="(temporary)",
         ctx=ctx,
         operation=None,
     )
     if not span:
         return original_function(
             exchange, routing_key, body, properties, mandatory
         )
     with trace.use_span(span, end_on_exit=True):
         if span.is_recording():
             propagate.inject(properties.headers)
         retval = original_function(
             exchange, routing_key, body, properties, mandatory
         )
     return retval
Esempio n. 6
0
    def before_enqueue(self, _broker, message, delay):
        retry_count = message.options.get("retries", 0)
        operation_name = utils.get_operation_name("before_enqueue",
                                                  retry_count)
        span_attributes = {_REMOULADE_MESSAGE_RETRY_COUNT_KEY: retry_count}

        span = self._tracer.start_span(
            operation_name,
            kind=trace.SpanKind.PRODUCER,
            attributes=span_attributes,
        )

        if span.is_recording():
            span.set_attributes({
                _REMOULADE_MESSAGE_TAG_KEY:
                _REMOULADE_MESSAGE_SEND,
                _REMOULADE_MESSAGE_NAME_KEY:
                message.actor_name,
                SpanAttributes.MESSAGING_MESSAGE_ID:
                message.message_id,
            })

        activation = trace.use_span(span, end_on_exit=True)
        activation.__enter__()  # pylint: disable=E1101

        utils.attach_span(
            self._span_registry,
            message.message_id,
            (span, activation),
            is_publish=True,
        )

        if "trace_ctx" not in message.options:
            message.options["trace_ctx"] = {}
        inject(message.options["trace_ctx"])
 def decorated_callback(
     channel: Channel,
     method: Basic.Deliver,
     properties: BasicProperties,
     body: bytes,
 ) -> Any:
     if not properties:
         properties = BasicProperties(headers={})
     if properties.headers is None:
         properties.headers = {}
     ctx = propagate.extract(properties.headers, getter=_pika_getter)
     if not ctx:
         ctx = context.get_current()
     token = context.attach(ctx)
     span = _get_span(
         tracer,
         channel,
         properties,
         destination=method.exchange
         if method.exchange else method.routing_key,
         span_kind=SpanKind.CONSUMER,
         task_name=task_name,
         operation=MessagingOperationValues.RECEIVE,
     )
     try:
         with trace.use_span(span, end_on_exit=True):
             try:
                 consume_hook(span, body, properties)
             except Exception as hook_exception:  # pylint: disable=W0703
                 _LOG.exception(hook_exception)
             retval = callback(channel, method, properties, body)
     finally:
         context.detach(token)
     return retval
Esempio n. 8
0
def _start_span(tracer, handler, start_time) -> _TraceContext:
    span, token = _start_internal_or_server_span(
        tracer=tracer,
        span_name=_get_operation_name(handler, handler.request),
        start_time=start_time,
        context_carrier=handler.request.headers,
        context_getter=textmap.default_getter,
    )

    if span.is_recording():
        attributes = _get_attributes_from_request(handler.request)
        for key, value in attributes.items():
            span.set_attribute(key, value)
        span.set_attribute("tornado.handler", _get_full_handler_name(handler))
        if span.is_recording() and span.kind == trace.SpanKind.SERVER:
            custom_attributes = _collect_custom_request_headers_attributes(
                handler.request.headers)
            if len(custom_attributes) > 0:
                span.set_attributes(custom_attributes)

    activation = trace.use_span(span, end_on_exit=True)
    activation.__enter__()  # pylint: disable=E1101
    ctx = _TraceContext(activation, span, token)
    setattr(handler, _HANDLER_CONTEXT_KEY, ctx)

    # finish handler is called after the response is sent back to
    # the client so it is too late to inject trace response headers
    # there.
    propagator = get_global_response_propagator()
    if propagator:
        propagator.inject(handler, setter=response_propagation_setter)

    return ctx
 def decorated_function(
     exchange: str,
     routing_key: str,
     body: bytes,
     properties: BasicProperties = None,
     mandatory: bool = False,
 ) -> Any:
     if not properties:
         properties = BasicProperties(headers={})
     if properties.headers is None:
         properties.headers = {}
     span = _get_span(
         tracer,
         channel,
         properties,
         destination=exchange if exchange else routing_key,
         span_kind=SpanKind.PRODUCER,
         task_name="(temporary)",
         operation=None,
     )
     if not span:
         return original_function(exchange, routing_key, body, properties,
                                  mandatory)
     with trace.use_span(span, end_on_exit=True):
         if span.is_recording():
             propagate.inject(properties.headers)
             try:
                 publish_hook(span, body, properties)
             except Exception as hook_exception:  # pylint: disable=W0703
                 _LOG.exception(hook_exception)
         retval = original_function(exchange, routing_key, body, properties,
                                    mandatory)
     return retval
Esempio n. 10
0
 def start_as_current_span(
     self,
     name: str,
     context: Optional[context_api.Context] = None,
     kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL,
     attributes: types.Attributes = None,
     links: Sequence[trace_api.Link] = (),
     start_time: Optional[int] = None,
     record_exception: bool = True,
     set_status_on_exception: bool = True,
     end_on_exit: bool = True,
 ) -> Iterator[trace_api.Span]:
     span = self.start_span(
         name=name,
         context=context,
         kind=kind,
         attributes=attributes,
         links=links,
         start_time=start_time,
         record_exception=record_exception,
         set_status_on_exception=set_status_on_exception,
     )
     with trace_api.use_span(
         span,
         end_on_exit=end_on_exit,
         record_exception=record_exception,
         set_status_on_exception=set_status_on_exception,
     ) as span_context:
         yield span_context
Esempio n. 11
0
    def __call__(self, environ, start_response):
        """The WSGI application

        Args:
            environ: A WSGI environment.
            start_response: The WSGI start_response callable.
        """

        token = context.attach(extract(environ, getter=wsgi_getter))
        span_name = self.name_callback(environ)

        span = self.tracer.start_span(
            span_name,
            kind=trace.SpanKind.SERVER,
            attributes=collect_request_attributes(environ),
        )

        try:
            with trace.use_span(span):
                start_response = self._create_start_response(
                    span, start_response)
                iterable = self.wsgi(environ, start_response)
                return _end_span_after_iterating(iterable, span, self.tracer,
                                                 token)
        except Exception as ex:
            if span.is_recording():
                span.set_status(Status(StatusCode.ERROR, str(ex)))
            span.end()
            context.detach(token)
            raise
    def _create_processing_span(
        self,
        queue_name: str,
        queue_url: str,
        receipt_handle: str,
        message: Dict[str, Any],
    ) -> None:
        message_attributes = message.get("MessageAttributes", {})
        links = []
        ctx = propagate.extract(message_attributes, getter=boto3sqs_getter)
        parent_span_ctx = trace.get_current_span(ctx).get_span_context()
        if parent_span_ctx.is_valid:
            links.append(Link(context=parent_span_ctx))

        span = self._tracer.start_span(name=f"{queue_name} process",
                                       links=links,
                                       kind=SpanKind.CONSUMER)
        with trace.use_span(span):
            message_id = message.get("MessageId")
            Boto3SQSInstrumentor.received_messages_spans[receipt_handle] = span
            Boto3SQSInstrumentor._enrich_span(
                span,
                queue_name,
                queue_url,
                message_id=message_id,
                operation=MessagingOperationValues.PROCESS,
            )
Esempio n. 13
0
    def _before_request():
        if _excluded_urls.url_disabled(flask.request.url):
            return

        flask_request_environ = flask.request.environ
        span_name = name_callback()
        token = context.attach(
            extract(flask_request_environ, getter=otel_wsgi.wsgi_getter))

        tracer = trace.get_tracer(__name__, __version__)

        span = tracer.start_span(
            span_name,
            kind=trace.SpanKind.SERVER,
            start_time=flask_request_environ.get(_ENVIRON_STARTTIME_KEY),
        )
        if span.is_recording():
            attributes = otel_wsgi.collect_request_attributes(
                flask_request_environ)
            if flask.request.url_rule:
                # For 404 that result from no route found, etc, we
                # don't have a url_rule.
                attributes["http.route"] = flask.request.url_rule.rule
            for key, value in attributes.items():
                span.set_attribute(key, value)

        activation = trace.use_span(span, end_on_exit=True)
        activation.__enter__()  # pylint: disable=E1101
        flask_request_environ[_ENVIRON_ACTIVATION_KEY] = activation
        flask_request_environ[_ENVIRON_SPAN_KEY] = span
        flask_request_environ[_ENVIRON_TOKEN] = token
    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 trace_api.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. 15
0
def _start_span(tracer, handler, start_time) -> _TraceContext:
    token = context.attach(extract(handler.request.headers))

    span = tracer.start_span(
        _get_operation_name(handler, handler.request),
        kind=trace.SpanKind.SERVER,
        start_time=start_time,
    )
    if span.is_recording():
        attributes = _get_attributes_from_request(handler.request)
        for key, value in attributes.items():
            span.set_attribute(key, value)

    activation = trace.use_span(span, end_on_exit=True)
    activation.__enter__()  # pylint: disable=E1101
    ctx = _TraceContext(activation, span, token)
    setattr(handler, _HANDLER_CONTEXT_KEY, ctx)

    # finish handler is called after the response is sent back to
    # the client so it is too late to inject trace response headers
    # there.
    propagator = get_global_response_propagator()
    if propagator:
        propagator.inject(handler, setter=response_propagation_setter)

    return ctx
Esempio n. 16
0
        async def async_wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
            LOGGER.debug("Spanned Async Function")
            span = setup(args, kwargs)
            is_iterator_class_anext_method = span.name.endswith(
                ".__anext__")  # type: ignore[attr-defined]
            reraise_stopasynciteration_outside_contextmanager = False

            # CASE 1 ----------------------------------------------------------
            if scond.behavior == SpanBehavior.ONLY_END_ON_EXCEPTION:
                try:
                    with use_span(span, end_on_exit=False):
                        try:
                            return await func(
                                *args,
                                **kwargs)  # type: ignore[misc, no-any-return]
                        except StopAsyncIteration:
                            # intercept and temporarily suppress StopAsyncIteration
                            if not is_iterator_class_anext_method:
                                raise
                            reraise_stopasynciteration_outside_contextmanager = True
                except:  # noqa: E722 # pylint: disable=bare-except
                    span.end()
                    raise
                if reraise_stopasynciteration_outside_contextmanager:
                    raise StopAsyncIteration
                raise RuntimeError("Malformed SpanBehavior Handling")
            # CASES 2 & 3 -----------------------------------------------------
            elif scond.behavior in (SpanBehavior.END_ON_EXIT,
                                    SpanBehavior.DONT_END):
                end_on_exit = bool(scond.behavior == SpanBehavior.END_ON_EXIT)
                with use_span(span, end_on_exit=end_on_exit):
                    try:
                        return await func(
                            *args,
                            **kwargs)  # type: ignore[misc, no-any-return]
                    except StopAsyncIteration:
                        # intercept and temporarily suppress StopAsyncIteration
                        if not is_iterator_class_anext_method:
                            raise
                        reraise_stopasynciteration_outside_contextmanager = True
                if reraise_stopasynciteration_outside_contextmanager:
                    raise StopAsyncIteration
                raise RuntimeError("Malformed SpanBehavior Handling")
            # ELSE ------------------------------------------------------------
            else:
                raise InvalidSpanBehavior(scond.behavior)
Esempio n. 17
0
 def test_with_only_nonrecording_span(self):
     with trace.use_span(INVALID_SPAN), set_ip_on_next_http_connection(
         INVALID_SPAN
     ):
         resp, body = self.perform_request()
     assert resp.status == 200
     assert body == b"Hello!"
     self.assert_span(num_spans=0)
Esempio n. 18
0
 def callback(response_future):
     with trace.use_span(span, end_on_exit=True):
         code = response_future.code()
         if code != grpc.StatusCode.OK:
             rpc_info.error = code
             return
         response = response_future.result()
         rpc_info.response = response
def _end_span_after_iterating(iterable, span, tracer, token):
    try:
        with trace.use_span(span):
            yield from iterable
    finally:
        close = getattr(iterable, "close", None)
        if close:
            close()
        span.end()
        context.detach(token)
Esempio n. 20
0
 async def decorated_publish(
         message: AbstractMessage, routing_key: str,
         **kwargs) -> Optional[aiormq.abc.ConfirmationFrameType]:
     span = self._get_publish_span(message, routing_key)
     if not span:
         return await publish(message, routing_key, **kwargs)
     with trace.use_span(span, end_on_exit=True):
         if span.is_recording():
             propagate.inject(message.properties.headers)
         return_value = await publish(message, routing_key, **kwargs)
     return return_value
Esempio n. 21
0
    def test_use_span_exception(self):
        class TestUseSpanException(Exception):
            pass

        test_span = TestSpan(trace.INVALID_SPAN_CONTEXT)
        exception = TestUseSpanException("test exception")
        with self.assertRaises(TestUseSpanException):
            with trace.use_span(test_span):
                raise exception

        self.assertEqual(test_span.recorded_exception, exception)
def _before_traversal(event):
    request = event.request
    request_environ = request.environ
    span_name = otel_wsgi.get_default_span_name(request_environ)

    enabled = request_environ.get(_ENVIRON_ENABLED_KEY)
    if enabled is None:
        _logger.warning(
            "Opentelemetry pyramid tween 'opentelemetry.instrumentation.pyramid.trace_tween_factory'"
            "was not called. Make sure that the tween is included in 'pyramid.tweens' if"
            "the tween list was created manually")
        return

    if not enabled:
        # Tracing not enabled, return
        return

    start_time = request_environ.get(_ENVIRON_STARTTIME_KEY)
    tracer = trace.get_tracer(__name__, __version__)

    if request.matched_route:
        span_name = request.matched_route.pattern
    else:
        span_name = otel_wsgi.get_default_span_name(request_environ)

    span, token = _start_internal_or_server_span(
        tracer=tracer,
        span_name=span_name,
        start_time=start_time,
        context_carrier=request_environ,
        context_getter=otel_wsgi.wsgi_getter,
    )

    if span.is_recording():
        attributes = otel_wsgi.collect_request_attributes(request_environ)
        if request.matched_route:
            attributes[
                SpanAttributes.HTTP_ROUTE] = request.matched_route.pattern
        for key, value in attributes.items():
            span.set_attribute(key, value)
        if span.kind == trace.SpanKind.SERVER:
            custom_attributes = (
                otel_wsgi.collect_custom_request_headers_attributes(
                    request_environ))
            if len(custom_attributes) > 0:
                span.set_attributes(custom_attributes)

    activation = trace.use_span(span, end_on_exit=True)
    activation.__enter__()  # pylint: disable=E1101
    request_environ[_ENVIRON_ACTIVATION_KEY] = activation
    request_environ[_ENVIRON_SPAN_KEY] = span
    if token:
        request_environ[_ENVIRON_TOKEN] = token
    def __call__(self, environ, start_response):
        """The WSGI application

        Args:
            environ: A WSGI environment.
            start_response: The WSGI start_response callable.
        """
        req_attrs = collect_request_attributes(environ)
        active_requests_count_attrs = _parse_active_request_count_attrs(
            req_attrs)
        duration_attrs = _parse_duration_attrs(req_attrs)

        span, token = _start_internal_or_server_span(
            tracer=self.tracer,
            span_name=get_default_span_name(environ),
            start_time=None,
            context_carrier=environ,
            context_getter=wsgi_getter,
            attributes=req_attrs,
        )
        if span.is_recording() and span.kind == trace.SpanKind.SERVER:
            custom_attributes = collect_custom_request_headers_attributes(
                environ)
            if len(custom_attributes) > 0:
                span.set_attributes(custom_attributes)

        if self.request_hook:
            self.request_hook(span, environ)

        response_hook = self.response_hook
        if response_hook:
            response_hook = functools.partial(response_hook, span, environ)

        start = default_timer()
        self.active_requests_counter.add(1, active_requests_count_attrs)
        try:
            with trace.use_span(span):
                start_response = self._create_start_response(
                    span, start_response, response_hook, duration_attrs)
                iterable = self.wsgi(environ, start_response)
                return _end_span_after_iterating(iterable, span, token)
        except Exception as ex:
            if span.is_recording():
                span.set_status(Status(StatusCode.ERROR, str(ex)))
            span.end()
            if token is not None:
                context.detach(token)
            raise
        finally:
            duration = max(round((default_timer() - start) * 1000), 0)
            self.duration_histogram.record(duration, duration_attrs)
            self.active_requests_counter.add(-1, active_requests_count_attrs)
Esempio n. 24
0
 def test_with_nested_nonrecording_span(self):
     tracer = trace.get_tracer(__name__)
     with tracer.start_as_current_span(
         "requests HTTP GET"
     ) as span, set_ip_on_next_http_connection(span):
         with trace.use_span(INVALID_SPAN), set_ip_on_next_http_connection(
             INVALID_SPAN
         ):
             resp, body = self.perform_request()
     assert resp.status == 200
     assert body == b"Hello!"
     span = self.assert_span(num_spans=1)
     self.assertEqual(span.attributes, {"net.peer.ip": "127.0.0.1"})
Esempio n. 25
0
    def __call__(self, env, start_response):
        # pylint: disable=E1101
        if self._otel_excluded_urls.url_disabled(env.get("PATH_INFO", "/")):
            return super().__call__(env, start_response)

        start_time = _time_ns()

        span, token = _start_internal_or_server_span(
            tracer=self._otel_tracer,
            span_name=otel_wsgi.get_default_span_name(env),
            start_time=start_time,
            context_carrier=env,
            context_getter=otel_wsgi.wsgi_getter,
        )

        if span.is_recording():
            attributes = otel_wsgi.collect_request_attributes(env)
            for key, value in attributes.items():
                span.set_attribute(key, value)
            if span.is_recording() and span.kind == trace.SpanKind.SERVER:
                custom_attributes = (
                    otel_wsgi.collect_custom_request_headers_attributes(env)
                )
                if len(custom_attributes) > 0:
                    span.set_attributes(custom_attributes)

        activation = trace.use_span(span, end_on_exit=True)
        activation.__enter__()
        env[_ENVIRON_SPAN_KEY] = span
        env[_ENVIRON_ACTIVATION_KEY] = activation

        def _start_response(status, response_headers, *args, **kwargs):
            response = start_response(
                status, response_headers, *args, **kwargs
            )
            activation.__exit__(None, None, None)
            if token is not None:
                context.detach(token)
            return response

        try:
            return super().__call__(env, _start_response)
        except Exception as exc:
            activation.__exit__(
                type(exc),
                exc,
                getattr(exc, "__traceback__", None),
            )
            if token is not None:
                context.detach(token)
            raise
Esempio n. 26
0
 async def decorated(message: AbstractIncomingMessage):
     if not is_instrumentation_enabled():
         return await callback(message)
     headers = message.headers or {}
     ctx = propagate.extract(headers)
     token = context.attach(ctx)
     span = self._get_span(message)
     if not span:
         return await callback(message)
     try:
         with trace.use_span(span, end_on_exit=True):
             return_value = await callback(message)
     finally:
         context.detach(token)
     return return_value
Esempio n. 27
0
    def test_use_span_set_status(self):
        class TestUseSpanException(Exception):
            pass

        test_span = TestSpan(trace.INVALID_SPAN_CONTEXT)
        with self.assertRaises(TestUseSpanException):
            with trace.use_span(test_span):
                raise TestUseSpanException("test error")

        self.assertEqual(test_span.recorded_status.status_code,
                         StatusCode.ERROR)
        self.assertEqual(
            test_span.recorded_status.description,
            "TestUseSpanException: test error",
        )
Esempio n. 28
0
    def activate(self, span: SpanShim, finish_on_close: bool) -> "ScopeShim":
        """Activates a :class:`SpanShim` and returns a :class:`ScopeShim` which
        represents the active span.

        Args:
            span: A :class:`SpanShim` to be activated.
            finish_on_close(:obj:`bool`): Determines whether the OpenTelemetry
                span should be ended when the returned :class:`ScopeShim` is
                closed.

        Returns:
            A :class:`ScopeShim` representing the activated span.
        """

        span_cm = use_span(span.unwrap(), end_on_exit=finish_on_close)
        return ScopeShim.from_context_manager(self, span_cm=span_cm)
    def _before_cur_exec(self, conn, cursor, statement, *args):
        attrs, found = _get_attributes_from_url(conn.engine.url)
        if not found:
            attrs = _get_attributes_from_cursor(self.vendor, cursor, attrs)

        db_name = attrs.get(SpanAttributes.DB_NAME, "")
        span = self.tracer.start_span(
            self._operation_name(db_name, statement),
            kind=trace.SpanKind.CLIENT,
        )
        self.current_thread_span = self.cursor_mapping[cursor] = span
        with trace.use_span(span, end_on_exit=False):
            if span.is_recording():
                span.set_attribute(SpanAttributes.DB_STATEMENT, statement)
                span.set_attribute(SpanAttributes.DB_SYSTEM, self.vendor)
                for key, value in attrs.items():
                    span.set_attribute(key, value)
    def process_request(self, request):
        # request.META is a dictionary containing all available HTTP headers
        # Read more about request.META here:
        # https://docs.djangoproject.com/en/3.0/ref/request-response/#django.http.HttpRequest.META

        if self._excluded_urls.url_disabled(request.build_absolute_uri("?")):
            return

        # pylint:disable=W0212
        request._otel_start_time = time()

        request_meta = request.META

        token = attach(extract(request_meta, getter=wsgi_getter))

        tracer = get_tracer(__name__, __version__)

        span = tracer.start_span(
            self._get_span_name(request),
            kind=SpanKind.SERVER,
            start_time=request_meta.get(
                "opentelemetry-instrumentor-django.starttime_key"
            ),
        )

        attributes = collect_request_attributes(request_meta)

        if span.is_recording():
            attributes = extract_attributes_from_object(
                request, self._traced_request_attrs, attributes
            )
            for key, value in attributes.items():
                span.set_attribute(key, value)

        activation = use_span(span, end_on_exit=True)
        activation.__enter__()  # pylint: disable=E1101

        request.META[self._environ_activation_key] = activation
        request.META[self._environ_span_key] = span
        request.META[self._environ_token] = token

        if _DjangoMiddleware._otel_request_hook:
            _DjangoMiddleware._otel_request_hook(  # pylint: disable=not-callable
                span, request
            )