autumn-opentelemetry
autumn-opentelemetry — интеграция OpenTelemetry SDK с Autumn Framework.
Библиотека предоставляет аннотации для автоматической инструментации методов трассировкой, метриками и счётчиками, а также мост между логгером logos и OTel Logs API.
Установка
opm install autumn-opentelemetryСовместимость
- OneScript 2.2.0+
- opentelemetry >= 1.1.0
- autumn >= 4.3.12
Быстрый старт
1. Подключение к приложению
autumn-opentelemetry подключается к приложению Autumn автоматически — достаточно добавить #Использовать autumn-opentelemetry:
#Использовать autumn
#Использовать autumn-opentelemetry
Поделка = Новый Поделка();
Поделка.ЗапуститьПриложение();2. Минимальная конфигурация
otel.enabled и otel.service.name — обязательные параметры:
{
"otel": {
"enabled": true,
"service": {
"name": "my-service"
}
}
}3. Инструментация методов
&Желудь
&Наблюдаемый
Процедура ПриСозданииОбъекта()
КонецПроцедуры
&Подсчитываемый("orders.processed")
&Замеряемый("orders.duration")
Функция ОбработатьЗаказ(&АтрибутСпана("order.id") ИдЗаказа) Экспорт
// span с атрибутом order.id = ИдЗаказа
// длительность в гистограмме orders.duration
// счётчик orders.processed инкрементируется
Возврат СформироватьОтвет(ИдЗаказа);
КонецФункцииОсновные возможности
ОтелДуб автоматически:
- Инициализирует OpenTelemetry SDK через параметры приложения
- Регистрирует желуди
ОтелSdk,ОтелТрассировщик,ОтелМетр - Создаёт и регистрирует аппендер
ОтелАппендерLogosдля экспорта логов
Аннотации доступны для любого &Желудь:
| Аннотация | Описание |
|---|---|
&Наблюдаемый | Создаёт span OpenTelemetry вокруг метода |
&Замеряемый | Записывает длительность вызова в гистограмму |
&Подсчитываемый | Инкрементирует счётчик при каждом вызове |
&АтрибутСпана | Добавляет параметр метода как атрибут span'а |
Дальнейшее изучение
Руководство пользователя
- Конфигурация — параметры OpenTelemetry и логирования
- Аннотации — подробное описание аннотаций с примерами
- Семантические соглашения — атрибуты semconv в ресурсе, спанах и метриках
Справочник API
Конфигурация
Обязательные параметры
Два параметра обязательны для запуска SDK:
| Параметр | Описание |
|---|---|
otel.enabled | Включает инструментирование аннотациями и экспорт логов. При false напильники возвращают желуди без изменений, аппендер ОтелАппендерLogos ничего не пишет, SDK не инициализируется и экспортёры не запускаются. |
otel.service.name | Имя сервиса в телеметрии. |
{
"otel": {
"enabled": true,
"service": {
"name": "my-service"
}
}
}OTEL_ENABLED=true
OTEL_SERVICE_NAME=my-serviceЭкспорт телеметрии
По умолчанию SDK экспортирует трассы, метрики и логи по адресу http://localhost:4318 (протокол http/protobuf).
{
"otel": {
"enabled": true,
"service": {
"name": "my-service"
},
"exporter": {
"otlp": {
"endpoint": "http://localhost:4318",
"protocol": "http/protobuf"
}
},
"traces": { "exporter": "otlp" },
"metrics": { "exporter": "otlp" },
"logs": { "exporter": "otlp" }
}
}Чтобы отключить SDK полностью:
{
"otel": {
"sdk": {
"disabled": true
}
}
}Полный список параметров OpenTelemetry — в документации opentelemetry SDK.
Ресурс
Ресурс — атрибуты, которые SDK прикладывает ко всей телеметрии сервиса. ОтелSdk собирает его в таком порядке, каждый следующий источник важнее предыдущего:
- Атрибуты по умолчанию и встроенные детекторы ядра opentelemetry.
- Детекторы ресурса приложения — желуди с прозвищем
ДетекторРесурса, в порядке&Порядокпо возрастанию. При совпадении ключей важнее детектор с большим&Порядок. - Переменные окружения
OTEL_RESOURCE_ATTRIBUTESиOTEL_SERVICE_NAME, затем параметрыotel.resource.attributesиotel.service.name.
autumn-opentelemetry сам содержит такой детектор — желудь ОтелДетекторРесурсаДистрибутива. Он добавляет атрибуты telemetry.distro.name = autumn-opentelemetry и telemetry.distro.version с версией пакета.
Свой детектор — желудь с прозвищем ДетекторРесурса:
#Использовать opentelemetry
Функция Обнаружить() Экспорт
Атрибуты = Новый Соответствие();
Атрибуты.Вставить("deployment.environment.name", "production");
Возврат Новый ОтелРесурс(Атрибуты);
КонецФункции
&Желудь
&Прозвище("ДетекторРесурса")
&Спецификация("Инициализация")
&Реализует("ИнтерфейсДетекторРесурса")
Процедура ПриСозданииОбъекта()
КонецПроцедуры&Спецификация("Инициализация")обязательна: SDK создаётся на этапе инициализации приложения, и желудь без неё на этом этапе не создаётся.&Реализует("ИнтерфейсДетекторРесурса")обязательна: без неё ядро не примет детектор и выбросит исключение.- Детектор, который завершился с ошибкой, ядро пропускает и пишет ошибку в лог.
При файловой конфигурации SDK (otel.config.file) ресурс задаётся в файле, и детекторы не применяются.
Инструментирование entity
Параметры otel.entity.enabled, otel.entity.query-text и otel.entity.repository.enabled управляют трассировкой и метриками работы с базой данных через autumn-data. Признаки включения по умолчанию наследуют otel.enabled, текст запроса по умолчанию не пишется. Подробнее - в разделе Инструментирование entity.
Конфигурация логирования
ОтелДуб автоматически создаёт желудь ОтелАппендерLogos и регистрирует его в logos. При otel.enabled = false аппендер создаётся без OTel-логгера и отбрасывает события, поэтому конфигурацию logos с ним можно не менять при выключении телеметрии. Для настройки уровня экспортируемых логов используйте autumn-properties.json:
{
"logos": {
"logger": {
"rootLogger": {
"level": "INFO",
"appenders": ["otel", "console"]
}
},
"appender": {
"otel": {
"type": "ОтелАппендерLogos",
"level": "WARN"
},
"console": {
"type": "ВыводЛогаВКонсоль",
"level": "INFO"
}
}
}
}Аннотации
&Наблюдаемый — трассировка методов
Автоматически создаёт span OpenTelemetry вокруг вызовов метода.
Размещение на отдельном методе инструментирует только его:
&Желудь
Процедура ПриСозданииОбъекта()
КонецПроцедуры
&Наблюдаемый("orders.process")
Функция ОбработатьЗаказ(ИдЗаказа) Экспорт
Возврат СформироватьОтвет(ИдЗаказа);
КонецФункцииРазмещение на конструкторе инструментирует все экспортные методы желудя, включая добавленные декоратором:
&Желудь
&Наблюдаемый
Процедура ПриСозданииОбъекта()
КонецПроцедуры
Функция ОбработатьЗаказ(ИдЗаказа) Экспорт
Возврат СформироватьОтвет(ИдЗаказа);
КонецФункцииПараметры аннотации:
| Параметр | По умолчанию | Описание |
|---|---|---|
Значение | "ИмяЖелудя.ИмяМетода" | Имя span'а |
ВидСпана | internal | Вид span'а: internal, server, client, producer, consumer |
Если из метода вышло исключение, span получает статус Error с текстом исключения и атрибут error.type, а само исключение записывается записью лога с событием exception в контексте span'а. Серьёзность записи — ERROR у span'ов server и consumer, WARN у остальных: исключение уходит в вызывающий код, который может его обработать. Процессор событий ядра, включённый в автоконфигурации по умолчанию, переносит запись в событие span'а. Исключение доходит до вызывающего кода как обычно.
Пример с явным видом спана:
&Желудь
&Наблюдаемый(ВидСпана = "server")
Процедура ПриСозданииОбъекта()
КонецПроцедуры&АтрибутСпана — атрибуты параметров
Добавляет значение параметра метода как атрибут текущего span'а. Используется совместно с &Наблюдаемый:
&Наблюдаемый
Функция ОбработатьЗаказ(&АтрибутСпана("order.id") ИдЗаказа, Данные) Экспорт
// span получит атрибут order.id = значение ИдЗаказа
Возврат СформироватьОтвет(ИдЗаказа);
КонецФункцииЕсли Значение не указано — в качестве ключа атрибута используется имя параметра:
&АтрибутСпана // ключ = "ИдЗаказа"
&АтрибутСпана("order.id") // ключ = "order.id"&Замеряемый — измерение длительности
Записывает длительность каждого вызова метода в гистограмму OTel в секундах, как требуют семантические соглашения для гистограмм длительности. До версии 1.1.0 длительность писалась в миллисекундах.
Атрибуты гистограммы: code.function.name (полное имя метода ИмяЖелудя.ИмяМетода), error.type (при ошибке: код ошибки, код нативной ошибки OneScript или _OTHER).
&Желудь
Процедура ПриСозданииОбъекта()
КонецПроцедуры
&Замеряемый("payments.process.duration")
Функция ОбработатьПлатёж(Данные) Экспорт
Возврат ПровестиПлатёж(Данные);
КонецФункцииРазмещение на конструкторе инструментирует все экспортные методы желудя, включая добавленные декоратором:
&Желудь
&Замеряемый
Процедура ПриСозданииОбъекта()
КонецПроцедурыПараметры аннотации:
| Параметр | По умолчанию | Описание |
|---|---|---|
Значение | "ИмяЖелудя.ИмяМетода.duration" | Имя метрики (должно быть ASCII) |
Имена методов на кириллице транслитерируются автоматически.
&Подсчитываемый — счётчик вызовов
Инкрементирует счётчик OTel при каждом вызове метода.
Атрибуты счётчика: code.function.name (полное имя метода ИмяЖелудя.ИмяМетода), error.type (при ошибке: код ошибки, код нативной ошибки OneScript или _OTHER). Успешные вызовы — точки без error.type.
&Желудь
Процедура ПриСозданииОбъекта()
КонецПроцедуры
&Подсчитываемый("api.requests")
Функция ОбработатьЗапрос(Запрос) Экспорт
Возврат СформироватьОтвет(Запрос);
КонецФункцииРазмещение на конструкторе инструментирует все экспортные методы желудя, включая добавленные декоратором:
&Желудь
&Подсчитываемый
Процедура ПриСозданииОбъекта()
КонецПроцедурыПараметры аннотации:
| Параметр | По умолчанию | Описание |
|---|---|---|
Значение | "ИмяЖелудя.ИмяМетода.counted" | Имя метрики (должно быть ASCII) |
Имена методов на кириллице транслитерируются автоматически.
Комбинирование аннотаций
Аннотации можно комбинировать на одном методе:
&Желудь
Процедура ПриСозданииОбъекта()
КонецПроцедуры
&Наблюдаемый("orders.process")
&Замеряемый("orders.duration")
&Подсчитываемый("orders.count")
Функция ОбработатьЗаказ(&АтрибутСпана("order.id") ИдЗаказа) Экспорт
Возврат СформироватьОтвет(ИдЗаказа);
КонецФункцииМетоды, добавленные декоратором
Желудь редко доезжает до напильника тем же объектом, каким его объявили: хранилища сущностей autumn-data, наследники из extends, обёртки предыдущих напильников - всё это декораторы, и методов у собранного экземпляра больше, чем в модуле его типа.
Напильники рефлексируют по самому экземпляру, а не по типу, и аннотации читают оттуда же. Поэтому метод, пришедший с декоратором, инструментируется наравне с методами самого желудя, а аннотация на нём задаёт своё имя спана или метрики, вид спана и атрибуты параметров. Аннотация на конструкторе для этого не нужна - метод инструментируется и без неё.
Пример с наследником: ПостроительНаследника собирает декоратор, в который переносит и методы родителя, и их аннотации.
&Замеряемый("orders.load.duration")
Функция ЗагрузитьЗаказ(ИдЗаказа) Экспорт
Возврат Прочитать(ИдЗаказа);
КонецФункции#Использовать extends
&Желудь
&Расширяет("БазовыйСервис")
Процедура ПриСозданииОбъекта()
КонецПроцедурыЗагрузитьЗаказ попадёт в метрику orders.load.duration, хотя в модуле СервисЗаказов этого метода нет и определение желудя о нём не знает.
Инструментирование entity
Приложение на autumn-data получает трассировку и метрики работы с базой данных без единой строки прикладного кода: операции менеджера сущностей, запросы к СУБД, соединения, транзакции и вызовы хранилищ становятся спанами и метриками OpenTelemetry. Устроено как в Spring: слой данных инструментируется наблюдателем ORM, слой репозиториев - метрикой вокруг желудей.
Как это работает
ОтелДубобъявляет завязьОтелНаблюдательИсточникаДанныхс прозвищемНаблюдательИсточникаДанных- наблюдатель из библиотеки opentelemetry-instrumentation-entity.autumn-dataрегистрирует все желуди с этим прозвищем на каждом источнике данных до создания менеджера сущностей.НапильникОтелХранилищеСущностейоборачивает хранилища сущностей: желуди с прозвищемХранилищеСущностейи пользовательские хранилища с аннотацией&ХранилищеСущностей.
Дерево спанов повторяет вызовы:
ПолучитьОдно Пользователь INTERNAL entity.type, entity.result.count
└─ SELECT Пользователи CLIENT db.system.name, db.query.text, server.addressВызов метода хранилища собственного спана не получает: наблюдатель уже показывает ту же работу с той же длительностью, и второй спан был бы ее повтором. В трейсе метод виден по операциям, которые он выполнил, а сколько раз и как долго его звали - по гистограмме entity.repository.invocation.duration.
Когда нужен именно спан на методе хранилища - например, чтобы увидеть метод, который делает несколько операций подряд, - он вешается аннотацией &Наблюдаемый:
&ХранилищеСущностей("Пользователь")
Процедура ПриСозданииОбъекта()
КонецПроцедуры
&МетодЗапроса
&Наблюдаемый
Функция ПолучитьОдноПоИмяРавно(Имя) Экспорт
КонецФункцииХранилищеПользователей.ПолучитьОдноПоИмяРавно INTERNAL спан от &Наблюдаемый
└─ ПолучитьОдно Пользователь INTERNAL entity.type, entity.result.count
└─ SELECT Пользователи CLIENT db.system.name, db.query.textНа отдельном методе аннотация покрывает только его. На конструкторе - все экспортные методы объекта, включая унаследованные от ХранилищеСущностей: на Получить и Сохранить тогда появится и спан аннотации, и спан операции entity - два спана об одном вызове с одинаковой длительностью. Если такой повтор не нужен, вешайте аннотацию на те методы, ради которых она нужна.
Сигналы
| Сигнал | Имя | Источник |
|---|---|---|
Гистограмма, с entity.repository.invocation.duration | entity.repository, code.function.name, entity.repository.state (success, error), error.type | напильник |
Спаны операций и запросов, гистограммы db.client.operation.duration и entity.operation.duration, счетчики entity.entities и entity.transactions, датчики db.client.connection.* | см. opentelemetry-instrumentation-entity | наблюдатель |
Оба сигнала пишет opentelemetry-instrumentation-entity: напильник находит желуди с прозвищем ХранилищеСущностей и отдает их инструментированию, а какие методы оборачиваются и что попадает в атрибуты - описано в его справочнике.
Трассировщик и метр наблюдателя - области entity; напильник использует желудь ОтелМетр, как и остальные напильники.
Настройки
| Деталька | По умолчанию | Действие |
|---|---|---|
otel.entity.enabled | otel.enabled | Завязь наблюдателя. При false завязь возвращает Неопределено, и менеджеры сущностей наблюдателя не получают; SDK при этом не поднимается |
otel.entity.query-text | false | Текст запроса в атрибуте db.query.text. Запросы самого entity содержат плейсхолдеры вместо значений параметров, но произвольный текст из ВыполнитьСКоннектором не санитизируется и может нести литералы, поэтому по умолчанию выключено |
otel.entity.repository.enabled | otel.enabled | Напильник слоя репозиториев |
{
"otel": {
"enabled": true,
"entity": {
"enabled": true,
"query-text": true,
"repository": {
"enabled": true
}
}
}
}OTEL_ENTITY_ENABLED=true
OTEL_ENTITY_QUERY_TEXT=false
OTEL_ENTITY_REPOSITORY_ENABLED=trueДатчики db.client.connection.* наблюдатель заполняет сам, из событий источника данных - что именно в них попадает, описано в его справочнике.
Семантические соглашения
Какие атрибуты семантических соглашений OpenTelemetry заполняет autumn-opentelemetry. В таблицах — stable-атрибуты semconv (версия 1.44.0). Группы атрибутов названы так же, как в semconv.
Атрибуты, которые заполняет само ядро, описаны в семантических соглашениях opentelemetry, атрибуты работы с базой данных — в семантических соглашениях opentelemetry-instrumentation-entity.
Ресурс
Telemetry Distro
| Атрибут | Значение |
|---|---|
telemetry.distro.name | autumn-opentelemetry |
telemetry.distro.version | версия пакета |
Атрибуты заполняет детектор ОтелДетекторРесурсаДистрибутива. Адрес схемы его ресурса — https://opentelemetry.io/schemas/1.44.0.
Остальные атрибуты ресурса — service.*, telemetry.sdk.*, атрибуты встроенных детекторов — заполняет ядро, см. Ресурс в семантических соглашениях opentelemetry.
Code
| Атрибут | Кто заполняет |
|---|---|
code.function.name | спаны &Наблюдаемый, гистограммы &Замеряемый, счётчики &Подсчитываемый: полное имя метода ИмяЖелудя.ИмяМетода |
Исключения
Исключение, вышедшее из метода &Наблюдаемый, записывается записью лога в контексте спана метода:
| Поле | Значение |
|---|---|
| Имя события | exception: метод желудя не относится к операции какой-либо предметной области семантических соглашений |
| Серьёзность | ERROR у спанов server и consumer, WARN у остальных |
| Атрибуты | exception.* из исключения, code.function.name |
Атрибуты exception.* заполняет ядро, см. Исключения в семантических соглашениях opentelemetry.
Error
| Атрибут | Кто заполняет |
|---|---|
error.type | спаны &Наблюдаемый, гистограммы &Замеряемый и счётчики &Подсчитываемый, если из метода вышло исключение: ОтелУтилиты.ТипОшибки — код ошибки библиотеки errors, код нативной ошибки OneScript или _OTHER. У успешных вызовов атрибута нет |
Описание статуса такого спана — текст исключения, по recording-errors.
Инструментирование entity
Спаны и метрики работы с базой данных через autumn-data пишет opentelemetry-instrumentation-entity. Их атрибуты описаны в семантических соглашениях opentelemetry-instrumentation-entity.
