Skip to content

Трассировка

Трассировка позволяет отслеживать цепочку вызовов внутри и между сервисами. Каждая единица работы называется спаном (span). Спаны образуют дерево, корнем которого является корневой спан (root span), а все остальные — дочерние.

Архитектура

ОтелПровайдерТрассировки
    └── ОтелТрассировщик
            └── ОтелСпан
  • ОтелПровайдерТрассировки — точка входа, создаёт трассировщики.
  • ОтелТрассировщик — создаёт спаны.
  • ОтелСпан — единица работы: хранит атрибуты, события, статус, временны́е метки.

Создание провайдера через построитель

ОтелПостроительПровайдераТрассировки предоставляет Fluent API для настройки провайдера.

bsl
#Использовать opentelemetry

Ресурс = Новый ОтелРесурс();
Ресурс.Атрибуты().Установить("service.name", "my-service");

Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318");
Экспортер = Новый ОтелЭкспортерСпанов(Транспорт);

Провайдер = Новый ОтелПостроительПровайдераТрассировки()
    .УстановитьРесурс(Ресурс)
    .ДобавитьПроцессор(Новый ОтелПакетныйПроцессорСпанов(Экспортер))
    .Построить();

Трассировщик = Провайдер.ПолучитьТрассировщик("my-library", "1.0.0");

Создание спанов

Простой спан

bsl
// SpanKind задаётся при создании и неизменен (immutable)
Спан = Трассировщик.НачатьСпан("обработка-запроса", ОтелВидСпана.Сервер());
Область = Спан.СделатьТекущим();

// ... работа ...

Область.Закрыть();
Спан.Завершить();

Дочерний спан

НачатьСпан автоматически подхватывает родителя из текущего контекста:

bsl
// Родительский спан
Спан = Трассировщик.НачатьСпан("операция", ОтелВидСпана.Сервер());
Область = Спан.СделатьТекущим();

// Дочерний спан — НачатьСпан видит текущий спан как родителя
ДочернийСпан = Трассировщик.НачатьСпан("запрос-к-бд", ОтелВидСпана.Клиент());
ОбластьДочернего = ДочернийСпан.СделатьТекущим();
// ... работа ...
ОбластьДочернего.Закрыть();
ДочернийСпан.Завершить();

Область.Закрыть();
Спан.Завершить();

Корневой спан (явный родительский контекст)

bsl
// НачатьДочернийСпан принимает контекст явно
НовыйКонтекст = Пропагаторы.Извлечь(ОтелКонтекст.Текущий(), ВходящиеЗаголовки);
Спан = Трассировщик.НачатьДочернийСпан("обработка", НовыйКонтекст, ОтелВидСпана.Сервер());

Виды спанов (SpanKind)

ОтелВидСпана описывает роль спана в распределённой системе:

МетодОписание
ОтелВидСпана.Внутренний()Внутренняя операция (по умолчанию)
ОтелВидСпана.Сервер()Входящий RPC/HTTP-запрос
ОтелВидСпана.Клиент()Исходящий RPC/HTTP-запрос
ОтелВидСпана.Производитель()Отправка сообщения в очередь
ОтелВидСпана.Потребитель()Получение сообщения из очереди

Атрибуты

Атрибуты — пары ключ/значение, описывающие контекст операции:

bsl
Спан.УстановитьАтрибут("http.method", "GET");
Спан.УстановитьАтрибут("http.url", "/api/data");
Спан.УстановитьАтрибут("http.status_code", 200);
Спан.УстановитьАтрибут("db.rows_affected", 42);

События спана

События — именованные точки во времени с атрибутами:

bsl
// Простое событие
Спан.ДобавитьСобытие("cache-miss");

// Событие с атрибутами
Атрибуты = Новый ОтелАтрибуты();
Атрибуты.Установить("exception.type", "ФайлНеНайден");
Атрибуты.Установить("exception.message", "Файл config.json не найден");
Спан.ДобавитьСобытиеСАтрибутами("exception", Атрибуты);

Линки связывают спан с другим контекстом (например, асинхронные операции):

bsl
КонтекстСпана = ДругойСпан.ПолучитьКонтекст();
Линк = Новый ОтелЛинк(КонтекстСпана);
Спан = Трассировщик.НачатьСпан("async-операция", ОтелВидСпана.Внутренний(), , Массив(Линк));

Статус спана

ОтелКодСтатуса описывает результат операции:

МетодОписание
ОтелКодСтатуса.НеУстановлен()Статус не задан (по умолчанию)
ОтелКодСтатуса.Ок()Операция завершилась успешно
ОтелКодСтатуса.Ошибка()Операция завершилась с ошибкой
bsl
// Успешное завершение
Спан.УстановитьСтатус(ОтелКодСтатуса.Ок());

// Ошибка с описанием
Спан.УстановитьСтатус(ОтелКодСтатуса.Ошибка(), "Таймаут подключения к БД");

Семплирование

ОтелСэмплер контролирует, какие спаны записываются и экспортируются. Стратегия задаётся при создании провайдера или через OTEL_TRACES_SAMPLER.

bsl
Провайдер = Новый ОтелПостроительПровайдераТрассировки()
    .УстановитьСэмплер(ОтелСэмплер.ВсегдаВключен())
    .Построить();
bsl
Провайдер = Новый ОтелПостроительПровайдераТрассировки()
    .УстановитьСэмплер(ОтелСэмплер.НаОсновеРодителя(ОтелСэмплер.ПоДолеТрассировок(0.1)))
    .Построить();
bash
# 10% трафика
export OTEL_TRACES_SAMPLER=parentbased_traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.1

# Ничего не записывать
export OTEL_TRACES_SAMPLER=always_off

Доступные стратегии:

МетодОписание
ОтелСэмплер.ВсегдаВключен()Сэмплировать все спаны
ОтелСэмплер.ВсегдаВыключен()Не сэмплировать ничего
ОтелСэмплер.ПоДолеТрассировок(Доля)Случайная доля трассировок (0.0 – 1.0)
ОтелСэмплер.НаОсновеРодителя(КорневойСэмплер)ParentBased: наследует решение родителя

Процессоры спанов

Простой процессор (для разработки)

Синхронно экспортирует каждый спан сразу после завершения. Подходит для отладки.

bsl
Процессор = Новый ОтелПростойПроцессорСпанов(Экспортер);

Пакетный процессор (для продакшена)

Накапливает спаны в очереди и отправляет пакетами в фоновом потоке.

bsl
Процессор = Новый ОтелПакетныйПроцессорСпанов(Экспортер);

Настройка через переменные окружения:

ПеременнаяПо умолчаниюОписание
OTEL_BSP_MAX_QUEUE_SIZE2048Максимальный размер очереди
OTEL_BSP_SCHEDULE_DELAY5000Интервал экспорта (мс)
OTEL_BSP_MAX_EXPORT_BATCH_SIZE512Максимальный размер пакета
OTEL_BSP_EXPORT_TIMEOUT30000Таймаут экспорта (мс)

Композитный процессор

Объединяет несколько процессоров для одновременной отправки в разные системы:

bsl
Процессор = Новый ОтелКомпозитныйПроцессорСпанов();
Процессор.ДобавитьПроцессор(Новый ОтелПакетныйПроцессорСпанов(ЭкспортерGrafana));
Процессор.ДобавитьПроцессор(Новый ОтелПакетныйПроцессорСпанов(ЭкспортерJaeger));

Лимиты спана

ОтелЛимитыСпана ограничивают количество атрибутов, событий и ссылок:

bsl
Лимиты = Новый ОтелЛимитыСпана();
// Настройки через конструктор или через ОтелКонфигурацияЛимитовСпана

Конфигурируются через переменные окружения:

ПеременнаяПо умолчаниюОписание
OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT128Максимальное число атрибутов спана
OTEL_SPAN_EVENT_COUNT_LIMIT128Максимальное число событий
OTEL_SPAN_LINK_COUNT_LIMIT128Максимальное число ссылок
OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT128Максимальное число атрибутов события
OTEL_LINK_ATTRIBUTE_COUNT_LIMIT128Максимальное число атрибутов ссылки

Завершение работы

bsl
// Обязательно закрывайте провайдер для сброса незавершённых спанов
Провайдер.Закрыть();

Смотрите также