Exemplo n.º 1
0
    def update_span_data(self, task_data, host_data, span):
        """ update the span with the given TaskData and HostData """

        name = '[%s] %s: %s' % (host_data.name, task_data.play, task_data.name)

        message = 'success'
        status = Status(status_code=StatusCode.OK)
        if host_data.status == 'included':
            rc = 0
        else:
            res = host_data.result._result
            rc = res.get('rc', 0)
            if host_data.status == 'failed':
                message = self.get_error_message(res)
                status = Status(status_code=StatusCode.ERROR, description=message)
                # Record an exception with the task message
                span.record_exception(BaseException(self.enrich_error_message(res)))
            elif host_data.status == 'skipped':
                if 'skip_reason' in res:
                    message = res['skip_reason']
                else:
                    message = 'skipped'
                status = Status(status_code=StatusCode.UNSET)

        span.set_status(status)
        self.set_span_attribute(span, "ansible.task.args", task_data.args)
        self.set_span_attribute(span, "ansible.task.module", task_data.action)
        self.set_span_attribute(span, "ansible.task.message", message)
        self.set_span_attribute(span, "ansible.task.name", name)
        self.set_span_attribute(span, "ansible.task.result", rc)
        self.set_span_attribute(span, "ansible.task.host.name", host_data.name)
        self.set_span_attribute(span, "ansible.task.host.status", host_data.status)
        span.end(end_time=host_data.finish)
def convertOutcome(outcome):
    if outcome == 'passed':
        return Status(status_code=StatusCode.OK)
    elif outcome == 'failed':
        return Status(status_code=StatusCode.ERROR)
    else:
        return Status(status_code=StatusCode.UNSET)
Exemplo n.º 3
0
    def traced_execution(self, query_method: typing.Callable[..., typing.Any],
                         *args: typing.Tuple[typing.Any, typing.Any],
                         **kwargs: typing.Dict[typing.Any, typing.Any]):

        statement = args[0] if args else ""
        with self._db_api_integration.tracer.start_as_current_span(
                self._db_api_integration.name, kind=SpanKind.CLIENT) as span:
            span.set_attribute("component",
                               self._db_api_integration.database_component)
            span.set_attribute("db.type",
                               self._db_api_integration.database_type)
            span.set_attribute("db.instance",
                               self._db_api_integration.database)
            span.set_attribute("db.statement", statement)

            for (
                    attribute_key,
                    attribute_value,
            ) in self._db_api_integration.span_attributes.items():
                span.set_attribute(attribute_key, attribute_value)

            if len(args) > 1:
                span.set_attribute("db.statement.parameters", str(args[1]))

            try:
                result = query_method(*args, **kwargs)
                span.set_status(Status(StatusCanonicalCode.OK))
                return result
            except Exception as ex:  # pylint: disable=broad-except
                span.set_status(Status(StatusCanonicalCode.UNKNOWN, str(ex)))
                raise ex
Exemplo n.º 4
0
async def _do_execute(func, instance, args, kwargs):
    span_attributes = _hydrate_span_from_args(instance, args[0], args[1:])
    tracer = getattr(asyncpg, _APPLIED)

    exception = None

    with tracer.start_as_current_span("postgresql",
                                      kind=SpanKind.CLIENT) as span:

        for attribute, value in span_attributes.items():
            span.set_attribute(attribute, value)

        try:
            result = await func(*args, **kwargs)
        except Exception as exc:  # pylint: disable=W0703
            exception = exc
            raise
        finally:
            if exception is not None:
                span.set_status(Status(
                    _exception_to_canonical_code(exception)))
            else:
                span.set_status(Status(StatusCanonicalCode.OK))

    return result
