Spans и Traces
Тема дорожной карты · Observability
Спан — это фундаментальная единица работы в распределённой трассировке: он представляет единственную именованную, временно ограниченную операцию в рамках сервиса, такую как вызов HTTP-обработчика, запрос к базе данных или запрос к внешнему API. Каждый спан несёт span_id, родительский span_id (если он был создан вызывающим сервисом) и trace_id, связывающий все спаны, принадлежащие одному сквозному запросу. Трассировка — это полная коллекция спанов, которые вместе описывают жизненный цикл одного запроса через распределённую систему; обычно она визуализируется в виде диаграммы Ганта или флейм-графа в таких инструментах, как Jaeger или Grafana Tempo. Спаны могут нести атрибуты (метаданные в виде пар «ключ-значение»), события (аннотации с временными метками) и статус (OK, ERROR) — всё это обогащает сигнал наблюдаемости при отладке. API Tracer в OpenTelemetry — это стандартный способ создания спанов программно, тогда как агенты автоинструментирования могут добавлять спаны для популярных фреймворков без каких-либо изменений в коде.
Как это работает
Spans и Traces захватывает пути запросов через сервисы. Trace = дерево spans; у каждого span — имя, длительность, атрибуты, parent span. Trace context (traceparent-заголовок по W3C) пробрасывается между сервисами — spans из разных сервисов соединяются в один trace. Storage: Jaeger, Tempo (Grafana-стек, масштабируется через object storage), Zipkin, SigNoz. Sampling at the head (решение per-request) или tail (решение после полного trace).
Когда применять
Tracing — когда сервисов > 2 или нужно дебажить latency. OpenTelemetry SDK + auto-instrumentation для популярных фреймворков (Spring, FastAPI, Express, Gin). Sampling 1-10% в production (head sampling); поднимайте до 100% на короткие debug-сессии. Tempo — если уже на Grafana-стеке; иначе Jaeger / SigNoz оба нормальны.
Типичные ошибки
Ловушки Spans и Traces: 100% sampling на высоком трафике (storage взрывается + perf-хит); сломанная context propagation (HTTP middleware, стрипающий W3C traceparent — каждый вызов = новый trace); spans без релевантного контекста (service, version, user-segment) — traces сложно фильтровать.