ИнтерфейсСэмплер
Интерфейс сэмплера (Sampler): контракт встроенных и своих сэмплеров.
Описание
Сэмплер решает при создании каждого спана, записывается ли спан и экспортируется ли он. Встроенные сэмплеры — AlwaysOn, AlwaysOff, TraceIdRatioBased, ParentBased и AlwaysRecord — создаёт модуль ОтелСэмплер. Свой сэмплер пишут, например, чтобы не записывать служебные запросы по имени спана или сэмплировать операции с разной долей. Аналог Java SDK: Sampler.
Интерфейс — класс ИнтерфейсСэмплер с аннотацией &Интерфейс библиотеки extends. Встроенные сэмплеры объявляют реализацию аннотацией &Реализует("ИнтерфейсСэмплер") у конструктора ПриСозданииОбъекта.
Регистрация сэмплера
Сэмплер задаётся провайдеру трассировки при создании: методом УстановитьСэмплерпостроителя провайдера или параметром конструктора провайдера. Без сэмплера провайдер использует сэмплер по умолчанию ParentBased(root=AlwaysOn). Свой сэмплер можно сделать корневым сэмплером или делегатом ОтелСэмплер.НаОсновеРодителя, обернуть в ОтелСэмплер.ВсегдаЗаписывать и наоборот: сэмплеры комбинируются, как объекты одного интерфейса.
Реализацию интерфейса SDK не проверяет: трассировщик вызывает методы по имени. Проверить класс заранее, например в тестах, можно валидатором библиотеки extends: метод ИнтерфейсыРеализованыКорректно(Сэмплер) объекта ВалидаторРеализации выбрасывает исключение, если у класса с аннотацией &Реализует("ИнтерфейсСэмплер") нет метода интерфейса или у метода неподходящее число параметров.
Потоки
ДолженСэмплировать и Описание вызываются из разных потоков (фоновых заданий) одновременно: спаны создаются параллельно. Сэмплер должен быть потокобезопасным (спецификация Trace SDK, раздел Concurrency requirements): встроенные сэмплеры после создания не изменяются, общие изменяемые данные своего сэмплера защищайте блокировкой.
Методы
ДолженСэмплировать
Принимает решение о сэмплировании создаваемого спана (ShouldSample). Трассировщик вызывает метод при создании каждого спана в SDK-режиме, до вызова процессоров. Порядок по спецификации Trace SDK (раздел SDK Span creation): TraceId родителя или новый TraceId, решение сэмплера, новый SpanId, спан по решению.
| Параметр | Тип | Описание |
|---|---|---|
Контекст | ФиксированноеСоответствие | Контекст (Context) с родительским спаном. Спана нет или его SpanContext невалиден — создаётся корневой спан. Контекст спана родителя возвращает ОтелСэмплер.КонтекстСпанаРодителя; Baggage — ОтелКонтекст.BaggageИзКонтекста(Контекст) |
ИдТрассировки | Строка | TraceId создаваемого спана (32 hex-символа). При валидном родителе совпадает с TraceId родителя |
ИмяСпана | Строка | Имя создаваемого спана |
ВидСпана | Число | Вид создаваемого спана, значение ОтелВидСпана; не заданный при создании вид — Внутренний |
Атрибуты | Соответствие, ФиксированноеСоответствие | Начальные атрибуты создаваемого спана; без атрибутов — пустое соответствие |
Линки | Массив, ФиксированныйМассив из ОтелЛинк | Линки создаваемого спана; без линков — пустой массив |
Атрибуты и линки сэмплер только читает: это коллекции создаваемого спана.
Возвращает: ОтелРезультатСэмплирования — решение, атрибуты, которые получит спан, и TraceState спана:
- решение
ОтелСэмплер.РешениеОтбросить()(DROP) — спан не записывается: возвращается незаписывающий спан с новыми TraceId и SpanId, процессоры его не получают; ОтелСэмплер.РешениеЗаписать()(RECORD_ONLY) — спан записывается и передаётся процессорам, флаг sampled не устанавливается, экспортер спан не получает;ОтелСэмплер.РешениеЗаписатьИЭкспортировать()(RECORD_AND_SAMPLE) — спан записывается, флаг sampled устанавливается, спан экспортируется.
Атрибуты результата устанавливаются у записывающего спана после начальных (одноименные заменяют их) и видны процессорам уже в ПриНачале. TraceState результата становится TraceState спана: пустой очищает состояние трассировки, а результат без TraceState сохраняет TraceState родителя. Результат без атрибутов и TraceState возвращает ОтелСэмплер.Результат(Решение) — без создания объекта на каждый спан.
Описание
Возвращает имя сэмплера или краткое описание с настройками (GetDescription), например TraceIdRatioBased{0.000100}. Описание предназначено для логов и отладки. Оно может меняться со временем, если сэмплер меняет параметры: не кэшируйте его.
Возвращает: Строка
Пример
Сэмплер, который не записывает проверки работоспособности, а остальные спаны передаёт другому сэмплеру, — класс приложения в файле СэмплерБезПроверок.os:
Перем Делегат;
Функция ДолженСэмплировать(Контекст, ИдТрассировки, ИмяСпана, ВидСпана, Атрибуты, Линки) Экспорт
Если ИмяСпана = "GET /health" Тогда
Возврат ОтелСэмплер.Результат(ОтелСэмплер.РешениеОтбросить());
КонецЕсли;
Возврат Делегат.ДолженСэмплировать(Контекст, ИдТрассировки, ИмяСпана, ВидСпана, Атрибуты, Линки);
КонецФункции
Функция Описание() Экспорт
Возврат "SkipHealthChecks{" + Делегат.Описание() + "}";
КонецФункции
&Реализует("ИнтерфейсСэмплер")
Процедура ПриСозданииОбъекта(НовыйДелегат)
Делегат = НовыйДелегат;
КонецПроцедурыРегистрация сэмплера: корневые спаны без проверок работоспособности сэмплируются с долей 10%, дочерние наследуют решение родителя:
#Использовать opentelemetry
ПодключитьСценарий(ОбъединитьПути(ТекущийСценарий().Каталог, "СэмплерБезПроверок.os"), "СэмплерБезПроверок");
Корневой = Новый СэмплерБезПроверок(ОтелСэмплер.ПоДолеТрассировок(0.1));
Провайдер = Новый ОтелПостроительПровайдераТрассировки()
.УстановитьСэмплер(ОтелСэмплер.НаОсновеРодителя(Корневой))
.Построить();Сэмплер, который добавляет атрибут к сэмплированным спанам:
Функция ДолженСэмплировать(Контекст, ИдТрассировки, ИмяСпана, ВидСпана, Атрибуты, Линки) Экспорт
Результат = Делегат.ДолженСэмплировать(Контекст, ИдТрассировки, ИмяСпана, ВидСпана, Атрибуты, Линки);
Если Результат.Решение() = ОтелСэмплер.РешениеОтбросить() Тогда
Возврат Результат;
КонецЕсли;
АтрибутыСэмплера = Новый Соответствие();
АтрибутыСэмплера.Вставить("sampler.name", Делегат.Описание());
Возврат Новый ОтелРезультатСэмплирования(Результат.Решение(), АтрибутыСэмплера,
Результат.СостояниеТрассировки());
КонецФункции