[feat] add otel adapters

This commit is contained in:
Azamat 2026-03-20 13:38:57 +03:00
parent 1588efb9ca
commit 96af9c08f5
10 changed files with 321 additions and 8 deletions

65
adapter/otel/tracing.py Normal file
View file

@ -0,0 +1,65 @@
from contextlib import AbstractContextManager
from types import TracebackType
from opentelemetry.trace import Span as OtelApiSpan
from opentelemetry.trace import Status, StatusCode
from opentelemetry.trace import Tracer as OtelApiTracer
from usecase.interface import Attrs, AttrValue
class OtelSpan:
def __init__(self, span: OtelApiSpan) -> None:
self._span = span
self._error_recorded = False
@property
def error_recorded(self) -> bool:
return self._error_recorded
def set_attribute(self, name: str, value: AttrValue) -> None:
self._span.set_attribute(name, value)
def record_error(self, error: Exception) -> None:
self._span.record_exception(error)
self._span.set_status(Status(StatusCode.ERROR, str(error)))
self._error_recorded = True
class OtelSpanContext:
def __init__(self, context_manager: AbstractContextManager[OtelApiSpan]) -> None:
self._context_manager = context_manager
self._span: OtelSpan | None = None
def __enter__(self) -> OtelSpan:
self._span = OtelSpan(self._context_manager.__enter__())
return self._span
def __exit__(
self,
exc_type: type[BaseException] | None,
exc: BaseException | None,
traceback: TracebackType | None,
) -> bool | None:
if isinstance(exc, Exception) and self._span is not None:
if not self._span.error_recorded:
self._span.record_error(exc)
return self._context_manager.__exit__(exc_type, exc, traceback)
class OtelTracer:
def __init__(self, tracer: OtelApiTracer) -> None:
self._tracer = tracer
def start_span(
self,
name: str,
attrs: Attrs | None = None,
) -> OtelSpanContext:
context_manager = self._tracer.start_as_current_span(
name,
attributes=None if attrs is None else dict(attrs),
record_exception=False,
set_status_on_exception=True,
)
return OtelSpanContext(context_manager)