OpenTelemetry SDK для OneScript
Библиотека на OneScript для использования OpenTelemetry в оскриптовых проектах. Реализует спецификацию OpenTelemetry v1.55.0.
Позволяет собирать и отправлять телеметрию (трассировку, логи, метрики) в формате OTLP в любой совместимый коллектор — Grafana LGTM, OpenTelemetry Collector и другие.
Возможности
| Подсистема | Описание |
|---|---|
| Автоконфигурация | Настройка SDK из переменных окружения или файла конфигурации (через configor) |
| Трассировка | Спаны, вложенные спаны, атрибуты, события, линки, статусы, семплирование |
| Логирование | Записи логов с уровнями серьёзности и корреляцией с трассировкой |
| Метрики | Счётчики, реверсивные счётчики, датчики, гистограммы, экспоненциальные гистограммы, наблюдаемые инструменты |
| Пропагация | W3C Trace Context, W3C Baggage, B3 (отдельный пакет), композитный пропагатор |
| Экспорт | OTLP/HTTP (JSON и Protobuf), OTLP/gRPC, InMemory (для тестов), TLS |
| Интеграция с logos | Аппендер для logos, перенаправляющий логи в OpenTelemetry |
| Пакетная обработка | Batch-процессоры для спанов и логов с фоновым экспортом |
Установка
opm install opentelemetryВсе зависимости (logos, 1connector, collectionos, configor, async) устанавливаются автоматически.
Быстрый старт
Самый простой способ настроить OpenTelemetry — через автоконфигурацию. Достаточно задать переменные окружения и вызвать ОтелАвтоконфигурация.Инициализировать().
export OTEL_SERVICE_NAME=my-service
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf#Использовать opentelemetry
// Автоконфигурация из переменных окружения
Сдк = ОтелАвтоконфигурация.Инициализировать();
// Получение трассировщика и метра через SDK
Трассировщик = Сдк.ПолучитьТрассировщик("my-library");
Метр = Сдк.ПолучитьМетр("my-library");
// Создание спана
Спан = Трассировщик.НачатьСпан("операция", ОтелВидСпана.Сервер());
Область = Спан.СделатьТекущим();
// ... работа ...
Область.Закрыть();
Спан.Завершить();
// Или через глобальный доступ из любого места кода
Трассировщик = ОтелГлобальный.ПолучитьТрассировщик("другая-библиотека");{
"otel": {
"service": { "name": "my-service" },
"exporter": {
"otlp": {
"endpoint": "http://localhost:4318",
"protocol": "http/protobuf"
}
}
}
}Требования
| Зависимость | Минимальная версия |
|---|---|
| OneScript | 2.2.1+ |
| logos | 1.7.1+ |
| 1connector | 2.2.1+ |
| collectionos | 0.8.2+ |
| configor | 0.11.1+ |
| async | 0.3.0+ |
| oint | 1.33.0+ (только для gRPC-транспорта) |
Дальнейшее изучение
- Автоконфигурация — настройка через переменные окружения и файл конфигурации
- Трассировка — спаны, атрибуты, события, семплирование
- Логирование — записи логов, интеграция с logos
- Метрики — инструменты измерения, периодический экспорт
- Пропагация — W3C Trace Context, Baggage, B3
- Экспорт — транспорты HTTP, gRPC, InMemory, TLS
Автоконфигурация
Модуль ОтелАвтоконфигурация — рекомендуемый способ инициализации SDK. Он следует спецификации переменных окружения OpenTelemetry и автоматически создаёт все необходимые провайдеры (трассировки, логирования, метрик), настраивает экспортеры, процессоры и пропагаторы.
Как работает автоконфигурация
- Читает параметры из переменных окружения (
OTEL_*) и/или файла конфигурации через configor. - Создаёт транспорт (HTTP или gRPC) согласно
OTEL_EXPORTER_OTLP_PROTOCOL. - Строит провайдеры трассировки, логирования и метрик с batch-процессорами. Перед batch-процессором логов стоит процессор событий в события спана.
- Регистрирует SDK глобально через
ОтелГлобальный. - Возвращает готовый объект
ОтелSdk.
Инициализация
#Использовать opentelemetry
Сдк = ОтелАвтоконфигурация.Инициализировать();
// Получение трассировщика
Трассировщик = Сдк.ПолучитьТрассировщик("my-library");
// Получение метра
Метр = Сдк.ПолучитьМетр("my-library");
// Глобальный доступ из любого места кода
Трассировщик2 = ОтелГлобальный.ПолучитьТрассировщик("other-library");Настройка через переменные окружения
Переменные окружения читаются автоматически. Имена переменных соответствуют стандарту OpenTelemetry: OTEL_FOO_BAR → ключ configor otel.foo.bar.
export OTEL_SERVICE_NAME=my-service
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318export OTEL_SERVICE_NAME=my-service
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_EXPORTER_OTLP_PROTOCOL=http/json
export OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production,team=backendexport OTEL_SERVICE_NAME=my-service
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
export OTEL_EXPORTER_OTLP_PROTOCOL=grpcexport OTEL_SDK_DISABLED=trueНастройка через файл конфигурации (configor)
Параметры можно хранить в файле JSON или YAML с теми же ключами, что и у переменных окружения (otel.service.name и т.д.). Файл подключается программно: МенеджерПараметров из configor читает его и передаётся в ОтелАвтоконфигурация.Инициализировать.
Переменная
OTEL_CONFIG_FILEзадаёт файл другого формата — декларативной конфигурации с обязательным полемfile_format. Он описан в ОтелФайловаяКонфигурация.
{
"otel": {
"service": {
"name": "my-service"
},
"exporter": {
"otlp": {
"endpoint": "http://otel-collector:4318",
"protocol": "http/protobuf",
"headers": "Authorization=Bearer token123",
"compression": "gzip",
"timeout": "10000"
}
},
"traces": {
"sampler": "parentbased_traceidratio",
"sampler.arg": "0.1"
},
"propagators": "tracecontext,baggage"
}
}otel:
service:
name: my-service
exporter:
otlp:
endpoint: http://otel-collector:4318
protocol: http/protobuf
compression: gzip
traces:
sampler: parentbased_always_on
propagators: tracecontext,baggage#Использовать opentelemetry
Менеджер = Новый МенеджерПараметров();
Менеджер.ИспользоватьПровайдерJSON(); // для YAML — ИспользоватьПровайдерYAML()
Менеджер.УстановитьФайлПараметров("/etc/myapp/otel-config.json");
Менеджер.Прочитать();
// Переменные окружения в этом случае не читаются
Сдк = ОтелАвтоконфигурация.Инициализировать(Менеджер);Полная таблица переменных окружения
Общие параметры SDK
| Переменная | Ключ configor | По умолчанию | Описание |
|---|---|---|---|
OTEL_SDK_DISABLED | otel.sdk.disabled | false | Отключить SDK. При true создаётся NoOp SDK |
OTEL_SERVICE_NAME | otel.service.name | — | Имя сервиса (service.name в ресурсе) |
OTEL_RESOURCE_ATTRIBUTES | otel.resource.attributes | — | Дополнительные атрибуты ресурса, формат: key1=value1,key2=value2, спецсимволы в percent-encoding. Значение с ошибкой разбора (элемент не в формате ключ=значение, пустой ключ, некорректный percent-encoding) игнорируется целиком |
OTEL_SDK_SHUTDOWN_TIMEOUT | otel.sdk.shutdown.timeout | 30000 | Таймаут завершения SDK в миллисекундах, 0 — без ограничения. Действует, если Закрыть вызван без таймаута |
OTEL_CONFIG_FILE | otel.config.file | — | Путь к файлу декларативной конфигурации (YAML с полем file_format, см. ОтелФайловаяКонфигурация). Читается из менеджера параметров: переданного в Инициализировать или менеджера из переменных окружения. Если задан, SDK строится только по файлу, остальные параметры не применяются. Устаревший ключ — otel.experimental.config.file (OTEL_EXPERIMENTAL_CONFIG_FILE) |
Экспортеры
| Переменная | Ключ configor | По умолчанию | Описание |
|---|---|---|---|
OTEL_TRACES_EXPORTER | otel.traces.exporter | otlp | Экспортер трассировки: otlp, none |
OTEL_LOGS_EXPORTER | otel.logs.exporter | otlp | Экспортер логов: otlp, none |
OTEL_METRICS_EXPORTER | otel.metrics.exporter | otlp | Экспортер метрик: otlp, none |
OTEL_OSCRIPT_EVENT_TO_SPAN_EVENT_BRIDGE_ENABLED | otel.oscript.event.to.span.event.bridge.enabled | true | Включает процессор событий в события спана. Включён только при true (без учёта регистра); пустое значение — как не заданное, другое значение выключает процессор. Ключ языковой: стандартной переменной для процессора нет. Процессор включён и с экспортером логов none |
С экспортером none (или недоступным транспортом) сэмплер, лимиты и фильтр exemplars из переменных окружения всё равно применяются: решение сэмплера задаёт флаг sampled, который передаётся дальше, а спаны, записи и метрики получают процессоры и читатели, добавленные в коде.
OTLP — общие параметры
Применяются ко всем сигналам, если не заданы per-signal переопределения.
| Переменная | Ключ configor | По умолчанию | Описание |
|---|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | otel.exporter.otlp.endpoint | http://localhost:4318 (HTTP) / http://localhost:4317 (gRPC) | Адрес OTLP-коллектора |
OTEL_EXPORTER_OTLP_PROTOCOL | otel.exporter.otlp.protocol | http/protobuf | Протокол: http/json, http/protobuf, grpc |
OTEL_EXPORTER_OTLP_HEADERS | otel.exporter.otlp.headers | — | Заголовки HTTP/gRPC, формат: key1=value1,key2=value2 |
OTEL_EXPORTER_OTLP_COMPRESSION | otel.exporter.otlp.compression | none | Сжатие: gzip, none |
OTEL_EXPORTER_OTLP_TIMEOUT | otel.exporter.otlp.timeout | 10000 | Таймаут запроса в миллисекундах, 0 — без ограничения |
OTEL_EXPORTER_OTLP_CERTIFICATE | otel.exporter.otlp.certificate | — | Путь к CA-сертификату (PEM) |
OTEL_EXPORTER_OTLP_CLIENT_KEY | otel.exporter.otlp.client.key | — | Путь к клиентскому приватному ключу (PEM) |
OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE | otel.exporter.otlp.client.certificate | — | Путь к клиентскому сертификату (PEM) |
OTEL_EXPORTER_OTLP_INSECURE | otel.exporter.otlp.insecure | false | true — gRPC-соединение с endpoint без схемы идёт без TLS (по умолчанию такое соединение защищено TLS); схема http/https важнее, на OTLP/HTTP не влияет |
OTLP — трассировка (per-signal)
Переопределяют общие OTEL_EXPORTER_OTLP_* для сигнала трассировки.
| Переменная | Описание |
|---|---|
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT | Адрес коллектора |
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL | Протокол |
OTEL_EXPORTER_OTLP_TRACES_HEADERS | Заголовки |
OTEL_EXPORTER_OTLP_TRACES_COMPRESSION | Сжатие |
OTEL_EXPORTER_OTLP_TRACES_TIMEOUT | Таймаут (мс) |
OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE | CA-сертификат (PEM) |
OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY | Клиентский ключ (PEM) |
OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE | Клиентский сертификат (PEM) |
OTLP — логирование (per-signal)
| Переменная | Описание |
|---|---|
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT | Адрес коллектора |
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL | Протокол |
OTEL_EXPORTER_OTLP_LOGS_HEADERS | Заголовки |
OTEL_EXPORTER_OTLP_LOGS_COMPRESSION | Сжатие |
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT | Таймаут (мс) |
OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE | CA-сертификат (PEM) |
OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY | Клиентский ключ (PEM) |
OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE | Клиентский сертификат (PEM) |
OTLP — метрики (per-signal)
| Переменная | По умолчанию | Описание |
|---|---|---|
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | — | Адрес коллектора |
OTEL_EXPORTER_OTLP_METRICS_PROTOCOL | — | Протокол |
OTEL_EXPORTER_OTLP_METRICS_HEADERS | — | Заголовки |
OTEL_EXPORTER_OTLP_METRICS_COMPRESSION | — | Сжатие |
OTEL_EXPORTER_OTLP_METRICS_TIMEOUT | — | Таймаут (мс) |
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | cumulative | Временная агрегация: cumulative, delta, lowmemory |
OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION | explicit_bucket_histogram | Агрегация гистограммы: explicit_bucket_histogram, base2_exponential_bucket_histogram |
OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE | — | CA-сертификат (PEM) |
OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY | — | Клиентский ключ (PEM) |
OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE | — | Клиентский сертификат (PEM) |
Семплирование трассировки
| Переменная | Ключ configor | По умолчанию | Описание |
|---|---|---|---|
OTEL_TRACES_SAMPLER | otel.traces.sampler | parentbased_always_on | Стратегия сэмплирования |
OTEL_TRACES_SAMPLER_ARG | otel.traces.sampler.arg | 1.0 | Аргумент сэмплера (доля для traceidratio) |
Поддерживаемые значения OTEL_TRACES_SAMPLER:
| Значение | Описание |
|---|---|
always_on | Сэмплировать все спаны |
always_off | Не сэмплировать ничего |
traceidratio | Случайная доля (задаётся через OTEL_TRACES_SAMPLER_ARG) |
parentbased_always_on | ParentBased(root=AlwaysOn) |
parentbased_always_off | ParentBased(root=AlwaysOff) |
parentbased_traceidratio | ParentBased(root=TraceIdRatio) |
Пакетный процессор спанов (BatchSpanProcessor)
| Переменная | Ключ configor | По умолчанию | Описание |
|---|---|---|---|
OTEL_BSP_MAX_QUEUE_SIZE | otel.bsp.max.queue.size | 2048 | Максимальный размер очереди, целое число больше 0 |
OTEL_BSP_SCHEDULE_DELAY | otel.bsp.schedule.delay | 5000 | Интервал запуска экспорта (мс) |
OTEL_BSP_MAX_EXPORT_BATCH_SIZE | otel.bsp.max.export.batch.size | 512 | Максимальный размер пакета, целое число больше 0, не больше OTEL_BSP_MAX_QUEUE_SIZE |
OTEL_BSP_EXPORT_TIMEOUT | otel.bsp.export.timeout | 30000 | Таймаут экспорта (мс) |
Пакетный процессор логов настраивается аналогичными переменными
OTEL_BLRP_*(ключиotel.blrp.*), значение по умолчаниюOTEL_BLRP_SCHEDULE_DELAY—1000мс. Размер очереди или пакета меньше 1 или дробный записывается в лог предупреждением и заменяется значением по умолчанию. Размер пакета больше размера очереди записывается в лог предупреждением и заменяется размером очереди.
Периодический экспорт метрик
| Переменная | Ключ configor | По умолчанию | Описание |
|---|---|---|---|
OTEL_METRIC_EXPORT_INTERVAL | otel.metric.export.interval | 60000 | Интервал экспорта метрик (мс) |
OTEL_METRIC_EXPORT_TIMEOUT | otel.metric.export.timeout | 30000 | Таймаут одного экспорта метрик (мс) |
OTEL_METRICS_EXEMPLAR_FILTER | otel.metrics.exemplar.filter | trace_based | Фильтр exemplars: always_on, always_off, trace_based |
Пропагаторы контекста
| Переменная | Ключ configor | По умолчанию | Описание |
|---|---|---|---|
OTEL_PROPAGATORS | otel.propagators | tracecontext,baggage | Пропагаторы через запятую |
Поддерживаемые значения:
| Значение | Описание |
|---|---|
tracecontext | W3C Trace Context |
baggage | W3C Baggage |
b3 | B3 Single Header (требуется пакет opentelemetry-propagator-b3) |
b3multi | B3 Multi Header (требуется тот же пакет) |
none | Отключить все пропагаторы; указанные вместе с none значения игнорируются с предупреждением |
Ограничения атрибутов
| Переменная | По умолчанию | Описание |
|---|---|---|
OTEL_ATTRIBUTE_COUNT_LIMIT | 128 | Максимальное число атрибутов (все сигналы) |
OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT | без ограничения | Максимальная длина строкового атрибута |
OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT | наследует OTEL_ATTRIBUTE_COUNT_LIMIT | Переопределение для спанов |
OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT | наследует OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT | Переопределение для спанов |
OTEL_SPAN_EVENT_COUNT_LIMIT | 128 | Максимальное число событий в спане |
OTEL_SPAN_LINK_COUNT_LIMIT | 128 | Максимальное число ссылок в спане |
OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT | 128 | Максимальное число атрибутов события |
OTEL_LINK_ATTRIBUTE_COUNT_LIMIT | 128 | Максимальное число атрибутов ссылки |
OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT | наследует OTEL_ATTRIBUTE_COUNT_LIMIT | Переопределение для записей лога |
OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT | наследует OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT | Переопределение для записей лога |
0 — нулевой лимит, а не отсутствие лимита: атрибуты отбрасываются, строки усекаются до пустых. Лимит длины действует на строки и двоичные данные, в том числе внутри массивов и соответствий. Атрибуты ресурса и метрик лимитами не ограничиваются.
Смотрите также
- Трассировка — ручная настройка провайдера трассировки
- Логирование — ручная настройка провайдера логирования
- Метрики — ручная настройка провайдера метрик
- Экспорт — транспорты и TLS
- Пропагация — пропагаторы контекста
Трассировка
Трассировка позволяет отслеживать цепочку вызовов внутри и между сервисами. Каждая единица работы называется спаном (span). Спаны образуют дерево, корнем которого является корневой спан (root span), а все остальные — дочерние.
Архитектура
ОтелПровайдерТрассировки
└── ОтелТрассировщик
└── ОтелСпан- ОтелПровайдерТрассировки — точка входа, создаёт трассировщики.
- ОтелТрассировщик — создаёт спаны.
- ОтелСпан — единица работы: хранит атрибуты, события, статус, временны́е метки.
Создание провайдера через построитель
ОтелПостроительПровайдераТрассировки предоставляет Fluent API для настройки провайдера.
#Использовать opentelemetry
Ресурс = ОтелРесурсы.ПоУмолчанию();
Ресурс.Атрибуты().Установить("service.name", "my-service");
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318");
Экспортер = Новый ОтелЭкспортерСпанов(Транспорт);
Базовый = Новый ОтелБазовыйПакетныйПроцессор(Экспортер, "traces");
Процессор = Новый ПостроительНаследника(Новый ОтелПакетныйПроцессорСпанов(), Базовый).Построить();
Процессор.ЗапуститьФоновыйЭкспорт();
Провайдер = Новый ОтелПостроительПровайдераТрассировки()
.УстановитьРесурс(Ресурс)
.ДобавитьПроцессор(Процессор)
.Построить();
Трассировщик = Провайдер.ПолучитьТрассировщик("my-library", "1.0.0");Создание спанов
Простой спан
// SpanKind задаётся при создании и неизменен (immutable)
Спан = Трассировщик.НачатьСпан("обработка-запроса", ОтелВидСпана.Сервер());
Область = Спан.СделатьТекущим();
// ... работа ...
Область.Закрыть();
Спан.Завершить();Дочерний спан
НачатьСпан автоматически подхватывает родителя из текущего контекста:
// Родительский спан
Спан = Трассировщик.НачатьСпан("операция", ОтелВидСпана.Сервер());
Область = Спан.СделатьТекущим();
// Дочерний спан — НачатьСпан видит текущий спан как родителя
ДочернийСпан = Трассировщик.НачатьСпан("запрос-к-бд", ОтелВидСпана.Клиент());
ОбластьДочернего = ДочернийСпан.СделатьТекущим();
// ... работа ...
ОбластьДочернего.Закрыть();
ДочернийСпан.Завершить();
Область.Закрыть();
Спан.Завершить();Дочерний спан от явного родителя
// НачатьДочернийСпан принимает контекст (Context) родителя явно
Пропагаторы = ОтелГлобальный.ПолучитьПропагаторы();
НовыйКонтекст = Пропагаторы.Извлечь(ОтелКонтекст.Текущий(), ВходящиеЗаголовки);
Спан = Трассировщик.НачатьДочернийСпан("обработка", НовыйКонтекст, ОтелВидСпана.Сервер());
// Спан-родитель передается в контексте
КонтекстРодителя = ОтелКонтекст.КонтекстСоСпаном(ОтелКонтекст.Текущий(), Спан);
ШагОбработки = Трассировщик.НачатьДочернийСпан("шаг", КонтекстРодителя);Виды спанов (SpanKind)
ОтелВидСпана описывает роль спана в распределённой системе:
| Метод | Описание |
|---|---|
ОтелВидСпана.Внутренний() | Внутренняя операция (по умолчанию) |
ОтелВидСпана.Сервер() | Входящий RPC/HTTP-запрос |
ОтелВидСпана.Клиент() | Исходящий RPC/HTTP-запрос |
ОтелВидСпана.Производитель() | Отправка сообщения в очередь |
ОтелВидСпана.Потребитель() | Получение сообщения из очереди |
Атрибуты
Атрибуты — пары ключ/значение, описывающие контекст операции:
Спан.УстановитьАтрибут("http.method", "GET");
Спан.УстановитьАтрибут("http.url", "/api/data");
Спан.УстановитьАтрибут("http.status_code", 200);
Спан.УстановитьАтрибут("db.rows_affected", 42);События спана
События — именованные точки во времени с атрибутами:
// Простое событие
Спан.ДобавитьСобытие("cache-miss");
// Событие с атрибутами
Атрибуты = Новый ОтелАтрибуты();
Атрибуты.Установить("cache.key", "user:42");
Спан.ДобавитьСобытие("cache-miss", Атрибуты);
// Событие, которое уже произошло: момент засечен раньше
МоментПромаха = ТекущаяУниверсальнаяДатаВМиллисекундах();
// ...
Спан.ДобавитьСобытие("cache-miss", , ОтелУтилиты.МиллисекундыВНаносекунды(МоментПромаха));Время событий и спана — строка с числом наносекунд от начала эпохи Unix, как в OTLP. Строку для своего времени дают функции ОтелУтилиты.
Исключение записывает ЗаписатьИсключение: событие exception с описанием ошибки, модулем и стеком вызовов. Тип ошибки (exception.type) — код библиотеки errors, а у нативной ошибки OneScript без кода — код native-errors, например filesystem.resource.not_found. Статус спана метод не меняет:
Попытка
ПрочитатьНастройки();
Исключение
Спан.ЗаписатьИсключение(ИнформацияОбОшибке());
Спан.УстановитьСтатус(ОтелКодСтатуса.Ошибка(), ОписаниеОшибки());
КонецПопытки;Линки (Links)
Линки связывают спан с другим контекстом (например, асинхронные операции):
КонтекстСпана = ДругойСпан.КонтекстСпана();
Линки = Новый Массив();
Линки.Добавить(Новый ОтелЛинк(КонтекстСпана));
Спан = Трассировщик.НачатьСпан("async-операция", ОтелВидСпана.Внутренний(), , Линки);Статус спана
ОтелКодСтатуса описывает результат операции:
| Метод | Описание |
|---|---|
ОтелКодСтатуса.НеУстановлен() | Статус не задан (по умолчанию) |
ОтелКодСтатуса.Ок() | Операция завершилась успешно |
ОтелКодСтатуса.Ошибка() | Операция завершилась с ошибкой |
// Успешное завершение
Спан.УстановитьСтатус(ОтелКодСтатуса.Ок());
// Ошибка с описанием
Спан.УстановитьСтатус(ОтелКодСтатуса.Ошибка(), "Таймаут подключения к БД");Семплирование
Сэмплер решает, какие спаны записываются и экспортируются. Встроенные сэмплеры создаёт модуль ОтелСэмплер; сэмплер задаётся при создании провайдера или через OTEL_TRACES_SAMPLER. Без настройки используется ParentBased(root=AlwaysOn): корневые спаны сэмплируются все, дочерние наследуют решение родителя.
Провайдер = Новый ОтелПостроительПровайдераТрассировки()
.УстановитьСэмплер(ОтелСэмплер.ВсегдаВключен())
.Построить();// Корневые спаны - 10% трассировок, дочерние наследуют решение родителя
Провайдер = Новый ОтелПостроительПровайдераТрассировки()
.УстановитьСэмплер(ОтелСэмплер.НаОсновеРодителя(ОтелСэмплер.ПоДолеТрассировок(0.1)))
.Построить();# 10% трафика
export OTEL_TRACES_SAMPLER=parentbased_traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.1
# Ничего не записывать
export OTEL_TRACES_SAMPLER=always_offВстроенные сэмплеры:
| Функция | Описание |
|---|---|
ОтелСэмплер.ВсегдаВключен() | AlwaysOn: сэмплировать все спаны |
ОтелСэмплер.ВсегдаВыключен() | AlwaysOff: не сэмплировать ничего |
ОтелСэмплер.ПоДолеТрассировок(Доля) | TraceIdRatioBased: доля трассировок (0.0 – 1.0) по TraceId |
ОтелСэмплер.НаОсновеРодителя(Корневой, ...) | ParentBased: корневые спаны сэмплирует Корневой, дочерние — делегаты для удалённого и локального, сэмплированного и несэмплированного родителя (по умолчанию — решение родителя) |
ОтелСэмплер.ВсегдаЗаписывать(Корневой) | AlwaysRecord: процессоры получают и спаны, отброшенные Корневым, экспортер — только сэмплированные |
Сэмплеры комбинируются, а свой сэмплер — объект с методами ДолженСэмплировать и Описание, см. ИнтерфейсСэмплер.
Процессоры спанов
Простой процессор (для разработки)
Синхронно экспортирует каждый спан сразу после завершения. Подходит для отладки.
Процессор = Новый ОтелПростойПроцессорСпанов(Экспортер);Пакетный процессор (для продакшена)
Накапливает спаны в очереди и отправляет пакетами в фоновом потоке.
Процессор собирается через ПостроительНаследника из ОтелБазовыйПакетныйПроцессор. Базовому процессору передаются экспортер и имя сигнала. Необязательные параметры: размер очереди, размер пакета, интервал экспорта и таймаут экспорта в миллисекундах. Фоновое задание экспорта запускается с первым спаном и отправляет пакет, как только он заполнен или истёк интервал; завершение спана не ждёт отправку. ЗапуститьФоновыйЭкспорт запускает задание заранее (необязательно).
Базовый = Новый ОтелБазовыйПакетныйПроцессор(Экспортер, "traces");
Процессор = Новый ПостроительНаследника(Новый ОтелПакетныйПроцессорСпанов(), Базовый).Построить();
Процессор.ЗапуститьФоновыйЭкспорт();При автоконфигурации параметры задаются переменными окружения:
| Переменная | По умолчанию | Описание |
|---|---|---|
OTEL_BSP_MAX_QUEUE_SIZE | 2048 | Максимальный размер очереди |
OTEL_BSP_SCHEDULE_DELAY | 5000 | Интервал экспорта (мс) |
OTEL_BSP_MAX_EXPORT_BATCH_SIZE | 512 | Максимальный размер пакета |
OTEL_BSP_EXPORT_TIMEOUT | 30000 | Таймаут экспорта (мс) |
Композитный процессор
Объединяет несколько процессоров для одновременной отправки в разные системы:
// ПроцессорGrafana и ПроцессорJaeger — пакетные процессоры, собранные как показано выше
Процессоры = Новый Массив();
Процессоры.Добавить(ПроцессорGrafana);
Процессоры.Добавить(ПроцессорJaeger);
Процессор = Новый ОтелКомпозитныйПроцессорСпанов(Процессоры);Лимиты спана
ОтелЛимитыСпана ограничивают количество атрибутов, событий и ссылок:
Лимиты = Новый ОтелЛимитыСпана()
.УстановитьМаксАтрибутов(64)
.УстановитьМаксСобытий(32);
Провайдер = Новый ОтелПостроительПровайдераТрассировки()
.УстановитьЛимитыСпана(Лимиты)
.Построить();При автоконфигурации лимиты задаются переменными окружения:
| Переменная | По умолчанию | Описание |
|---|---|---|
OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT | 128 | Максимальное число атрибутов спана |
OTEL_SPAN_EVENT_COUNT_LIMIT | 128 | Максимальное число событий |
OTEL_SPAN_LINK_COUNT_LIMIT | 128 | Максимальное число ссылок |
OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT | 128 | Максимальное число атрибутов события |
OTEL_LINK_ATTRIBUTE_COUNT_LIMIT | 128 | Максимальное число атрибутов ссылки |
Завершение работы
// Обязательно закрывайте провайдер для сброса незавершённых спанов
Провайдер.Закрыть();Смотрите также
- Автоконфигурация — настройка через env vars
- Экспорт — транспорты и экспортеры
- Пропагация — передача контекста между сервисами
- API: ОтелСпан
- API: ОтелТрассировщик
- API: ОтелПровайдерТрассировки
Логирование
OpenTelemetry Logs API позволяет собирать структурированные записи логов и экспортировать их в формате OTLP. Логи автоматически коррелируют с трассировкой через контекст — в каждую запись автоматически добавляются TraceId и SpanId текущего активного спана.
Архитектура
ОтелПровайдерЛогирования
└── ОтелЛоггер
└── ОтелЗаписьЛога- ОтелПровайдерЛогирования — точка входа, создаёт логгеры.
- ОтелЛоггер — создаёт и отправляет записи логов.
- ОтелЗаписьЛога — запись с телом, уровнем серьёзности и атрибутами.
Создание провайдера через построитель
#Использовать opentelemetry
Ресурс = ОтелРесурсы.ПоУмолчанию();
Ресурс.Атрибуты().Установить("service.name", "my-service");
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318");
Экспортер = Новый ОтелЭкспортерЛогов(Транспорт);
Базовый = Новый ОтелБазовыйПакетныйПроцессор(Экспортер, "logs", 2048, 512, 1000);
Процессор = Новый ПостроительНаследника(Новый ОтелПакетныйПроцессорЛогов(), Базовый).Построить();
Процессор.ЗапуститьФоновыйЭкспорт();
Провайдер = Новый ОтелПостроительПровайдераЛогирования()
.УстановитьРесурс(Ресурс)
.ДобавитьПроцессор(Процессор)
.Построить();
Логгер = Провайдер.ПолучитьЛоггер("my-library", "1.0.0");Создание записей лога
ОтелЗаписьЛога строится через Fluent API:
Запись = Логгер.СоздатьЗаписьЛога();
Запись.УстановитьТело("Пользователь авторизован")
.УстановитьСерьезность(ОтелСтепеньСерьезности.Info());
Логгер.Записать(Запись);Запись = Логгер.СоздатьЗаписьЛога();
Запись.УстановитьТело("Запрос выполнен")
.УстановитьСерьезность(ОтелСтепеньСерьезности.Info())
.УстановитьАтрибут("user.id", "12345")
.УстановитьАтрибут("http.method", "POST")
.УстановитьАтрибут("http.status_code", 201);
Логгер.Записать(Запись);Попытка
// ... работа ...
Исключение
Запись = Логгер.СоздатьЗаписьЛога();
Запись.УстановитьТело(ОписаниеОшибки())
.УстановитьСерьезность(ОтелСтепеньСерьезности.Error())
.УстановитьИсключение(ИнформацияОбОшибке());
Логгер.Записать(Запись);
КонецПопыткиУстановитьИсключение сохраняет информацию об ошибке, а атрибуты exception.message, exception.stacktrace и exception.type заполняет Логгер.Записать(): до этого вызова в Запись.Атрибуты() их нет. Тип — машинный код ошибки библиотеки errors (ФабрикаОшибок.Создать("config.invalid_port", ...) даст config.invalid_port, код находится и через обертки ФабрикаОшибок). Нативная ошибка OneScript без кода получает код библиотеки native-errors: деление на ноль — numeric.division_by_zero, отказ в соединении — network.connection.refused. У нераспознанной ошибки без кода exception.type не заполняется; явно заданный атрибут записи главнее, и тогда ошибка не классифицируется.
Уровни серьёзности
ОтелСтепеньСерьезности соответствует спецификации OpenTelemetry (числовые значения 1–24). Промежуточные значения уровня (например, 10–12 для INFO) передаются в УстановитьСерьезность числом. Запись без заданной серьезности имеет номер 0 (SEVERITY_NUMBER_UNSPECIFIED) и пустой текст серьезности.
| Метод | Числовое значение | Диапазон уровня | Описание |
|---|---|---|---|
ОтелСтепеньСерьезности.Trace() | 1 | 1–4 | Детальная трассировка |
ОтелСтепеньСерьезности.Debug() | 5 | 5–8 | Отладочная информация |
ОтелСтепеньСерьезности.Info() | 9 | 9–12 | Информационное сообщение |
ОтелСтепеньСерьезности.Warn() | 13 | 13–16 | Предупреждение |
ОтелСтепеньСерьезности.Error() | 17 | 17–20 | Ошибка |
ОтелСтепеньСерьезности.Fatal() | 21 | 21–24 | Критическая ошибка |
Корреляция с трассировкой
Корреляция происходит автоматически. Если в момент записи лога активен спан, его TraceId и SpanId добавляются в запись:
// Трассировка уже инициализирована
Спан = Трассировщик.НачатьСпан("обработка", ОтелВидСпана.Внутренний());
Область = Спан.СделатьТекущим();
// Запись лога автоматически получит TraceId и SpanId из контекста
Запись = Логгер.СоздатьЗаписьЛога();
Запись.УстановитьТело("Начало обработки")
.УстановитьСерьезность(ОтелСтепеньСерьезности.Info());
Логгер.Записать(Запись);
Область.Закрыть();
Спан.Завершить();События и события спана
Событие — запись лога с именем события (УстановитьИмяСобытия). Семантические соглашения записывают исключения событиями: exception или имя операции с суффиксом .exception, например db.client.operation.exception. Чтобы исключение было видно и в трассе, процессор ОтелПроцессорСобытийВСобытияСпана переносит событие в событие текущего спана, если запись относится к этому спану и спан ещё записывается. Запись при этом экспортируется логом как обычно.
Автоконфигурация включает процессор по умолчанию. Выключить его — OTEL_OSCRIPT_EVENT_TO_SPAN_EVENT_BRIDGE_ENABLED=false, например когда бэкенд показывает логи рядом со спаном и дублировать исключение в спане не нужно. Обычные записи без имени события процессор не трогает.
Интеграция с logos
ОтелАппендерLogos перенаправляет все сообщения библиотеки logos в OpenTelemetry. Это позволяет использовать привычный API logos, не меняя код.
#Использовать opentelemetry
#Использовать logos
Ресурс = ОтелРесурсы.ПоУмолчанию();
Ресурс.Атрибуты().Установить("service.name", "my-service");
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318");
Экспортер = Новый ОтелЭкспортерЛогов(Транспорт);
Процессор = Новый ОтелПростойПроцессорЛогов(Экспортер);
Провайдер = Новый ОтелПровайдерЛогирования(Ресурс, Процессор);
ОтелЛоггер = Провайдер.ПолучитьЛоггер("my-library", "1.0.0");
// Создаём аппендер и добавляем его к logos-логу
Аппендер = Новый ОтелАппендерLogos(ОтелЛоггер);
Лог = Логирование.ПолучитьЛог("oscript.app.myapp");
Лог.ДобавитьСпособВывода(Аппендер);
// Теперь все сообщения logos отправляются в OpenTelemetry
Лог.Информация("Приложение запущено");
Лог.Предупреждение("Конфигурация не найдена, используются значения по умолчанию");
Лог.Ошибка("Произошла ошибка: файл не найден");Маппинг уровней logos → ОтелСтепеньСерьезности:
| logos | OTel Severity |
|---|---|
Отладка | Debug |
Информация | Info |
Предупреждение | Warn |
Ошибка | Error |
Процессоры логов
Простой процессор (для разработки)
Процессор = Новый ОтелПростойПроцессорЛогов(Экспортер);Пакетный процессор (для продакшена)
Процессор собирается через ПостроительНаследника из ОтелБазовыйПакетныйПроцессор. Параметры: экспортер, имя сигнала, размер очереди, размер пакета, интервал экспорта (мс). Для сигнала "logs" интервал по умолчанию 1000 мс, как в спецификации; размер пакета больше размера очереди ограничивается размером очереди.
Базовый = Новый ОтелБазовыйПакетныйПроцессор(Экспортер, "logs", 2048, 512, 1000);
Процессор = Новый ПостроительНаследника(Новый ОтелПакетныйПроцессорЛогов(), Базовый).Построить();
Процессор.ЗапуститьФоновыйЭкспорт();При автоконфигурации пакетный процессор логов настраивается переменными
OTEL_BLRP_*:OTEL_BLRP_MAX_QUEUE_SIZE,OTEL_BLRP_SCHEDULE_DELAY(по умолчанию 1000 мс),OTEL_BLRP_MAX_EXPORT_BATCH_SIZE,OTEL_BLRP_EXPORT_TIMEOUT.
Процессор событий в события спана
Переносит события в события текущего спана, см. События и события спана. Ставится перед процессором экспорта:
Процессоры = Новый Массив();
Процессоры.Добавить(Новый ОтелПроцессорСобытийВСобытияСпана());
Процессоры.Добавить(ПакетныйПроцессор);
Процессор = Новый ОтелКомпозитныйПроцессорЛогов(Процессоры);Композитный процессор
// ПакетныйПроцессор — пакетный процессор логов, собранный как показано выше,
// ОтладочныйЭкспортер — второй экспортер логов
Процессоры = Новый Массив();
Процессоры.Добавить(ПакетныйПроцессор);
Процессоры.Добавить(Новый ОтелПростойПроцессорЛогов(ОтладочныйЭкспортер));
Процессор = Новый ОтелКомпозитныйПроцессорЛогов(Процессоры);Смотрите также
- Автоконфигурация — настройка через
OTEL_LOGS_EXPORTER - Трассировка — корреляция логов со спанами
- Экспорт — эндпоинт
/v1/logs - API: ОтелЛоггер
- API: ОтелЗаписьЛога
Метрики
OpenTelemetry Metrics API позволяет измерять числовые характеристики системы: счётчики запросов, время ответа, использование ресурсов и другие показатели. Метрики периодически собираются и экспортируются в формате OTLP.
Архитектура
ОтелПровайдерМетрик
└── ОтелМетр
├── ОтелСчетчик
├── ОтелРеверсивныйСчетчик
├── ОтелДатчик
├── ОтелГистограмма
├── ОтелНаблюдаемыйСчетчик
├── ОтелНаблюдаемыйРеверсивныйСчетчик
└── ОтелНаблюдаемыйДатчикИнструмент записывает измерения в потоки метрик: по потоку на каждого читателя провайдера и на каждое совпавшее представление (View). Поэтому у каждого читателя свои данные: агрегацию, лимит мощности и временную агрегацию (cumulative/delta) задаёт читатель, и сбор одним читателем не сбрасывает данные другого.
Создание провайдера
#Использовать opentelemetry
Ресурс = ОтелРесурсы.ПоУмолчанию();
Ресурс.Атрибуты().Установить("service.name", "my-service");
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318");
Экспортер = Новый ОтелЭкспортерМетрик(Транспорт);
// Периодический читатель — экспортирует каждые 60 секунд
Читатель = Новый ОтелПериодическийЧитательМетрик(Экспортер, 60000);
Читатель.Запустить();
Провайдер = Новый ОтелПостроительПровайдераМетрик()
.УстановитьРесурс(Ресурс)
.ЗарегистрироватьЧитатель(Читатель)
.Построить();
Метр = Провайдер.ПолучитьМетр("my-library", "1.0.0");Синхронные инструменты
Counter (Счётчик)
Монотонно возрастающий счётчик. Используется для подсчёта событий, запросов, байт и т.п.
// Создание
Счетчик = Метр.СоздатьСчетчик("http.requests", "Количество запросов", "1");
// Использование
Счетчик.Добавить(1);
// С атрибутами
Атрибуты = Новый ОтелАтрибуты();
Атрибуты.Установить("http.method", "GET");
Атрибуты.Установить("http.status_code", 200);
Счетчик.Добавить(1, Атрибуты);UpDownCounter (Реверсивный счётчик)
Счётчик, который может как увеличиваться, так и уменьшаться. Используется для очередей, пула соединений.
ОчередьСчетчик = Метр.СоздатьРеверсивныйСчетчик("queue.size", "Размер очереди", "1");
ОчередьСчетчик.Добавить(1); // задача добавлена
ОчередьСчетчик.Добавить(-1); // задача обработанаGauge (Датчик)
Фиксирует последнее измеренное значение. Используется для CPU, памяти, температуры.
Датчик = Метр.СоздатьДатчик("cpu.usage", "Загрузка CPU", "%");
Датчик.Записать(75.5);
// С атрибутами
Атрибуты = Новый ОтелАтрибуты();
Атрибуты.Установить("cpu.core", "0");
Датчик.Записать(62.3, Атрибуты);Histogram (Гистограмма)
Распределяет значения по корзинам. Идеально для времени ответа, размеров запросов.
Гистограмма = Метр.СоздатьГистограмму("http.duration", "Время ответа", "ms");
// Запись измерения
Гистограмма.Записать(150);
// С атрибутами
Атрибуты = Новый ОтелАтрибуты();
Атрибуты.Установить("http.route", "/api/orders");
Гистограмма.Записать(230, Атрибуты);Экспоненциальная гистограмма
Экспоненциальная гистограмма (Base2 Exponential Bucket Histogram) — агрегация инструмента Histogram с автоматическими логарифмическими корзинами, более точная при широком диапазоне значений. Отдельного инструмента для неё в спецификации нет: гистограмма создаётся через СоздатьГистограмму, а агрегация задаётся View или агрегацией гистограмм по умолчанию (default_histogram_aggregation, OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION).
Провайдер.ЗарегистрироватьПредставление(
Новый ОтелСелекторИнструментов("db.query.duration"),
Новый ОтелПредставление(, , , , ОтелАгрегация.ГистограммаЭкспоненциальная()));
Гистограмма = Метр.СоздатьГистограмму("db.query.duration", "Время запроса к БД", "ms");
Гистограмма.Записать(45);Метод СоздатьЭкспоненциальнуюГистограмму из версий 1.x удалён: замените его на СоздатьГистограмму с View, как в примере.
Наблюдаемые (асинхронные) инструменты
Наблюдаемые инструменты вызывают callback-функцию при каждом сборе метрик. Это удобно для измерений, которые дорого получать по запросу.
Callback вызывается при каждом сборе каждым читателем, наблюдения попадают только к этому читателю. Если после фильтра атрибутов представления несколько наблюдений одного сбора попадают в одну серию, они объединяются: у счётчиков значения складываются, у датчика берётся последнее.
Callback выполняется в фоновом задании с таймаутом (по умолчанию 30 секунд): не завершившийся вовремя callback не задерживает сбор, его наблюдения отбрасываются с предупреждением в логе. Фоновое задание OneScript нельзя прервать, поэтому оно продолжает работу, и до его завершения сбор инструмента не начинается: callback-и инструмента должны завершиться до следующего раунда его сбора. Таймаут задаётся для провайдера или метра:
Провайдер.УстановитьТаймаутОбратныхВызововМс(5000);
// 0 — callback-и выполняются в потоке сбора без таймаута
Метр.УстановитьТаймаутОбратныхВызововМс(0);ObservableCounter
// Регистрация callback
Функция ПолучитьОшибки(Наблюдение) Экспорт
// вызывается при каждом сборе метрик
Наблюдение.Записать(ПолучитьКоличествоОшибокИзСистемы());
КонецФункции
НаблСчетчик = Метр.СоздатьНаблюдаемыйСчетчик("process.errors",
Новый Действие(ЭтотОбъект, "ПолучитьОшибки"), "Количество ошибок", "1");ObservableUpDownCounter
Функция ПолучитьРазмерПула(Наблюдение) Экспорт
Наблюдение.Записать(ПулСоединений.Размер());
КонецФункции
НаблРеверсивный = Метр.СоздатьНаблюдаемыйРеверсивныйСчетчик("db.pool.size",
Новый Действие(ЭтотОбъект, "ПолучитьРазмерПула"), "Размер пула", "1");ObservableGauge
Функция ПолучитьПамять(Наблюдение) Экспорт
Наблюдение.Записать(ПолучитьИспользуемуюПамятьМб());
КонецФункции
НаблДатчик = Метр.СоздатьНаблюдаемыйДатчик("process.memory",
Новый Действие(ЭтотОбъект, "ПолучитьПамять"), "Использование памяти", "MB");Периодический читатель метрик
ОтелПериодическийЧитательМетрик запускает фоновый поток, который собирает и экспортирует метрики с заданным интервалом.
// Интервал задаётся в миллисекундах (60000 = 60 секунд)
Читатель = Новый ОтелПериодическийЧитательМетрик(Экспортер, 60000);
Читатель.Запустить();
// ... работа приложения ...
// При завершении — сброс накопленных метрик
Провайдер.Закрыть();Настройка через переменную окружения:
export OTEL_METRIC_EXPORT_INTERVAL=30000 # каждые 30 секунд
export OTEL_METRIC_EXPORT_TIMEOUT=10000 # таймаут одного экспортаТаймаут экспорта и размер пакета можно задать и в коде: при УстановитьМаксРазмерПакетаЭкспорта данные сбора экспортируются пакетами не больше заданного числа точек.
Читатель.УстановитьТаймаутЭкспортаМс(10000);
Читатель.УстановитьМаксРазмерПакетаЭкспорта(1000);Агрегацию и лимит мощности по умолчанию читатель задаёт по виду инструмента — они действуют для потоков, у которых представление не задало свои:
Читатель = Новый ОтелПериодическийЧитательМетрик(Экспортер, 60000);
Читатель.УстановитьАгрегациюПоУмолчанию("UpDownCounter", ОтелАгрегация.Отбросить());
Читатель.УстановитьЛимитМощностиДляВида("Histogram", 500);Читатель Prometheus
ОтелПрометеусЧитательМетрик предоставляет метрики в формате Prometheus для scraping. HTTP-сервера в SDK нет: метрики отдаёт приложение из своего HTTP-обработчика /metrics:
Читатель = Новый ОтелПрометеусЧитательМетрик();
Провайдер = Новый ОтелПостроительПровайдераМетрик()
.УстановитьРесурс(Ресурс)
.ЗарегистрироватьЧитатель(Читатель)
.Построить();
// В HTTP-обработчике /metrics
ТелоОтвета = Читатель.СобратьВТексте();
ТипКонтента = Читатель.ContentType(); // "text/plain; version=0.0.4; charset=utf-8"Читатель переводит метрики OTel в семейства Prometheus, а текст в Prometheus text format 0.0.4 формирует библиотека prometheus. Атрибуты ресурса в лейблы метрик по умолчанию не копируются (УстановитьАтрибутыРесурсаВЛейблах). Читатель можно также зарегистрировать в реестре библиотеки prometheus (Collect) и отдавать реестр, например, через prometheus-metrics. Формат выдачи реестра выбирает библиотека; единицу (# UNIT), время создания серий (_created) и exemplars счётчиков и бакетов гистограмм она выводит только в OpenMetrics. Подробности — в описании читателя.
Представления (Views)
ОтелПредставление позволяет переименовывать инструменты, фильтровать атрибуты и менять агрегацию.
- Каждое представление, выбравшее инструмент, даёт отдельную метрику.
- Настройки представления приоритетнее advisory-параметров инструмента.
- Представление с агрегацией, несовместимой с видом инструмента, игнорируется целиком, в лог пишется предупреждение. Предупреждение пишется и когда представление даёт двум метрикам одно имя — обе экспортируются.
- Представление, зарегистрированное после создания инструмента, действует для измерений, записанных после регистрации.
Exemplars и отфильтрованные атрибуты. Атрибуты, которые представление исключило из потока метрики, всё равно могут экспортироваться в exemplars как
filteredAttributes— так требует спецификация, чтобы exemplar сохранял исходное измерение. Если фильтр атрибутов убирает чувствительные данные, выключите exemplars: фильтромОтелФильтрЭкземпляров.ВсегдаВыключен()(илиOTEL_METRICS_EXEMPLAR_FILTER=always_off) для всего провайдера либо резервуаромОтелФабрикаNoopРезервуаровв параметреРезервуарЭкземпляровпредставления для отдельного потока. С фильтромВсегдаВыключенрезервуары exemplars у серий не создаются вовсе.
// Оставить только нужные атрибуты, убрать чувствительные данные
Селектор = Новый ОтелСелекторИнструментов("http.requests");
РазрешенныеКлючи = Новый Массив();
РазрешенныеКлючи.Добавить("http.method");
РазрешенныеКлючи.Добавить("http.status_code");
Представление = Новый ОтелПредставление(
Неопределено, // НовоеИмя
Неопределено, // НовоеОписание
РазрешенныеКлючи); // РазрешенныеКлючиАтрибутов
Провайдер = Новый ОтелПостроительПровайдераМетрик()
.ЗарегистрироватьПредставление(Селектор, Представление)
.Построить();// Атрибуты, исключенные представлением, могут попасть в exemplars как filteredAttributes.
// Чтобы чувствительные данные не уходили и в exemplars, выключите их сбор:
Провайдер = Новый ОтелПостроительПровайдераМетрик()
.ЗарегистрироватьПредставление(Селектор, Представление)
.УстановитьФильтрЭкземпляров(ОтелФильтрЭкземпляров.ВсегдаВыключен())
.Построить();
// или для отдельного потока: резервуар без exemplars в представлении
// (параметр РезервуарЭкземпляров = Новый ОтелФабрикаNoopРезервуаров())// Использовать экспоненциальную гистограмму вместо явных корзин
Селектор = Новый ОтелСелекторИнструментов("http.duration");
Представление = Новый ОтелПредставление(
Неопределено, // НовоеИмя
Неопределено, // НовоеОписание
Неопределено, // РазрешенныеКлючиАтрибутов
Неопределено, // ГраницыГистограммы
ОтелАгрегация.ГистограммаЭкспоненциальная());
Провайдер = Новый ОтелПостроительПровайдераМетрик()
.ЗарегистрироватьПредставление(Селектор, Представление)
.Построить();Агрегации
ОтелАгрегация определяет, как измерения объединяются в точку данных:
| Метод | Описание |
|---|---|
ОтелАгрегация.ПоУмолчанию() | Агрегация по виду инструмента |
ОтелАгрегация.Сумма() | Сумма всех измерений (Counter, UpDownCounter) |
ОтелАгрегация.ПоследнееЗначение() | Последнее значение (Gauge) |
ОтелАгрегация.ГистограммаСЯвнымиГраницами(Границы, ЗаписыватьМинМакс) | Гистограмма с явными корзинами; без границ - границы по умолчанию; ЗаписыватьМинМакс = Ложь - без min и max |
ОтелАгрегация.ГистограммаЭкспоненциальная(МаксБакетов, МаксШкала, ЗаписыватьМинМакс) | Экспоненциальная гистограмма: до 160 корзин и шкала до 20 по умолчанию |
ОтелАгрегация.Отбросить() | Отбросить измерения (отключить инструмент) |
Временна́я агрегация
ОтелВременнаяАгрегация определяет, как агрегируются данные во времени:
| Значение | Описание |
|---|---|
ОтелВременнаяАгрегация.Кумулятивная() | Накопительные значения с начала работы (по умолчанию) |
ОтелВременнаяАгрегация.Дельта() | Разница за интервал экспорта |
# Настройка через переменную окружения
export OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=deltaOTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | Дельта | Кумулятивная |
|---|---|---|
cumulative | — | все виды |
delta | Counter, ObservableCounter, Histogram, Gauge, ObservableGauge | UpDownCounter, ObservableUpDownCounter |
lowmemory | Counter, Histogram | остальные виды |
Временную агрегацию каждого потока выбирает читатель по виду инструмента.
Смотрите также
- Автоконфигурация — настройка через
OTEL_METRICS_EXPORTER,OTEL_METRIC_EXPORT_INTERVAL - Экспорт — эндпоинт
/v1/metrics - API: ОтелМетр
- API: ОтелПровайдерМетрик
Пропагация контекста
Пропагация контекста — механизм передачи телеметрических данных (trace ID, baggage) через границы сервисов. SDK поддерживает W3C Trace Context, W3C Baggage и B3 (через отдельный пакет).
Что такое пропагация
При каждом вызове между сервисами необходимо передать информацию о текущей трассировке — иначе спаны разных сервисов не будут связаны в единую трассу. Пропагаторы сериализуют контекст в HTTP-заголовки (Inject) и десериализуют обратно (Extract).
Сервис A (Inject) → HTTP-заголовки → Сервис B (Extract)
traceparent: 00-4bf92f3577b34da6...
baggage: userId=alice,env=prodW3C Trace Context
ОтелW3CПропагатор работает с заголовками traceparent и tracestate по стандарту W3C Trace Context.
// Спан уже активен в текущем контексте
Заголовки = Новый Соответствие();
Пропагатор = Новый ОтелW3CПропагатор();
Сеттер = Новый ОтелСеттерТекстовойКарты();
Пропагатор.Внедрить(ОтелКонтекст.Текущий(), Заголовки, Сеттер);
// Заголовки["traceparent"] = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
// Заголовки["tracestate"] = ""Пропагатор = Новый ОтелW3CПропагатор();
Геттер = Новый ОтелГеттерТекстовойКарты();
НовыйКонтекст = Пропагатор.Извлечь(ОтелКонтекст.Текущий(), ВходящиеЗаголовки, Геттер);
// Создание дочернего спана от извлечённого удалённого спана
Спан = Трассировщик.НачатьДочернийСпан("обработка", НовыйКонтекст, ОтелВидСпана.Сервер());W3C Baggage
ОтелW3CBaggageПропагатор передаёт произвольные данные в заголовке baggage по стандарту W3C Baggage.
// Создание baggage: ОтелBaggage неизменяем, Установить возвращает новый экземпляр
Baggage = Новый ОтелBaggage()
.Установить("userId", "alice")
.Установить("env", "production");
// Помещение baggage в контекст
КонтекстСBaggage = ОтелКонтекст.КонтекстСBaggage(ОтелКонтекст.Текущий(), Baggage);
// Внедрение в заголовки
Заголовки = Новый Соответствие();
Пропагатор = Новый ОтелW3CBaggageПропагатор();
Сеттер = Новый ОтелСеттерТекстовойКарты();
Пропагатор.Внедрить(КонтекстСBaggage, Заголовки, Сеттер);
// Заголовки["baggage"] = "userId=alice,env=production"
// Извлечение на стороне получателя
Геттер = Новый ОтелГеттерТекстовойКарты();
НовыйКонтекст = Пропагатор.Извлечь(ОтелКонтекст.Текущий(), ВходящиеЗаголовки, Геттер);
ПолученныйBaggage = ОтелКонтекст.BaggageИзКонтекста(НовыйКонтекст);Композитный пропагатор
ОтелКомпозитныйПропагатор объединяет несколько пропагаторов. Inject и Extract вызываются для каждого из них последовательно.
Список = Новый Массив();
Список.Добавить(Новый ОтелW3CПропагатор());
Список.Добавить(Новый ОтелW3CBaggageПропагатор());
Пропагатор = Новый ОтелКомпозитныйПропагатор(Список);
// Использование через глобальный SDK
ОтелГлобальный.УстановитьПропагаторы(Пропагатор);
// Внедрение всех форматов сразу
Заголовки = Новый Соответствие();
Пропагаторы = ОтелГлобальный.ПолучитьПропагаторы();
Пропагаторы.Внедрить(ОтелКонтекст.Текущий(), Заголовки);
// traceparent + tracestate + baggage — все в одних заголовкахГеттер и сеттер текстовой карты
ОтелГеттерТекстовойКарты и ОтелСеттерТекстовойКарты — адаптеры для работы с Соответствие:
// Сеттер — записывает заголовок в соответствие
Сеттер = Новый ОтелСеттерТекстовойКарты();
// Геттер — читает заголовок из соответствия (регистронезависимо)
Геттер = Новый ОтелГеттерТекстовойКарты();
// Можно реализовать собственный геттер/сеттер для
// нестандартных структур данных (например, заголовки HTTP-запроса)Пропагаторы по умолчанию
Пока пропагаторы не настроены, ОтелГлобальный.ПолучитьПропагаторы() возвращает ОтелНоопПропагатор: по спецификации API использует no-op пропагаторы, пока они не настроены явно. Настроить их можно через ОтелГлобальный.УстановитьПропагаторы(), ОтелПостроительSdk.УстановитьПропагаторы() или автоконфигурацию.
При автоконфигурации ОтелАвтоконфигурация.Инициализировать() автоматически регистрирует пропагаторы, заданные в OTEL_PROPAGATORS (по умолчанию: tracecontext,baggage). Если задан файл конфигурации (OTEL_CONFIG_FILE), OTEL_PROPAGATORS не читается: пропагаторы задаёт секция propagator файла, а без неё пропагация отключена (noop-пропагатор).
// После автоконфигурации — глобальные пропагаторы уже настроены
Сдк = ОтелАвтоконфигурация.Инициализировать();
// Inject/Extract через глобальный доступ
Пропагаторы = ОтелГлобальный.ПолучитьПропагаторы();
Пропагаторы.Внедрить(ОтелКонтекст.Текущий(), Заголовки);B3 пропагатор (отдельный пакет)
Согласно спецификации Propagators Distribution, B3 и Jaeger пропагаторы поставляются отдельными пакетами.
Для поддержки B3 установите пакет opentelemetry-propagator-b3:
opm install opentelemetry-propagator-b3После установки включите B3 через переменную окружения:
# B3 Single Header
export OTEL_PROPAGATORS=tracecontext,baggage,b3
# B3 Multi Header
export OTEL_PROPAGATORS=tracecontext,baggage,b3multiили в файле конфигурации (OTEL_CONFIG_FILE):
propagator:
composite_list: tracecontext,baggage,b3multiБез пакета b3 и b3multi из OTEL_PROPAGATORS пропускаются с предупреждением в логе, а в файле конфигурации — ошибка создания SDK с подсказкой, как установить пакет: SDK не запускается с файлом конфигурации, компонент которого не может создать.
B3 Single Header использует заголовок b3, B3 Multi Header — отдельные заголовки X-B3-TraceId, X-B3-SpanId, X-B3-Sampled.
Настройка через переменные окружения
| Переменная | По умолчанию | Описание |
|---|---|---|
OTEL_PROPAGATORS | tracecontext,baggage | Список пропагаторов через запятую |
Поддерживаемые значения:
| Значение | Пропагатор | Заголовки |
|---|---|---|
tracecontext | ОтелW3CПропагатор | traceparent, tracestate |
baggage | ОтелW3CBaggageПропагатор | baggage |
b3 | B3 Single (пакет opentelemetry-propagator-b3) | b3 |
b3multi | B3 Multi (пакет opentelemetry-propagator-b3) | X-B3-TraceId, X-B3-SpanId, … |
none | — | Отключить все пропагаторы; указанные вместе с none значения игнорируются с предупреждением |
Смотрите также
- Автоконфигурация — настройка
OTEL_PROPAGATORS - Трассировка — создание спанов и контекст
- API: ОтелW3CПропагатор
- API: ОтелКомпозитныйПропагатор
Экспорт данных
SDK поддерживает три транспорта для отправки телеметрии: HTTP (JSON и Protobuf), gRPC и InMemory (для тестов). Все экспортеры работают с любым транспортом — достаточно передать нужный объект транспорта.
Архитектура
Транспорт → Экспортер → Процессор → Провайдер- Транспорт (
ОтелHttpТранспорт,ОтелGrpcТранспорт,ОтелКонсольныйТранспорт,ОтелВПамятьТранспорт) — отвечает за физическую отправку данных. Все попытки отправки и паузы между ними транспорт укладывает в срок, который получает от экспортера. - Экспортер (
ОтелЭкспортерСпанов,ОтелЭкспортерЛогов,ОтелЭкспортерМетрик) — сериализует данные и передаёт транспорту вместе со сроком экспорта: меньшим из таймаута вызова и таймаута экспортера (OTLP Timeout). - Процессор — буферизирует и вызывает экспортер.
HTTP-транспорт
ОтелHttpТранспорт отправляет данные по OTLP/HTTP (порт 4318). Поддерживает два формата: http/protobuf (по умолчанию) и http/json.
Все настройки передаются в конструктор: Новый ОтелHttpТранспорт(Адрес, Заголовки, Таймаут, МаксПопыток, Компрессия, НастройкиTls, Протокол). Таймаут задаётся в секундах.
// Protobuf — бинарный формат, более компактный
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318");Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318", , , , , , "http/json");Заголовки = Новый Соответствие();
Заголовки.Вставить("Authorization", "Bearer my-token");
Заголовки.Вставить("X-Team", "backend");
Транспорт = Новый ОтелHttpТранспорт("https://otel-collector:4318", Заголовки, 15); // 15 секундТранспорт = Новый Отел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
#Использовать 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).
Заголовки = Новый Соответствие();
Заголовки.Вставить("User-Agent", "MyDistribution/1.2.3");
// User-Agent: MyDistribution/1.2.3 OTel-OTLP-Exporter-OneScript/<версия>
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318", Заголовки)
.УстановитьМаксРазмерЗапроса(16777216);Консольный транспорт
ОтелКонсольныйТранспорт выводит каждую отправку одной строкой OTLP JSON в стандартный вывод — для отладки и локальной разработки. Это экспортер console файла конфигурации.
Экспортер = Новый ОтелЭкспортерСпанов(Новый ОтелКонсольныйТранспорт());InMemory-транспорт (для тестов)
ОтелВПамятьТранспорт сохраняет сериализованные данные в памяти. Используется в тестах для проверки экспортируемых данных без реальной сети.
Транспорт = Новый ОтелВПамятьТранспорт();
Экспортер = Новый ОтелЭкспортерСпанов(Транспорт);
Процессор = Новый ОтелПростойПроцессорСпанов(Экспортер);
Провайдер = Новый ОтелПровайдерТрассировки(Ресурс, Процессор);
Трассировщик = Провайдер.ПолучитьТрассировщик("test");
// Работа
Спан = Трассировщик.НачатьСпан("тест", ОтелВидСпана.Внутренний());
Спан.Завершить();
// Проверка экспортированных данных
Отправки = Транспорт.ПолучитьОтправленные();
// Отправки — массив соответствий с ключами "Путь" и "Данные" (сериализованный OTLP-пакет)TLS
ОтелНастройкиTls хранит настройки TLS в полях ФайлСертификата, ФайлКлиентскогоКлюча, ФайлКлиентскогоСертификата и Insecure. Настройки передаются в конструктор транспорта.
Настройки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_INSECURE | true — 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) |
| Protocol | http/protobuf, http/json | grpc |
Неприменяемая опция не теряется молча: транспорт или автоконфигурация пишут предупреждение в лог. Причины — ограничения платформы и библиотек:
- 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).
Полные примеры
Трассировка + Логирование + Метрики
#Использовать opentelemetry
Ресурс = ОтелРесурсы.ПоУмолчанию();
Ресурс.Атрибуты().Установить("service.name", "my-service");
// Один транспорт для всех сигналов
Транспорт = Новый ОтелHttpТранспорт("http://otel-collector:4318");
// Трассировка
ЭкспортерСпанов = Новый ОтелЭкспортерСпанов(Транспорт);
БазовыйСпанов = Новый ОтелБазовыйПакетныйПроцессор(ЭкспортерСпанов, "traces");
ПроцессорСпанов = Новый ПостроительНаследника(Новый ОтелПакетныйПроцессорСпанов(), БазовыйСпанов).Построить();
ПроцессорСпанов.ЗапуститьФоновыйЭкспорт();
ПровайдерТрассировки = Новый ОтелПровайдерТрассировки(Ресурс, ПроцессорСпанов);
// Логирование
ЭкспортерЛогов = Новый ОтелЭкспортерЛогов(Транспорт);
БазовыйЛогов = Новый ОтелБазовыйПакетныйПроцессор(ЭкспортерЛогов, "logs", 2048, 512, 1000);
ПроцессорЛогов = Новый ПостроительНаследника(Новый ОтелПакетныйПроцессорЛогов(), БазовыйЛогов).Построить();
ПроцессорЛогов.ЗапуститьФоновыйЭкспорт();
ПровайдерЛогирования = Новый ОтелПровайдерЛогирования(Ресурс, ПроцессорЛогов);
// Метрики
ЭкспортерМетрик = Новый ОтелЭкспортерМетрик(Транспорт);
Читатель = Новый ОтелПериодическийЧитательМетрик(ЭкспортерМетрик, 60000);
Читатель.Запустить();
ПровайдерМетрик = Новый ОтелПровайдерМетрик(Ресурс, Читатель);
// Завершение — сбрасывает все буферы
ПровайдерТрассировки.Закрыть();
ПровайдерЛогирования.Закрыть();
ПровайдерМетрик.Закрыть();gRPC для всех сигналов
#Использовать opentelemetry
Ресурс = ОтелРесурсы.ПоУмолчанию();
Ресурс.Атрибуты().Установить("service.name", "my-service");
// gRPC-транспорт
Транспорт = Новый ОтелGrpcТранспорт("http://otel-collector:4317");
// Трассировка
ЭкспортерСпанов = Новый ОтелЭкспортерСпанов(Транспорт);
Базовый = Новый ОтелБазовыйПакетныйПроцессор(ЭкспортерСпанов, "traces");
ПроцессорСпанов = Новый ПостроительНаследника(Новый ОтелПакетныйПроцессорСпанов(), Базовый).Построить();
ПроцессорСпанов.ЗапуститьФоновыйЭкспорт();
Провайдер = Новый ОтелПровайдерТрассировки(Ресурс, ПроцессорСпанов);
Трассировщик = Провайдер.ПолучитьТрассировщик("my-library");
Спан = Трассировщик.НачатьСпан("операция", ОтелВидСпана.Сервер());
Область = Спан.СделатьТекущим();
// ... работа ...
Область.Закрыть();
Спан.Завершить();
Провайдер.Закрыть();Смотрите также
- Автоконфигурация — настройка через
OTEL_EXPORTER_OTLP_* - Трассировка — экспортер спанов
- Логирование — экспортер логов
- Метрики — экспортер метрик
- API: ОтелHttpТранспорт
- API: ОтелGrpcТранспорт
Семантические соглашения
Какие атрибуты семантических соглашений OpenTelemetry заполняет SDK. В таблицах — stable-атрибуты semconv (версия 1.44.0); атрибуты в статусах development и release candidate отмечены отдельно. Группы атрибутов названы так же, как в semconv.
Ресурс
Автоконфигурация через переменные окружения и файловая конфигурация собирают ресурс SDK из ресурса по умолчанию и атрибутов детекторов (ОтелРесурсы). Атрибуты детекторов ресурса описаны схемой https://opentelemetry.io/schemas/1.44.0. Провайдер, которому ресурс не передан, получает только ресурс по умолчанию: service.name и telemetry.sdk.*.
Service
| Атрибут | Значение |
|---|---|
service.name | unknown_service:oscript, если имя не задано через OTEL_SERVICE_NAME, OTEL_RESOURCE_ATTRIBUTES или resource файловой конфигурации |
Service Instance
| Атрибут | Значение |
|---|---|
service.instance.id | детектор ОтелДетекторРесурсаЭкземпляраСервиса: случайный UUID, один на процесс, если значение не задано через OTEL_RESOURCE_ATTRIBUTES или resource файловой конфигурации |
Telemetry Sdk
| Атрибут | Значение |
|---|---|
telemetry.sdk.language | oscript |
telemetry.sdk.name | oscript-opentelemetry: значение opentelemetry по semconv зарезервировано за официальным SDK проекта OpenTelemetry |
telemetry.sdk.version | версия пакета |
Container
| Атрибут | Значение |
|---|---|
container.id | детектор ОтелДетекторРесурсаКонтейнера: только на Linux и только в контейнере |
Атрибуты в статусах development и release candidate
Атрибуты, которые заполняют детекторы ресурса по умолчанию. Атрибуты Process — в статусе release candidate, остальные — development.
Host
| Атрибут | Детектор |
|---|---|
host.arch | ОтелДетекторРесурсаПроцессора |
host.name | ОтелДетекторРесурсаХоста |
Host CPU
| Атрибут | Детектор |
|---|---|
host.cpu.model.name | ОтелДетекторРесурсаПроцессора |
OS
| Атрибут | Детектор |
|---|---|
os.type | ОтелДетекторРесурсаХоста |
Process
| Атрибут | Детектор |
|---|---|
process.pid | ОтелДетекторРесурсаПроцесса |
Исключения
ОтелСпан.ЗаписатьИсключение и запись лога с исключением (ОтелЗаписьЛога) заполняют атрибуты исключения:
| Атрибут | Значение |
|---|---|
exception.message | описание ошибки |
exception.type | код ошибки библиотеки errors или код нативной ошибки OneScript (native-errors); у нераспознанной ошибки не заполняется |
exception.stacktrace | стек вызовов |
Error
| Атрибут | Кто заполняет |
|---|---|
error.type | библиотеки инструментирования в спанах и метриках: значение ОтелУтилиты.ТипОшибки — тип ошибки или _OTHER |