Exemplo n.º 5
0
async def _opentracing_middleware(
    request: Request,
    handler: Callable[[Request], Awaitable[StreamResponse]],
) -> StreamResponse:
    tracer = get_tracer(__name__)
    attach(extract(_headers_getter, request))
    with tracer.start_as_current_span(
            request.path,
            kind=SpanKind.SERVER,
            attributes={
                "component": "http",
                "http.method": request.method,
                "http.scheme": request.scheme,
                "http.host": request.host,
            },
    ) as span:
        try:
            response = await handler(request)
        except HTTPException as e:
            code = _utils.status_to_canonical_code(e.status)
            span.set_status(Status(code))
            span.set_attribute("http.status_text", e.reason)
            raise
        else:
            code = _utils.status_to_canonical_code(response.status)
            span.set_status(Status(code))
            span.set_attribute("http.status_text", response.reason)
            return response
Exemplo n.º 6
0
    def test_description_and_non_error_status(self):
        with self.assertLogs(level=WARNING) as warning:
            status = Status(status_code=StatusCode.OK,
                            description="status description")
            self.assertIs(status.status_code, StatusCode.OK)
            self.assertEqual(status.description, None)
            self.assertIn(
                "description should only be set when status_code is set to StatusCode.ERROR",
                warning.output[0],
            )

        with self.assertLogs(level=WARNING) as warning:
            status = Status(status_code=StatusCode.UNSET,
                            description="status description")
            self.assertIs(status.status_code, StatusCode.UNSET)
            self.assertEqual(status.description, None)
            self.assertIn(
                "description should only be set when status_code is set to StatusCode.ERROR",
                warning.output[0],
            )

        status = Status(status_code=StatusCode.ERROR,
                        description="status description")
        self.assertIs(status.status_code, StatusCode.ERROR)
        self.assertEqual(status.description, "status description")
Exemplo n.º 7
0
def trace_call(name, session, extra_attributes=None):
    if not HAS_OPENTELEMETRY_INSTALLED or not session:
        # Empty context manager. Users will have to check if the generated value is None or a span
        yield None
        return

    tracer = trace.get_tracer(__name__)

    # Set base attributes that we know for every trace created
    attributes = {
        "db.type": "spanner",
        "db.url": SpannerClient.DEFAULT_ENDPOINT,
        "db.instance": session._database.name,
        "net.host.name": SpannerClient.DEFAULT_ENDPOINT,
    }

    if extra_attributes:
        attributes.update(extra_attributes)

    with tracer.start_as_current_span(name,
                                      kind=trace.SpanKind.CLIENT,
                                      attributes=attributes) as span:
        try:
            yield span
        except GoogleAPICallError as error:
            if error.code is not None:
                span.set_status(
                    Status(http_status_to_canonical_code(error.code)))
            elif error.grpc_status_code is not None:
                span.set_status(
                    # OpenTelemetry's StatusCanonicalCode maps 1-1 with grpc status codes
                    Status(StatusCanonicalCode(error.grpc_status_code.value[0])
                           ))
            raise
def trace_call(name, session, extra_attributes=None):
    if not HAS_OPENTELEMETRY_INSTALLED or not session:
        # Empty context manager. Users will have to check if the generated value is None or a span
        yield None
        return

    tracer = trace.get_tracer(__name__)

    # Set base attributes that we know for every trace created
    attributes = {
        "db.type": "spanner",
        "db.url": SpannerClient.DEFAULT_ENDPOINT,
        "db.instance": session._database.name,
        "net.host.name": SpannerClient.DEFAULT_ENDPOINT,
    }

    if extra_attributes:
        attributes.update(extra_attributes)

    with tracer.start_as_current_span(
        name, kind=trace.SpanKind.CLIENT, attributes=attributes
    ) as span:
        try:
            span.set_status(Status(StatusCode.OK))
            yield span
        except GoogleAPICallError as error:
            span.set_status(Status(StatusCode.ERROR))
            span.record_exception(error)
            raise
