# Логирование и трассировка (OpenTelemetry)

> Логи, метрики и распределённые трассы как три сигнала наблюдаемости и OpenTelemetry — открытый стандарт и набор SDK для их сбора и передачи.

Источник: https://llmdocs.ru/wiki/opentelemetry/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Проект**: OpenTelemetry (CNCF, с 2019)
- **Предшественники**: OpenTracing и OpenCensus
- **Сигналы**: трассы, метрики, логи, профили
- **Протокол**: OTLP (gRPC и HTTP)
- **Компоненты**: API, SDK, Collector, автоинструментирование
- **Контекст**: W3C Trace Context (traceparent)
- **Бэкенды**: Jaeger, Tempo, Zipkin, Prometheus, Loki, коммерческие APM
**Логирование и трассировка** — способы понять, что происходит внутри работающей системы. Вместе с метриками их называют тремя сигналами **наблюдаемости** (*observability*): метрики показывают, *что* сломалось, логи — *почему*, а распределённые трассы — *где* именно в цепочке сервисов. **OpenTelemetry** (OTel) — открытый стандарт и набор библиотек для сбора всех трёх сигналов единым способом и отправки их в любую систему хранения, без привязки к конкретному поставщику.

## Три сигнала

| Сигнал | Что это | Сильная сторона | Пример хранилища |
|---|---|---|---|
| **Метрики** | числа во времени (RPS, задержка, память) | дёшево, алерты, тренды | [Prometheus](https://llmdocs.ru/wiki/prometheus.md) |
| **Логи** | записи о событиях | подробности конкретного случая | Loki, Elasticsearch |
| **Трассы** | путь одного запроса через сервисы | где тратится время и возникает ошибка | Jaeger, Tempo |

Сила наблюдаемости — в связях между сигналами: из всплеска ошибок на графике [Grafana](https://llmdocs.ru/wiki/grafana.md) перейти к трассам этих запросов, а из трассы — к логам конкретного сервиса с тем же `trace_id`.[2]

## Логирование

Современная практика — **структурированные логи**: каждая запись — объект [JSON](https://llmdocs.ru/wiki/json.md) с полями, а не произвольная строка.

```json
{"ts":"2026-11-09T14:03:12Z","level":"error","service":"payments",
 "msg":"charge failed","order_id":"A-1042","trace_id":"4bf92f3577b34da6"}
```

Такие логи можно фильтровать и агрегировать по полям. Принципы:

- писать в stdout, а сбор и доставку оставить среде: [systemd](https://llmdocs.ru/wiki/systemd.md) и journald, Docker, агенты Fluent Bit, Vector или OTel Collector — так советует методология Twelve-Factor App;[6]
- использовать уровни (`debug`, `info`, `warn`, `error`) и не включать `debug` в продакшене постоянно;
- не писать в логи пароли, токены и персональные данные;
- добавлять идентификатор запроса или трассы, чтобы связать записи разных сервисов.

## Распределённая трассировка

**Трасса** описывает путь одного запроса и состоит из **спанов** — операций с началом, длительностью, атрибутами и ссылкой на родителя. Запрос к API порождает спан, внутри — спаны обращения к базе данных и вызова другого сервиса, у того — свои спаны. В интерфейсе это выглядит как водопадная диаграмма, где сразу видно самое медленное звено.

Чтобы спаны разных сервисов сложились в одну трассу, контекст передаётся с запросом — в HTTP это заголовок `traceparent` по стандарту **W3C Trace Context**:[4]

```
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
             версия-trace_id-родительский span_id-флаги
```

Хранить каждую трассу дорого, поэтому применяют **сэмплирование**: на входе (сохранять, например, 10% запросов) или по завершении (tail sampling — сохранять все медленные и ошибочные).

## OpenTelemetry

OpenTelemetry появился в 2019 году слиянием двух конкурирующих проектов — OpenTracing и OpenCensus — и входит в CNCF; по активности это один из крупнейших проектов фонда после [Kubernetes](https://llmdocs.ru/wiki/kubernetes.md).[1] Он включает:

- **API и SDK** для основных языков (Go, Java, Python, JavaScript, .NET, Rust и др.);
- **автоинструментирование** — агенты, которые без изменения кода создают спаны для HTTP-фреймворков, клиентов баз данных и очередей;
- **OTLP** — протокол передачи телеметрии;
- **Collector** — отдельный сервис, принимающий, обрабатывающий и отправляющий данные;
- **семантические соглашения** — единые имена атрибутов (`http.request.method`, `db.system`), чтобы данные разных сервисов были сопоставимы.[5]

Пример ручного спана на Python:

```python
from opentelemetry import trace

tracer = trace.get_tracer("payments")

def charge(order):
    with tracer.start_as_current_span("charge") as span:
        span.set_attribute("order.id", order.id)
        return gateway.charge(order)
```

Для веб-приложения на [FastAPI](https://llmdocs.ru/wiki/fastapi.md) достаточно запустить его через `opentelemetry-instrument` — спаны для входящих запросов и вызовов базы появятся автоматически.

## Collector

Collector отделяет приложения от бэкендов: сервисы отправляют всё по OTLP на локальный Collector, а он фильтрует, сэмплирует, добавляет метки окружения и пересылает данные в нужные системы.[3]

```yaml
receivers:
  otlp:
    protocols: {grpc: {}, http: {}}
processors:
  batch: {}
exporters:
  otlphttp/tempo: {endpoint: http://tempo:4318}
  prometheus: {endpoint: 0.0.0.0:8889}
service:
  pipelines:
    traces:  {receivers: [otlp], processors: [batch], exporters: [otlphttp/tempo]}
    metrics: {receivers: [otlp], processors: [batch], exporters: [prometheus]}
```

Сменить бэкенд — Jaeger на Tempo или открытое решение на коммерческое — можно правкой конфигурации Collector, не трогая код сервисов.

## Наблюдаемость LLM-приложений

Те же принципы применяют к системам на языковых моделях: каждый вызов модели, шаг [агента](https://llmdocs.ru/wiki/ai-agent.md) и обращение к инструменту становится спаном с атрибутами — модель, число токенов, задержка. Для этого в OpenTelemetry развиваются семантические соглашения GenAI; на них опираются инструменты вроде Langfuse и Phoenix.

## См. также

- [Мониторинг и алертинг](https://llmdocs.ru/wiki/monitoring-alerting.md)
- [Prometheus](https://llmdocs.ru/wiki/prometheus.md)
- [Grafana](https://llmdocs.ru/wiki/grafana.md)
- [SRE, SLO и SLA](https://llmdocs.ru/wiki/sre-slo-sla.md)

## Источники

1. [OpenTelemetry — What is OpenTelemetry](https://opentelemetry.io/docs/what-is-opentelemetry/)
2. [OpenTelemetry — Observability primer](https://opentelemetry.io/docs/concepts/observability-primer/)
3. [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/)
4. [W3C Trace Context](https://www.w3.org/TR/trace-context/)
5. [OpenTelemetry — Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/)
6. [The Twelve-Factor App — Logs](https://12factor.net/logs)
