Opentelemetry
OpenTelemetry SDK для OneScript
Install / Use
/learn @nixel2007/OpentelemetryREADME
OpenTelemetry SDK для OneScript
Библиотека на OneScript для использования OpenTelemetry в оскриптовых проектах.
Позволяет собирать и отправлять телеметрию (трассировку, логи, метрики) в формате OTLP в любой совместимый коллектор - Grafana LGTM, OpenTelemetry Collector и другие. Поддерживает два транспорта: HTTP JSON и gRPC.
Возможности
- Автоконфигурация - настройка SDK из переменных окружения или файла конфигурации (через configor)
- Трассировка - спаны, вложенные спаны, атрибуты, события, линки, статусы, семплирование
- Логирование - записи логов с уровнями серьезности и корреляцией с трассировкой
- Метрики - счетчики, реверсивные счетчики, датчики, гистограммы, экспоненциальные гистограммы, наблюдаемые инструменты
- Контекст - thread-safe implicit context propagation для автоматического наследования родительских спанов
- W3C Trace Context - внедрение и извлечение
traceparent/tracestateHTTP-заголовков - W3C Baggage - пропагация baggage через HTTP-заголовки
- Пакетная обработка - batch-процессоры для спанов и логов с фоновым экспортом
- Периодический экспорт метрик - автоматический сбор и отправка метрик по расписанию
- Экспорт по OTLP/HTTP - отправка данных в формате JSON на эндпоинты
/v1/traces,/v1/logs,/v1/metrics - Экспорт по OTLP/gRPC - отправка данных через gRPC с помощью библиотеки oint (OPI_GRPC)
- Интеграция с logos - аппендер для библиотеки logos, перенаправляющий логи в OpenTelemetry
- Централизованный SDK - единый объект
ОтелSdkдля доступа ко всем провайдерам
Установка
opm install opentelemetry
Быстрый старт
Автоконфигурация (рекомендуемый способ)
Самый простой способ настроить OpenTelemetry - через автоконфигурацию. Модуль ОтелАвтоконфигурация читает переменные окружения и/или файл конфигурации, создает все необходимые провайдеры и регистрирует SDK глобально.
#Использовать opentelemetry
// Автоконфигурация из переменных окружения
Сдк = ОтелАвтоконфигурация.Инициализировать();
// Получение трассировщика и метра
Трассировщик = Сдк.ПолучитьТрассировщик("my-library");
Метр = Сдк.ПолучитьМетр("my-library");
// Работа с трассировкой
Спан = Трассировщик.НачатьСпан("операция", ОтелВидСпана.Сервер());
Область = Спан.СделатьТекущим();
// ... работа ...
Область.Закрыть();
Спан.Завершить();
// Или через глобальный доступ в любом месте кода
Трассировщик = ОтелГлобальный.ПолучитьТрассировщик("другая-библиотека");
Переменные окружения:
export OTEL_SERVICE_NAME=my-service
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_EXPORTER_OTLP_PROTOCOL=http/json # или grpc
Или через файл конфигурации (configor):
{
"otel": {
"service": { "name": "my-service" },
"exporter": {
"otlp": {
"endpoint": "http://localhost:4318",
"protocol": "http/json"
}
}
}
}
Ручная настройка: Трассировка
#Использовать opentelemetry
Ресурс = Новый ОтелРесурс();
Ресурс.Атрибуты().Установить("service.name", "my-service");
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318");
Экспортер = Новый ОтелЭкспортерСпанов(Транспорт);
Процессор = Новый ОтелПростойПроцессорСпанов(Экспортер);
Провайдер = Новый ОтелПровайдерТрассировки(Ресурс, Процессор);
Трассировщик = Провайдер.ПолучитьТрассировщик("my-library", "1.0.0");
// Создание спана (SpanKind задается при создании - immutable)
Спан = Трассировщик.НачатьСпан("обработка-запроса", ОтелВидСпана.Сервер());
Область = Спан.СделатьТекущим();
Спан.УстановитьАтрибут("http.method", "GET");
Спан.УстановитьАтрибут("http.url", "/api/data");
// Дочерний спан - НачатьСпан автоматически берет родителя из контекста
ДочернийСпан = Трассировщик.НачатьСпан("запрос-к-бд", ОтелВидСпана.Клиент());
ОбластьДочернего = ДочернийСпан.СделатьТекущим();
// ... выполнение работы ...
ДочернийСпан.УстановитьСтатус(ОтелКодСтатуса.Ок());
ОбластьДочернего.Закрыть();
ДочернийСпан.Завершить();
Спан.УстановитьСтатус(ОтелКодСтатуса.Ок());
Область.Закрыть();
Спан.Завершить();
Провайдер.Закрыть();
Ручная настройка: Логирование
#Использовать opentelemetry
Ресурс = Новый ОтелРесурс();
Ресурс.Атрибуты().Установить("service.name", "my-service");
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318");
Экспортер = Новый ОтелЭкспортерЛогов(Транспорт);
Процессор = Новый ОтелПростойПроцессорЛогов(Экспортер);
Провайдер = Новый ОтелПровайдерЛогирования(Ресурс, Процессор);
Логгер = Провайдер.ПолучитьЛоггер("my-library", "1.0.0");
Запись = Логгер.СоздатьЗаписьЛога();
Запись.УстановитьТело("Пользователь авторизован")
.УстановитьСерьезность(ОтелСтепеньСерьезности.Info())
.УстановитьАтрибут("user.id", "12345");
Логгер.Записать(Запись);
Ручная настройка: Метрики
#Использовать opentelemetry
Ресурс = Новый ОтелРесурс();
Ресурс.Атрибуты().Установить("service.name", "my-service");
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318");
Экспортер = Новый ОтелЭкспортерМетрик(Транспорт);
Читатель = Новый ОтелПериодическийЧитательМетрик(Экспортер, 60000);
Читатель.Запустить();
Провайдер = Новый ОтелПровайдерМетрик(Ресурс, Читатель);
Метр = Провайдер.ПолучитьМетр("my-library", "1.0.0");
// Счетчик
Счетчик = Метр.СоздатьСчетчик("http.requests", "Количество запросов", "1");
Счетчик.Добавить(1);
// Гистограмма
Гистограмма = Метр.СоздатьГистограмму("http.duration", "Время ответа", "ms");
Гистограмма.Записать(150);
// Реверсивный счетчик (UpDownCounter)
ОчередьСчетчик = Метр.СоздатьРеверсивныйСчетчик("queue.size", "Размер очереди", "1");
ОчередьСчетчик.Добавить(1); // добавлен элемент
ОчередьСчетчик.Добавить(-1); // элемент обработан
// Датчик (Gauge)
Датчик = Метр.СоздатьДатчик("cpu.usage", "Загрузка CPU", "%");
Датчик.Записать(75.5);
W3C Trace Context
#Использовать opentelemetry
// Внедрение контекста в исходящий HTTP-запрос
Спан = Трассировщик.НачатьСпан("http-запрос", ОтелВидСпана.Клиент());
Область = Трассировщик.НачатьОбласть(Спан);
Заголовки = Новый Соответствие();
Пропагаторы = ОтелГлобальный.ПолучитьПропагаторы();
Пропагаторы.Внедрить(ОтелКонтекст.Текущий(), Заголовки);
// Заголовки теперь содержат "traceparent", "tracestate" и "baggage"
Область.Закрыть();
Спан.Завершить();
// Извлечение контекста из входящего запроса
НовыйКонтекст = Пропагаторы.Извлечь(ОтелКонтекст.Текущий(), ВходящиеЗаголовки);
Спан = Трассировщик.НачатьСпан("обработка", ОтелВидСпана.Сервер(), НовыйКонтекст);
Использование gRPC-транспорта
Все экспортеры работают с обоими транспортами. Достаточно заменить ОтелHttpТранспорт на ОтелGrpcТранспорт:
#Использовать opentelemetry
// gRPC-транспорт - порт 4317 (стандартный OTLP gRPC)
Транспорт = Новый ОтелGrpcТранспорт("http://localhost:4317");
Экспортер = Новый ОтелЭкспортерСпанов(Транспорт);
Процессор = Новый ОтелПростойПроцессорСпанов(Экспортер);
Ресурс = Новый ОтелРесурс();
Ресурс.Атрибуты().Установить("service.name", "my-service");
Провайдер = Новый ОтелПровайдерТрассировки(Ресурс, Процессор);
Трассировщик = Провайдер.ПолучитьТрассировщик("my-library", "1.0.0");
Спан = Трассировщик.НачатьСпан("операция", ОтелВидСпана.Сервер());
Область = Спан.СделатьТекущим();
// ... работа ...
Область.Закрыть();
Спан.Завершить();
Провайдер.Закрыть();
Интеграция с logos
#Использовать opentelemetry
#Использовать logos
Ресурс = Новый ОтелРесурс();
Ресурс.Атрибуты().Установить("service.name", "my-service");
Транспорт = Новый ОтелHttpТранспорт("http://localhost:4318");
Экспортер = Новый ОтелЭкспортерЛогов(Транспорт);
Процессор = Новый ОтелПростойПроцессорЛогов(Экспортер);
Провайдер = Новый ОтелПровайдерЛогирования(Ресурс, Процессор);
ОтелЛоггер = Провайдер.ПолучитьЛоггер("my-library", "1.0.0");
Аппендер = Новый ОтелАппендерLogos(ОтелЛоггер);
Лог = Логирование.ПолучитьЛог("oscript.app.myapp");
Лог.ДобавитьСпособВывода(Аппендер);
// Теперь все сообщения logos автоматически отправляются в OpenTelemetry
Лог.Информация("Приложение запущено");
Лог.Ошибка("Произошла ошибка: файл не найден");
Автоконфигурация
Модуль ОтелАвтоконфигурация следует спецификации переменных окружения OpenTelemetry и читает стандартные параметры OpenTelemetry.
Параметры могут задаваться через переменные окружения (OTEL_*) или через менеджер параметров configor (файл конфигурации, программное создание). Переменные окружения преобразуются в ключи configor с заменой _ на . и приведением к ни