def trace_call(name, connection, extra_attributes=None):
    if not HAS_OPENTELEMETRY_INSTALLED or not connection:
        # Empty context manager. Users will have to check if the generated value
        # is None or a span.
        yield None
        return

    tracer = trace.get_tracer(__name__)

    # Set base attributes that we know for every trace created
    attributes = {
        "db.type": "spanner",
        "db.engine": "django_spanner",
        "db.project": connection.settings_dict["PROJECT"],
        "db.instance": connection.settings_dict["INSTANCE"],
        "db.name": connection.settings_dict["NAME"],
    }

    if extra_attributes:
        attributes.update(extra_attributes)

    with tracer.start_as_current_span(
        name, kind=trace.SpanKind.CLIENT, attributes=attributes
    ) as span:
        try:
            span.set_status(Status(StatusCode.OK))
            yield span
        except GoogleAPICallError as error:
            span.set_status(Status(StatusCode.ERROR))
            span.record_exception(error)
            raise
Exemplo n.º 10
0
    def test_constructor(self):
        status = Status()
        self.assertIs(status.status_code, StatusCode.UNSET)
        self.assertIsNone(status.description)

        status = Status(StatusCode.ERROR, "unavailable")
        self.assertIs(status.status_code, StatusCode.ERROR)
        self.assertEqual(status.description, "unavailable")
Exemplo n.º 11
0
    def test_constructor(self):
        status = Status()
        self.assertIs(status.canonical_code, StatusCanonicalCode.OK)
        self.assertIsNone(status.description)

        status = Status(StatusCanonicalCode.UNAVAILABLE, "unavailable")
        self.assertIs(status.canonical_code, StatusCanonicalCode.UNAVAILABLE)
        self.assertEqual(status.description, "unavailable")
Exemplo n.º 12
0
 def v2_playbook_on_stats(self, stats):
     if self.errors == 0:
         status = Status(status_code=StatusCode.OK)
     else:
         status = Status(status_code=StatusCode.ERROR)
     self.opentelemetry.generate_distributed_traces(self.otel_service_name,
                                                    self.ansible_playbook,
                                                    self.tasks_data, status,
                                                    self.traceparent)
