Трейсинг (OpenTelemetry)¶
Инструментируем каждый запрос¶
# Middleware/__init__.py
from endocore.middleware import tracing_middleware
middlewares = [tracing_middleware()]
Это открывает один спан на каждый запрос (с именем вида "GET /v1/user/42"),
с атрибутами http.method, http.target, http.status_code. Брошенный
HTTPError проставляет http.status_code из своего статуса, но помечает
спан как ошибку только для 5xx — NotFound не является отказом сервера
и не должен выглядеть так в бэкенде трейсинга. Любое другое необработанное
исключение записывается на спан и помечает его как ошибку — так же, как это
уже логирует logging_middleware.
Без настроенного экспортёра спаны всё равно создаются — это само по себе полезно для корреляции trace-id/логов ниже — но никуда не отправляются.
Отправляем спаны куда-то¶
# extensions.py
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from endocore.extensions.tracing import TracingExtension
extensions = [TracingExtension(exporter=OTLPSpanExporter(), service_name="my-app")]
EndoCore не зависит ни от какого конкретного пакета-экспортёра — поставьте
тот, что нужен вашему коллектору (opentelemetry-exporter-otlp, консольный
экспортёр для локальной отладки и т.д.), и передайте уже созданный экземпляр.
TracingExtension выставляет его как глобальный TracerProvider и сбрасывает
накопленные спаны при остановке.
Сопоставление трейсов с логами¶
У каждого запроса уже есть X-Request-ID (см. Логирование).
tracing_middleware дополнительно кладёт trace id спана в
request.scope["trace_id"], так что хендлер (или другой middleware) может
залогировать оба значения рядом: