123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- # Copyright 2024 The Chromium Authors
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- """Tracer, Provider and span context."""
- import contextlib
- from typing import Any, Iterator, Optional, Sequence
- import logging
- import pathlib
- import sys
- from opentelemetry import context as otel_context_api
- from opentelemetry import trace as otel_trace_api
- from opentelemetry.sdk import trace as otel_trace_sdk
- from opentelemetry.util import types as otel_types
- from . import config
- from . import clearcut_span_exporter
- from . import detector
- @contextlib.contextmanager
- def use_span(
- span: otel_trace_api.Span,
- end_on_exit: bool = False,
- record_exception: bool = True,
- set_status_on_exception: bool = True,
- ) -> Iterator[otel_trace_api.Span]:
- """Takes a non-active span and activates it in the current context."""
- try:
- token = otel_context_api.attach(
- # This is needed since the key needs to be the same as
- # used in the rest of opentelemetry code.
- otel_context_api.set_value(otel_trace_api._SPAN_KEY, span))
- try:
- yield span
- finally:
- otel_context_api.detach(token)
- except KeyboardInterrupt as exc:
- if span.is_recording():
- if record_exception:
- span.record_exception(exc)
- if set_status_on_exception:
- span.set_status(otel_trace_api.StatusCode.OK)
- raise
- except BaseException as exc:
- if span.is_recording():
- # Record the exception as an event
- if record_exception:
- span.record_exception(exc)
- # Set status in case exception was raised
- if set_status_on_exception:
- span.set_status(
- otel_trace_api.Status(
- status_code=otel_trace_api.StatusCode.ERROR,
- description=f"{type(exc).__name__}: {exc}",
- ))
- raise
- finally:
- if end_on_exit:
- span.end()
- class Tracer(otel_trace_api.Tracer):
- """Specific otel tracer."""
- def __init__(self, inner: otel_trace_sdk.Tracer) -> None:
- self._inner = inner
- def start_span(
- self,
- name: str,
- context: Optional[otel_context_api.Context] = None,
- kind: otel_trace_api.SpanKind = otel_trace_api.SpanKind.INTERNAL,
- attributes: otel_types.Attributes = None,
- links: Optional[Sequence[otel_trace_api.Link]] = None,
- start_time: Optional[int] = None,
- record_exception: bool = True,
- set_status_on_exception: bool = True,
- ) -> otel_trace_api.Span:
- return self._inner.start_span(
- 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,
- )
- @contextlib.contextmanager
- def start_as_current_span(
- self,
- name: str,
- context: Optional[otel_context_api.Context] = None,
- kind: otel_trace_api.SpanKind = otel_trace_api.SpanKind.INTERNAL,
- attributes: otel_types.Attributes = None,
- links: Optional[Sequence[otel_trace_api.Link]] = None,
- start_time: Optional[int] = None,
- record_exception: bool = True,
- set_status_on_exception: bool = True,
- end_on_exit: bool = True,
- ) -> Iterator[otel_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 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
- class TracerProvider(otel_trace_api.TracerProvider):
- """Specific otel tracer provider."""
- def __init__(self, inner: otel_trace_sdk.TracerProvider) -> None:
- self._inner = inner
- def get_tracer(
- self,
- instrumenting_module_name: str,
- instrumenting_library_version: Optional[str] = None,
- schema_url: Optional[str] = None,
- ) -> otel_trace_api.Tracer:
- tracer = self._inner.get_tracer(
- instrumenting_module_name=instrumenting_module_name,
- instrumenting_library_version=instrumenting_library_version,
- schema_url=schema_url,
- )
- return Tracer(tracer)
- def __getattr__(self, name: str) -> Any:
- """Method allows to delegate method calls."""
- return getattr(self._inner, name)
|