Skip to content

Экспорт данных ​

SDK поддерживает три транспорта для отправки телеметрии: HTTP (JSON и Protobuf), gRPC и InMemory (для тестов). Все экспортеры работают с любым транспортом — достаточно передать нужный объект транспорта.

Архитектура ​

Транспорт → Экспортер → Процессор → Провайдер
  • Транспорт (ОтелHttpТранспорт, ОтелGrpcТранспорт, ОтелКонсольныйТранспорт, ОтелВПамятьТранспорт) — отвечает за физическую отправку данных. Все попытки отправки и паузы между ними транспорт укладывает в срок, который получает от экспортера.
  • Экспортер (ОтелЭкспортерСпанов, ОтелЭкспортерЛогов, ОтелЭкспортерМетрик) — сериализует данные и передаёт транспорту вместе со сроком экспорта: меньшим из таймаута вызова и таймаута экспортера (OTLP Timeout).
  • Процессор — буферизирует и вызывает экспортер.

HTTP-транспорт ​

ОтелHttpТранспорт отправляет данные по OTLP/HTTP (порт 4318). Поддерживает два формата: http/protobuf (по умолчанию) и http/json.

Все настройки передаются в конструктор: Новый ОтелHttpТранспорт(Адрес, Заголовки, Таймаут, МаксПопыток, Компрессия, НастройкиTls, Протокол). Таймаут задаётся в секундах.

bsl
// Protobuf — бинарный формат, более компактный
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318");
bsl
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318", , , , , , "http/json");
bsl
Заголовки = Новый Соответствие();
Заголовки.Вставить("Authorization", "Bearer my-token");
Заголовки.Вставить("X-Team", "backend");
Транспорт = Новый ОтелHttpТранспорт("https://otel-collector:4318", Заголовки, 15); // 15 секунд
bsl
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318", , , , "gzip");

Эндпоинты HTTP ​

Экспортеры автоматически добавляют суффикс пути к базовому URL транспорта:

ЭкспортерПуть
ОтелЭкспортерСпанов/v1/traces
ОтелЭкспортерЛогов/v1/logs
ОтелЭкспортерМетрик/v1/metrics

gRPC-транспорт ​

ОтелGrpcТранспорт отправляет данные по OTLP/gRPC (порт 4317) через библиотеку oint (OPI_GRPC).

Для использования gRPC необходимо установить oint 1.33.0+: opm install oint

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

// gRPC-транспорт — порт 4317 (стандартный OTLP gRPC)
Транспорт = Новый ОтелGrpcТранспорт("http://localhost:4317");

// Все три экспортера работают с gRPC так же, как с HTTP
ЭкспортерСпанов = Новый ОтелЭкспортерСпанов(Транспорт);
ЭкспортерЛогов = Новый ОтелЭкспортерЛогов(Транспорт);
ЭкспортерМетрик = Новый ОтелЭкспортерМетрик(Транспорт);

gRPC-транспорт повторяет временные ошибки по спецификации OTLP/gRPC (UNAVAILABLE, DEADLINE_EXCEEDED, CANCELLED и др.) и открывает соединение заново, если коллектор был недоступен при создании транспорта. Если сервер прислал RetryInfo, повтор идёт не раньше retry_delay, а следующие — вдвое дольше; RESOURCE_EXHAUSTED повторяется только с RetryInfo. Сжатие gRPC-клиент OPI_GRPC не поддерживает.

Размер запроса и ответа, User-Agent ​

