Что является основной единицей в распределенной трассировке (distributed tracing)?

Ответ

Основной и минимальной единицей в распределенной трассировке является 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")

    // ...
}