Exemplo n.º 13
0
    def update_span_data(self, task_data, host_data, span):
        """ update the span with the given TaskData and HostData """

        name = '[%s] %s: %s' % (host_data.name, task_data.play, task_data.name)

        message = 'success'
        res = {}
        rc = 0
        status = Status(status_code=StatusCode.OK)
        if host_data.status != 'included':
            # Support loops
            if 'results' in host_data.result._result:
                if host_data.status == 'failed':
                    message = self.get_error_message_from_results(
                        host_data.result._result['results'], task_data.action)
                    enriched_error_message = self.enrich_error_message_from_results(
                        host_data.result._result['results'], task_data.action)
            else:
                res = host_data.result._result
                rc = res.get('rc', 0)
                if host_data.status == 'failed':
                    message = self.get_error_message(res)
                    enriched_error_message = self.enrich_error_message(res)

            if host_data.status == 'failed':
                status = Status(status_code=StatusCode.ERROR,
                                description=message)
                # Record an exception with the task message
                span.record_exception(BaseException(enriched_error_message))
            elif host_data.status == 'skipped':
                message = res[
                    'skip_reason'] if 'skip_reason' in res else 'skipped'
                status = Status(status_code=StatusCode.UNSET)
            elif host_data.status == 'ignored':
                status = Status(status_code=StatusCode.UNSET)

        span.set_status(status)
        if isinstance(task_data.args,
                      dict) and "gather_facts" not in task_data.action:
            names = tuple(
                self.transform_ansible_unicode_to_str(k)
                for k in task_data.args.keys())
            values = tuple(
                self.transform_ansible_unicode_to_str(k)
                for k in task_data.args.values())
            self.set_span_attribute(span, ("ansible.task.args.name"), names)
            self.set_span_attribute(span, ("ansible.task.args.value"), values)
        self.set_span_attribute(span, "ansible.task.module", task_data.action)
        self.set_span_attribute(span, "ansible.task.message", message)
        self.set_span_attribute(span, "ansible.task.name", name)
        self.set_span_attribute(span, "ansible.task.result", rc)
        self.set_span_attribute(span, "ansible.task.host.name", host_data.name)
        self.set_span_attribute(span, "ansible.task.host.status",
                                host_data.status)
        # This will allow to enrich the service map
        self.add_attributes_for_service_map_if_possible(span, task_data)
        span.end(end_time=host_data.finish)
    def _instrumented_requests_call(
        method: str, url: str, call_wrapped, get_or_create_headers
    ):
        if context.get_value("suppress_instrumentation") or context.get_value(
            _SUPPRESS_REQUESTS_INSTRUMENTATION_KEY
        ):
            return call_wrapped()

        # See
        # https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/http.md#http-client
        method = method.upper()
        span_name = "HTTP {}".format(method)

        exception = None

        with get_tracer(
            __name__, __version__, tracer_provider
        ).start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
            span.set_attribute("component", "http")
            span.set_attribute("http.method", method.upper())
            span.set_attribute("http.url", url)

            headers = get_or_create_headers()
            propagators.inject(type(headers).__setitem__, headers)

            token = context.attach(
                context.set_value(_SUPPRESS_REQUESTS_INSTRUMENTATION_KEY, True)
            )
            try:
                result = call_wrapped()  # *** PROCEED
            except Exception as exc:  # pylint: disable=W0703
                exception = exc
                result = getattr(exc, "response", None)
            finally:
                context.detach(token)

            if exception is not None:
                span.set_status(
                    Status(_exception_to_canonical_code(exception))
                )
                span.record_exception(exception)

            if result is not None:
                span.set_attribute("http.status_code", result.status_code)
                span.set_attribute("http.status_text", result.reason)
                span.set_status(
                    Status(http_status_to_canonical_code(result.status_code))
                )

            if span_callback is not None:
                span_callback(span, result)

        if exception is not None:
            raise exception.with_traceback(exception.__traceback__)

        return result
Exemplo n.º 15
0
def convertOutcome(outcome):
    """Convert from pytest outcome to OpenTelemetry status code"""
    if outcome == "passed":
        return Status(status_code=StatusCode.OK)
    elif (outcome == "failed" or outcome == "interrupted"
          or outcome == "internal_error" or outcome == "usage_error"
          or outcome == "no_tests_collected"):
        return Status(status_code=StatusCode.ERROR)
    else:
        return Status(status_code=StatusCode.UNSET)
Exemplo n.º 16
0
    def instrumented_request(self, method, url, *args, **kwargs):
        if context.get_value("suppress_instrumentation"):
            return wrapped(self, method, url, *args, **kwargs)

        # See
        # https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/http.md#http-client
        try:
            parsed_url = urlparse(url)
            span_name = parsed_url.path
        except ValueError as exc:  # Invalid URL
            span_name = "<Unparsable URL: {}>".format(exc)

        exception = None

        with get_tracer(
            __name__, __version__, tracer_provider
        ).start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
            span.set_attribute("component", "http")
            span.set_attribute("http.method", method.upper())
            span.set_attribute("http.url", url)

            headers = kwargs.get("headers", {}) or {}
            propagators.inject(type(headers).__setitem__, headers)
            kwargs["headers"] = headers

            try:
                result = wrapped(
                    self, method, url, *args, **kwargs
                )  # *** PROCEED
            except Exception as exc:  # pylint: disable=W0703
                exception = exc
                result = getattr(exc, "response", None)

            if exception is not None:
                span.set_status(
                    Status(_exception_to_canonical_code(exception))
                )

            if result is not None:
                span.set_attribute("http.status_code", result.status_code)
                span.set_attribute("http.status_text", result.reason)
                span.set_status(
                    Status(http_status_to_canonical_code(result.status_code))
                )

            if span_callback is not None:
                span_callback(span, result)

        if exception is not None:
            raise exception.with_traceback(exception.__traceback__)

        return result