Оба транспорта не отправляют запрос больше 64 MiB (размер до сжатия) — лимит меняется методом УстановитьМаксРазмерЗапроса, 0 снимает ограничение. HTTP-транспорт не принимает ответ больше 4 MiB (УстановитьМаксРазмерОтвета), у gRPC этот лимит фиксирован клиентом gRPC (OpenIntegrations#113).

Заголовок User-Agent (метаданные user-agent для gRPC) — идентификатор продукта: он добавляется перед стандартным OTel-OTLP-Exporter-OneScript/<версия>. По gRPC метаданные user-agent до сервера пока не доходят: клиент tonic внутри OPI_GRPC ставит свой заголовок, и сервер получает tonic/0.13.1 (OpenIntegrations#111).

bsl
Заголовки = Новый Соответствие();
Заголовки.Вставить("User-Agent", "MyDistribution/1.2.3");
// User-Agent: MyDistribution/1.2.3 OTel-OTLP-Exporter-OneScript/<версия>
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318", Заголовки)
    .УстановитьМаксРазмерЗапроса(16777216);

Консольный транспорт ​

ОтелКонсольныйТранспорт выводит каждую отправку одной строкой OTLP JSON в стандартный вывод — для отладки и локальной разработки. Это экспортер console файла конфигурации.

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

InMemory-транспорт (для тестов) ​

ОтелВПамятьТранспорт сохраняет сериализованные данные в памяти. Используется в тестах для проверки экспортируемых данных без реальной сети.

bsl
Транспорт = Новый ОтелВПамятьТранспорт();

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

Провайдер = Новый ОтелПровайдерТрассировки(Ресурс, Процессор);
Трассировщик = Провайдер.ПолучитьТрассировщик("test");

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

// Проверка экспортированных данных
Отправки = Транспорт.ПолучитьОтправленные();
// Отправки — массив соответствий с ключами "Путь" и "Данные" (сериализованный OTLP-пакет)

TLS ​

ОтелНастройкиTls хранит настройки TLS в полях ФайлСертификата, ФайлКлиентскогоКлюча, ФайлКлиентскогоСертификата и Insecure. Настройки передаются в конструктор транспорта.

bsl
НастройкиTls = Новый ОтелНастройкиTls();
НастройкиTls.ФайлСертификата = "/etc/ssl/certs/ca.pem";

Транспорт = Новый ОтелGrpcТранспорт("https://otel-collector:4317", НастройкиTls);

Транспорты применяют настройки по-разному:

  • gRPC-транспорт: защищённость соединения задаёт схема адреса — https:// с TLS, http:// без TLS. По TLS сертификат сервера проверяется по системным корневым сертификатам и CA-сертификату из настроек. Insecure действует только на адрес без схемы: по умолчанию такое соединение защищено TLS, с Insecure = Истина — без TLS.
  • HTTP-транспорт принимает настройки шестым параметром конструктора. Insecure по спецификации относится только к gRPC: защищённость HTTP-соединения задаёт схема адреса.
  • Клиентские ключ и сертификат (mTLS) пока не применяются ни одним транспортом. Их не поддерживают HTTP-клиент OneScript и библиотека OPI_GRPC. Оба транспорта пишут об этом предупреждение; HTTP-транспорт предупреждает и о CA-сертификате, который HTTP-клиент OneScript тоже не применяет.

Безопасность. HTTP-клиент OneScript (HTTPСоединение, через него работает 1connector) не проверяет сертификат сервера по HTTPS: соединение шифруется, но принимается любой сертификат, в том числе самоподписанный или выданный на другое имя. Подлинность коллектора по OTLP/HTTP не подтверждается. Если это важно, используйте gRPC-транспорт — он проверяет сертификат сервера, — или доверенную сеть до коллектора.

TLS через переменные окружения:

ПеременнаяОписание
OTEL_EXPORTER_OTLP_CERTIFICATEПуть к CA-сертификату (PEM)
OTEL_EXPORTER_OTLP_CLIENT_KEYПуть к клиентскому ключу (PEM)
OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATEПуть к клиентскому сертификату (PEM)
OTEL_EXPORTER_OTLP_INSECUREtrue — gRPC-соединение с endpoint без схемы идёт без TLS; схема http/https важнее, на OTLP/HTTP не влияет

Опции OTLP-экспортёра по транспортам ​

Все опции спецификации OTLP Exporter задаются переменными окружения (с вариантами для сигналов), файловой конфигурацией и параметрами конструкторов. Часть опций транспорт применить не может:

ОпцияHTTP-транспортgRPC-транспорт
Endpoint✓✓
Insecure— опция только для gRPC✓ адрес без схемы — без TLS
Certificate File✗ сертификат сервера не проверяется✓
Client key file, Client certificate file (mTLS)✗✗
Headers✓✓ метаданные gRPC
Compression (gzip)✓✗ данные отправляются без сжатия (OpenIntegrations#112)
Timeout✓✓ кроме открытия соединения и переподключения (OpenIntegrations#114)
Max Request Size✓ УстановитьМаксРазмерЗапроса✓ УстановитьМаксРазмерЗапроса
Max Response Size✓ УстановитьМаксРазмерОтвета✗ лимит клиента gRPC 4 MiB, как по умолчанию в спецификации (OpenIntegrations#113)
Protocolhttp/protobuf, http/jsongrpc

Неприменяемая опция не теряется молча: транспорт или автоконфигурация пишут предупреждение в лог. Причины — ограничения платформы и библиотек:

  • HTTP-клиент OneScript (HTTPСоединение, через него работает 1connector) не умеет задавать клиентский и корневой сертификаты: в OneScript 2.2.1 нет аналогов ЗащищенноеСоединениеOpenSSL и СертификатКлиентаФайл. Сертификат сервера по HTTPS он не проверяет: принимается любой.
  • gRPC-клиент OPI_GRPC (oint 1.33.0) принимает из настроек TLS только корневой сертификат: клиентского сертификата нет (OpenIntegrations#102), сжатия (OpenIntegrations#112) и настройки лимитов размера сообщения (OpenIntegrations#113) тоже. Таймаута подключения у OPI_GRPC нет: открытие соединения и переподключение не укладываются в срок экспорта. Сервер, который принял TCP-соединение и молчит при TLS-рукопожатии, держит экспорт, пока не закроет соединение, поэтому для gRPC требование «Export MUST NOT block indefinitely» выполняется не полностью (OpenIntegrations#114).

Полные примеры ​

Трассировка + Логирование + Метрики ​

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

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

// Один транспорт для всех сигналов
Транспорт = Новый ОтелHttpТранспорт("http://otel-collector:4318");

// Трассировка
ЭкспортерСпанов = Новый ОтелЭкспортерСпанов(Транспорт);
БазовыйСпанов = Новый ОтелБазовыйПакетныйПроцессор(ЭкспортерСпанов, "traces");
ПроцессорСпанов = Новый ПостроительНаследника(Новый ОтелПакетныйПроцессорСпанов(), БазовыйСпанов).Построить();
ПроцессорСпанов.ЗапуститьФоновыйЭкспорт();
ПровайдерТрассировки = Новый ОтелПровайдерТрассировки(Ресурс, ПроцессорСпанов);

// Логирование
ЭкспортерЛогов = Новый ОтелЭкспортерЛогов(Транспорт);
БазовыйЛогов = Новый ОтелБазовыйПакетныйПроцессор(ЭкспортерЛогов, "logs", 2048, 512, 1000);
ПроцессорЛогов = Новый ПостроительНаследника(Новый ОтелПакетныйПроцессорЛогов(), БазовыйЛогов).Построить();
ПроцессорЛогов.ЗапуститьФоновыйЭкспорт();
ПровайдерЛогирования = Новый ОтелПровайдерЛогирования(Ресурс, ПроцессорЛогов);

// Метрики
ЭкспортерМетрик = Новый ОтелЭкспортерМетрик(Транспорт);
Читатель = Новый ОтелПериодическийЧитательМетрик(ЭкспортерМетрик, 60000);
Читатель.Запустить();
ПровайдерМетрик = Новый ОтелПровайдерМетрик(Ресурс, Читатель);

// Завершение — сбрасывает все буферы
ПровайдерТрассировки.Закрыть();
ПровайдерЛогирования.Закрыть();
ПровайдерМетрик.Закрыть();

gRPC для всех сигналов ​

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

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

// gRPC-транспорт
Транспорт = Новый ОтелGrpcТранспорт("http://otel-collector:4317");

// Трассировка
ЭкспортерСпанов = Новый ОтелЭкспортерСпанов(Транспорт);
Базовый = Новый ОтелБазовыйПакетныйПроцессор(ЭкспортерСпанов, "traces");
ПроцессорСпанов = Новый ПостроительНаследника(Новый ОтелПакетныйПроцессорСпанов(), Базовый).Построить();
ПроцессорСпанов.ЗапуститьФоновыйЭкспорт();
Провайдер = Новый ОтелПровайдерТрассировки(Ресурс, ПроцессорСпанов);

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

Провайдер.Закрыть();

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