Ответ
Основной и минимальной единицей в распределенной трассировке является Span (отрезок, промежуток).
Span представляет собой отдельную логическую единицу работы или операцию в системе (например, HTTP-запрос, вызов функции, запрос к базе данных). Каждый span содержит важную информацию:
- Имя операции.
- Время начала и окончания.
- Атрибуты (теги): пары ключ-значение для контекста (например,
http.method="GET"
). - События (логи): временные метки с описанием событий, произошедших во время выполнения span.
- Идентификаторы:
Trace ID
: уникальный идентификатор всего сквозного запроса.Span ID
: уникальный идентификатор данного span.Parent Span ID
: идентификатор родительского span (если он есть).
Совокупность всех span с одинаковым Trace ID
, выстроенных в иерархию с помощью Parent Span ID
, образует Trace (трассу) — полную картину прохождения одного запроса через всю систему.
Пример создания span в Go с использованием OpenTelemetry:
import (
"context"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
)
func processRequest(ctx context.Context) {
// Получаем глобальный tracer
tracer := otel.Tracer("my-app-tracer")
// Начинаем новый span
ctx, span := tracer.Start(ctx, "processRequest")
defer span.End() // Важно завершить span
// Добавляем атрибуты для контекста
span.SetAttributes(attribute.String("user.id", "12345"))
// ... здесь выполняется полезная работа ...
// Добавляем событие, чтобы отметить момент времени
span.AddEvent("Cache lookup finished")
// ...
}