Exemplo n.º 17
0
def set_status_code(span, status_code):
    """Adds HTTP response attributes to span using the status_code argument."""
    try:
        status_code = int(status_code)
    except ValueError:
        span.set_status(
            Status(
                StatusCanonicalCode.UNKNOWN,
                "Non-integer HTTP status: " + repr(status_code),
            ))
    else:
        span.set_attribute("http.status_code", status_code)
        span.set_status(Status(http_status_to_canonical_code(status_code)))
Exemplo n.º 18
0
    def traced_execution(self, query_method: typing.Callable[..., typing.Any],
                         *args: typing.Tuple[typing.Any, typing.Any],
                         **kwargs: typing.Dict[typing.Any, typing.Any]):

        with self._db_api_integration.get_tracer().start_as_current_span(
                self._db_api_integration.name, kind=SpanKind.CLIENT) as span:
            self._populate_span(span, *args)
            try:
                result = query_method(*args, **kwargs)
                span.set_status(Status(StatusCanonicalCode.OK))
                return result
            except Exception as ex:  # pylint: disable=broad-except
                span.set_status(Status(StatusCanonicalCode.UNKNOWN, str(ex)))
                raise ex
def set_status_code(span, status_code):
    """Adds HTTP response attributes to span using the status_code argument."""
    if not span.is_recording():
        return
    try:
        status_code = int(status_code)
    except ValueError:
        span.set_status(
            Status(
                StatusCode.ERROR,
                "Non-integer HTTP status: " + repr(status_code),
            ))
    else:
        span.set_attribute("http.status_code", status_code)
        span.set_status(Status(http_status_to_status_code(status_code)))
Exemplo n.º 20
0
    def started(self, event: monitoring.CommandStartedEvent):
        """ Method to handle a pymongo CommandStartedEvent """
        command = event.command.get(event.command_name, "")
        name = DATABASE_TYPE + "." + event.command_name
        statement = event.command_name
        if command:
            name += "." + command
            statement += " " + command

        try:
            span = self._tracer.start_span(name, kind=SpanKind.CLIENT)
            span.set_attribute("component", DATABASE_TYPE)
            span.set_attribute("db.type", DATABASE_TYPE)
            span.set_attribute("db.instance", event.database_name)
            span.set_attribute("db.statement", statement)
            if event.connection_id is not None:
                span.set_attribute("peer.hostname", event.connection_id[0])
                span.set_attribute("peer.port", event.connection_id[1])

            # pymongo specific, not specified by spec
            span.set_attribute("db.mongo.operation_id", event.operation_id)
            span.set_attribute("db.mongo.request_id", event.request_id)

            for attr in COMMAND_ATTRIBUTES:
                _attr = event.command.get(attr)
                if _attr is not None:
                    span.set_attribute("db.mongo." + attr, str(_attr))

            # Add Span to dictionary
            self._span_dict[_get_span_dict_key(event)] = span
        except Exception as ex:  # noqa pylint: disable=broad-except
            if span is not None:
                span.set_status(Status(StatusCanonicalCode.INTERNAL, str(ex)))
                span.end()
                self._remove_span(event)
Exemplo n.º 21
0
    def use_span(self,
                 span: trace_api.Span,
                 end_on_exit: bool = False) -> Iterator[trace_api.Span]:
        try:
            token = context_api.attach(context_api.set_value(SPAN_KEY, span))
            try:
                yield span
            finally:
                context_api.detach(token)

        except Exception as error:  # pylint: disable=broad-except
            if (isinstance(span, Span) and span.status is None
                    and span._set_status_on_exception  # pylint:disable=protected-access  # noqa
                ):
                span.set_status(
                    Status(
                        canonical_code=StatusCanonicalCode.UNKNOWN,
                        description="{}: {}".format(
                            type(error).__name__, error),
                    ))

            raise

        finally:
            if end_on_exit:
                span.end()
Exemplo n.º 22
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(
            propagators.extract(get_header_from_environ, environ))
        span_name = self.name_callback(environ)

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

        try:
            with self.tracer.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:
            span.set_status(Status(StatusCanonicalCode.INTERNAL, str(ex)))
            span.end()
            context.detach(token)
            raise
    def _trace_failure(*args, **kwargs):
        task = utils.retrieve_task_from_sender(kwargs)
        task_id = utils.retrieve_task_id(kwargs)

        if task is None or task_id is None:
            return

        # retrieve and pass exception info to activation
        span, _ = utils.retrieve_span(task, task_id)
        if span is None or not span.is_recording():
            return

        status_kwargs = {"status_code": StatusCode.ERROR}

        ex = kwargs.get("einfo")

        if (
            hasattr(task, "throws")
            and ex is not None
            and isinstance(ex.exception, task.throws)
        ):
            return

        if ex is not None:
            status_kwargs["description"] = str(ex)
        span.set_status(Status(**status_kwargs))
Exemplo n.º 24
0
    def _intercept_server_stream(self, request_or_iterator, metadata,
                                 client_info, invoker):
        if not metadata:
            mutable_metadata = OrderedDict()
        else:
            mutable_metadata = OrderedDict(metadata)

        with self._start_span(client_info.full_method) as span:
            inject(mutable_metadata, setter=_carrier_setter)
            metadata = tuple(mutable_metadata.items())
            rpc_info = RpcInfo(
                full_method=client_info.full_method,
                metadata=metadata,
                timeout=client_info.timeout,
            )

            if client_info.is_client_stream:
                rpc_info.request = request_or_iterator

            try:
                yield from invoker(request_or_iterator, metadata)
            except grpc.RpcError as err:
                span.set_status(Status(StatusCode.ERROR))
                span.set_attribute(SpanAttributes.RPC_GRPC_STATUS_CODE,
                                   err.code().value[0])
                raise err
Exemplo n.º 25
0
 def __init__(
     self,
     name: str = None,
     context: trace_api.SpanContext = None,
     parent: Optional[trace_api.SpanContext] = None,
     resource: Resource = Resource.create({}),
     attributes: types.Attributes = None,
     events: Sequence[Event] = (),
     links: Sequence[trace_api.Link] = (),
     kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL,
     instrumentation_info: InstrumentationInfo = None,
     status: Status = Status(StatusCode.UNSET),
     start_time: Optional[int] = None,
     end_time: Optional[int] = None,
 ) -> None:
     self._name = name
     self._context = context
     self._kind = kind
     self._instrumentation_info = instrumentation_info
     self._parent = parent
     self._start_time = start_time
     self._end_time = end_time
     self._attributes = attributes
     self._events = events
     self._links = links
     self._resource = resource
     self._status = status
Exemplo n.º 26
0
    def test_span_to_envelope_properties(self):
        exporter = self._exporter
        start_time = 1575494316027613500
        end_time = start_time + 1001000000

        # Properties
        span = trace._Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
                is_remote=False,
            ),
            attributes={
                "test": "asd",
                "http.method": "GET",
                "http.url": "https://www.wikipedia.org/wiki/Rabbit",
                "http.status_code": 200,
            },
            kind=SpanKind.CLIENT,
        )
        span._status = Status(status_code=StatusCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter._span_to_envelope(span)
        self.assertEqual(len(envelope.data.base_data.properties), 1)
        self.assertEqual(envelope.data.base_data.properties["test"], "asd")
Exemplo n.º 27
0
    def test_span_envelope_server_messaging(self):
        exporter = self._exporter
        start_time = 1575494316027613500
        end_time = start_time + 1001000000

        # SpanKind.SERVER messaging
        span = trace._Span(
            name="test",
            context=SpanContext(
                trace_id=36873507687745823477771305566750195431,
                span_id=12030755672171557337,
                is_remote=False,
            ),
            attributes={
                "messaging.system": "messaging",
                "net.peer.name": "test name",
                "net.peer.ip": "127.0.0.1",
                "messaging.destination": "celery",
            },
            kind=SpanKind.SERVER,
        )
        span._status = Status(status_code=StatusCode.OK)
        span.start(start_time=start_time)
        span.end(end_time=end_time)
        envelope = exporter._span_to_envelope(span)
        self.assertEqual(envelope.data.base_type, "RequestData")
        self.assertEqual(envelope.data.base_data.name, "test")
        self.assertEqual(envelope.data.base_data.id, "a6f5d48acb4d31d9")
        self.assertEqual(envelope.data.base_data.duration, "0.00:00:01.001")
        self.assertTrue(envelope.data.base_data.success)
Exemplo n.º 28
0
    async def _do_execute(self, func, instance, args, kwargs):

        exception = None
        params = getattr(instance, "_params", {})
        name = args[0] if args[0] else params.get("database", "postgresql")

        with self._tracer.start_as_current_span(
            name, kind=SpanKind.CLIENT
        ) as span:
            if span.is_recording():
                span_attributes = _hydrate_span_from_args(
                    instance,
                    args[0],
                    args[1:] if self.capture_parameters else None,
                )
                for attribute, value in span_attributes.items():
                    span.set_attribute(attribute, value)

            try:
                result = await func(*args, **kwargs)
            except Exception as exc:  # pylint: disable=W0703
                exception = exc
                raise
            finally:
                if span.is_recording() and exception is not None:
                    span.set_status(Status(StatusCode.ERROR))

        return result
Exemplo n.º 29
0
    def use_span(
        self,
        span: trace_api.Span,
        end_on_exit: bool = False,
    ) -> Iterator[trace_api.Span]:
        try:
            token = context_api.attach(context_api.set_value(SPAN_KEY, span))
            try:
                yield span
            finally:
                context_api.detach(token)

        except Exception as exc:  # pylint: disable=broad-except
            # Record the exception as an event
            if isinstance(span, Span) and span.is_recording():
                # pylint:disable=protected-access
                if span._record_exception:
                    span.record_exception(exc)

                # Records status if use_span is used
                # i.e. with tracer.start_as_current_span() as span:
                if (span.status.status_code is StatusCode.UNSET
                        and span._set_status_on_exception):
                    span.set_status(
                        Status(
                            status_code=StatusCode.ERROR,
                            description="{}: {}".format(
                                type(exc).__name__, exc),
                        ))
            raise

        finally:
            if end_on_exit:
                span.end()
Exemplo n.º 30
0
    def started(self, event: monitoring.CommandStartedEvent):
        """ Method to handle a pymongo CommandStartedEvent """
        if not self.is_enabled:
            return
        command = event.command.get(event.command_name, "")
        name = event.command_name
        statement = event.command_name
        if command:
            name += "." + str(command)
            statement += " " + str(command)

        try:
            span = self._tracer.start_span(name, kind=SpanKind.CLIENT)
            if span.is_recording():
                span.set_attribute("db.system", DATABASE_SYSTEM)
                span.set_attribute("db.name", event.database_name)
                span.set_attribute("db.statement", statement)
                if event.connection_id is not None:
                    span.set_attribute("net.peer.name", event.connection_id[0])
                    span.set_attribute("net.peer.port", event.connection_id[1])

            # Add Span to dictionary
            self._span_dict[_get_span_dict_key(event)] = span
        except Exception as ex:  # noqa pylint: disable=broad-except
            if span is not None and span.is_recording():
                span.set_status(Status(StatusCode.ERROR, str(ex)))
                span.end()
                self._pop_span(event)