Skip to content

autumn-opentelemetry ​

Quality Gate StatusCoverageTelegram

autumn-opentelemetry — интеграция OpenTelemetry SDK с Autumn Framework.

Библиотека предоставляет аннотации для автоматической инструментации методов трассировкой, метриками и счётчиками, а также мост между логгером logos и OTel Logs API.

Установка ​

sh
opm install autumn-opentelemetry

Совместимость ​

Быстрый старт ​

1. Подключение к приложению ​

autumn-opentelemetry подключается к приложению Autumn автоматически — достаточно добавить #Использовать autumn-opentelemetry:

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

Поделка = Новый Поделка();
Поделка.ЗапуститьПриложение();

2. Минимальная конфигурация ​

otel.enabled и otel.service.name — обязательные параметры:

json
{
  "otel": {
    "enabled": true,
    "service": {
      "name": "my-service"
    }
  }
}

3. Инструментация методов ​

bsl
&Желудь
&Наблюдаемый
Процедура ПриСозданииОбъекта()
КонецПроцедуры

&Подсчитываемый("orders.processed")
&Замеряемый("orders.duration")
Функция ОбработатьЗаказ(&АтрибутСпана("order.id") ИдЗаказа) Экспорт
    // span с атрибутом order.id = ИдЗаказа
    // длительность в гистограмме orders.duration
    // счётчик orders.processed инкрементируется
    Возврат СформироватьОтвет(ИдЗаказа);
КонецФункции

Основные возможности ​

ОтелДуб автоматически:

  1. Инициализирует OpenTelemetry SDK через параметры приложения
  2. Регистрирует желуди ОтелSdk, ОтелТрассировщик, ОтелМетр
  3. Создаёт и регистрирует аппендер ОтелАппендерLogos для экспорта логов

Аннотации доступны для любого &Желудь:

АннотацияОписание
&НаблюдаемыйСоздаёт span OpenTelemetry вокруг метода
&ЗамеряемыйЗаписывает длительность вызова в гистограмму
&ПодсчитываемыйИнкрементирует счётчик при каждом вызове
&АтрибутСпанаДобавляет параметр метода как атрибут span'а

Дальнейшее изучение ​

Руководство пользователя ​

Справочник API ​


Конфигурация ​

Обязательные параметры ​

Два параметра обязательны для запуска SDK:

ПараметрОписание
otel.enabledВключает инструментирование аннотациями и экспорт логов. При false напильники возвращают желуди без изменений, аппендер ОтелАппендерLogos ничего не пишет, SDK не инициализируется и экспортёры не запускаются.
otel.service.nameИмя сервиса в телеметрии.
json
{
  "otel": {
    "enabled": true,
    "service": {
      "name": "my-service"
    }
  }
}
sh
OTEL_ENABLED=true
OTEL_SERVICE_NAME=my-service

Экспорт телеметрии ​

По умолчанию SDK экспортирует трассы, метрики и логи по адресу http://localhost:4318 (протокол http/protobuf).

json
{
  "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 полностью:

json
{
  "otel": {
    "sdk": {
      "disabled": true
    }
  }
}

Полный список параметров OpenTelemetry — в документации opentelemetry SDK.

Ресурс ​

Ресурс — атрибуты, которые SDK прикладывает ко всей телеметрии сервиса. ОтелSdk собирает его в таком порядке, каждый следующий источник важнее предыдущего:

  1. Атрибуты по умолчанию и встроенные детекторы ядра opentelemetry.
  2. Детекторы ресурса приложения — желуди с прозвищем ДетекторРесурса, в порядке &Порядок по возрастанию. При совпадении ключей важнее детектор с большим &Порядок.
  3. Переменные окружения OTEL_RESOURCE_ATTRIBUTES и OTEL_SERVICE_NAME, затем параметры otel.resource.attributes и otel.service.name.

autumn-opentelemetry сам содержит такой детектор — желудь ОтелДетекторРесурсаДистрибутива. Он добавляет атрибуты telemetry.distro.name = autumn-opentelemetry и telemetry.distro.version с версией пакета.

Свой детектор — желудь с прозвищем ДетекторРесурса:

bsl
#Использовать 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:

json
{
  "logos": {
    "logger": {
      "rootLogger": {
        "level": "INFO",
        "appenders": ["otel", "console"]
      }
    },
    "appender": {
      "otel": {
        "type": "ОтелАппендерLogos",
        "level": "WARN"
      },
      "console": {
        "type": "ВыводЛогаВКонсоль",
        "level": "INFO"
      }
    }
  }
}

Аннотации ​

&Наблюдаемый — трассировка методов ​

Автоматически создаёт span OpenTelemetry вокруг вызовов метода.

Размещение на отдельном методе инструментирует только его:

bsl
&Желудь
Процедура ПриСозданииОбъекта()
КонецПроцедуры

&Наблюдаемый("orders.process")
Функция ОбработатьЗаказ(ИдЗаказа) Экспорт
    Возврат СформироватьОтвет(ИдЗаказа);
КонецФункции

Размещение на конструкторе инструментирует все экспортные методы желудя, включая добавленные декоратором:

bsl
&Желудь
&Наблюдаемый
Процедура ПриСозданииОбъекта()
КонецПроцедуры

Функция ОбработатьЗаказ(ИдЗаказа) Экспорт
    Возврат СформироватьОтвет(ИдЗаказа);
КонецФункции

Параметры аннотации:

ПараметрПо умолчаниюОписание
Значение"ИмяЖелудя.ИмяМетода"Имя span'а
ВидСпанаinternalВид span'а: internal, server, client, producer, consumer

Если из метода вышло исключение, span получает статус Error с текстом исключения и атрибут error.type, а само исключение записывается записью лога с событием exception в контексте span'а. Серьёзность записи — ERROR у span'ов server и consumer, WARN у остальных: исключение уходит в вызывающий код, который может его обработать. Процессор событий ядра, включённый в автоконфигурации по умолчанию, переносит запись в событие span'а. Исключение доходит до вызывающего кода как обычно.

Пример с явным видом спана:

bsl
&Желудь
&Наблюдаемый(ВидСпана = "server")
Процедура ПриСозданииОбъекта()
КонецПроцедуры

&АтрибутСпана — атрибуты параметров ​

Добавляет значение параметра метода как атрибут текущего span'а. Используется совместно с &Наблюдаемый:

bsl
&Наблюдаемый
Функция ОбработатьЗаказ(&АтрибутСпана("order.id") ИдЗаказа, Данные) Экспорт
    // span получит атрибут order.id = значение ИдЗаказа
    Возврат СформироватьОтвет(ИдЗаказа);
КонецФункции

Если Значение не указано — в качестве ключа атрибута используется имя параметра:

bsl
&АтрибутСпана          // ключ = "ИдЗаказа"
&АтрибутСпана("order.id")  // ключ = "order.id"

&Замеряемый — измерение длительности ​

Записывает длительность каждого вызова метода в гистограмму OTel в секундах, как требуют семантические соглашения для гистограмм длительности. До версии 1.1.0 длительность писалась в миллисекундах.

Атрибуты гистограммы: code.function.name (полное имя метода ИмяЖелудя.ИмяМетода), error.type (при ошибке: код ошибки, код нативной ошибки OneScript или _OTHER).

bsl
&Желудь
Процедура ПриСозданииОбъекта()
КонецПроцедуры

&Замеряемый("payments.process.duration")
Функция ОбработатьПлатёж(Данные) Экспорт
    Возврат ПровестиПлатёж(Данные);
КонецФункции

Размещение на конструкторе инструментирует все экспортные методы желудя, включая добавленные декоратором:

bsl
&Желудь
&Замеряемый
Процедура ПриСозданииОбъекта()
КонецПроцедуры

Параметры аннотации:

ПараметрПо умолчаниюОписание
Значение"ИмяЖелудя.ИмяМетода.duration"Имя метрики (должно быть ASCII)

Имена методов на кириллице транслитерируются автоматически.

&Подсчитываемый — счётчик вызовов ​

Инкрементирует счётчик OTel при каждом вызове метода.

Атрибуты счётчика: code.function.name (полное имя метода ИмяЖелудя.ИмяМетода), error.type (при ошибке: код ошибки, код нативной ошибки OneScript или _OTHER). Успешные вызовы — точки без error.type.

bsl
&Желудь
Процедура ПриСозданииОбъекта()
КонецПроцедуры

&Подсчитываемый("api.requests")
Функция ОбработатьЗапрос(Запрос) Экспорт
    Возврат СформироватьОтвет(Запрос);
КонецФункции

Размещение на конструкторе инструментирует все экспортные методы желудя, включая добавленные декоратором:

bsl
&Желудь
&Подсчитываемый
Процедура ПриСозданииОбъекта()
КонецПроцедуры

Параметры аннотации:

ПараметрПо умолчаниюОписание
Значение"ИмяЖелудя.ИмяМетода.counted"Имя метрики (должно быть ASCII)

Имена методов на кириллице транслитерируются автоматически.

Комбинирование аннотаций ​

Аннотации можно комбинировать на одном методе:

bsl
&Желудь
Процедура ПриСозданииОбъекта()
КонецПроцедуры

&Наблюдаемый("orders.process")
&Замеряемый("orders.duration")
&Подсчитываемый("orders.count")
Функция ОбработатьЗаказ(&АтрибутСпана("order.id") ИдЗаказа) Экспорт
    Возврат СформироватьОтвет(ИдЗаказа);
КонецФункции

Методы, добавленные декоратором ​

Желудь редко доезжает до напильника тем же объектом, каким его объявили: хранилища сущностей autumn-data, наследники из extends, обёртки предыдущих напильников - всё это декораторы, и методов у собранного экземпляра больше, чем в модуле его типа.

Напильники рефлексируют по самому экземпляру, а не по типу, и аннотации читают оттуда же. Поэтому метод, пришедший с декоратором, инструментируется наравне с методами самого желудя, а аннотация на нём задаёт своё имя спана или метрики, вид спана и атрибуты параметров. Аннотация на конструкторе для этого не нужна - метод инструментируется и без неё.

Пример с наследником: ПостроительНаследника собирает декоратор, в который переносит и методы родителя, и их аннотации.

bsl
&Замеряемый("orders.load.duration")
Функция ЗагрузитьЗаказ(ИдЗаказа) Экспорт
    Возврат Прочитать(ИдЗаказа);
КонецФункции
bsl
#Использовать extends

&Желудь
&Расширяет("БазовыйСервис")
Процедура ПриСозданииОбъекта()
КонецПроцедуры

ЗагрузитьЗаказ попадёт в метрику orders.load.duration, хотя в модуле СервисЗаказов этого метода нет и определение желудя о нём не знает.


Инструментирование entity ​

Приложение на autumn-data получает трассировку и метрики работы с базой данных без единой строки прикладного кода: операции менеджера сущностей, запросы к СУБД, соединения, транзакции и вызовы хранилищ становятся спанами и метриками OpenTelemetry. Устроено как в Spring: слой данных инструментируется наблюдателем ORM, слой репозиториев - метрикой вокруг желудей.

Как это работает ​

  1. ОтелДуб объявляет завязь ОтелНаблюдательИсточникаДанных с прозвищем НаблюдательИсточникаДанных - наблюдатель из библиотеки opentelemetry-instrumentation-entity.
  2. autumn-data регистрирует все желуди с этим прозвищем на каждом источнике данных до создания менеджера сущностей.
  3. НапильникОтелХранилищеСущностей оборачивает хранилища сущностей: желуди с прозвищем ХранилищеСущностей и пользовательские хранилища с аннотацией &ХранилищеСущностей.

Дерево спанов повторяет вызовы:

text
ПолучитьОдно Пользователь      INTERNAL  entity.type, entity.result.count
└─ SELECT Пользователи         CLIENT    db.system.name, db.query.text, server.address

Вызов метода хранилища собственного спана не получает: наблюдатель уже показывает ту же работу с той же длительностью, и второй спан был бы ее повтором. В трейсе метод виден по операциям, которые он выполнил, а сколько раз и как долго его звали - по гистограмме entity.repository.invocation.duration.

Когда нужен именно спан на методе хранилища - например, чтобы увидеть метод, который делает несколько операций подряд, - он вешается аннотацией &Наблюдаемый:

bsl
&ХранилищеСущностей("Пользователь")
Процедура ПриСозданииОбъекта()
КонецПроцедуры

&МетодЗапроса
&Наблюдаемый
Функция ПолучитьОдноПоИмяРавно(Имя) Экспорт
КонецФункции
text
ХранилищеПользователей.ПолучитьОдноПоИмяРавно  INTERNAL  спан от &Наблюдаемый
└─ ПолучитьОдно Пользователь                   INTERNAL  entity.type, entity.result.count
   └─ SELECT Пользователи                      CLIENT    db.system.name, db.query.text

На отдельном методе аннотация покрывает только его. На конструкторе - все экспортные методы объекта, включая унаследованные от ХранилищеСущностей: на Получить и Сохранить тогда появится и спан аннотации, и спан операции entity - два спана об одном вызове с одинаковой длительностью. Если такой повтор не нужен, вешайте аннотацию на те методы, ради которых она нужна.

Сигналы ​

СигналИмяИсточник
Гистограмма, с entity.repository.invocation.durationentity.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.enabledotel.enabledЗавязь наблюдателя. При false завязь возвращает Неопределено, и менеджеры сущностей наблюдателя не получают; SDK при этом не поднимается
otel.entity.query-textfalseТекст запроса в атрибуте db.query.text. Запросы самого entity содержат плейсхолдеры вместо значений параметров, но произвольный текст из ВыполнитьСКоннектором не санитизируется и может нести литералы, поэтому по умолчанию выключено
otel.entity.repository.enabledotel.enabledНапильник слоя репозиториев
json
{
  "otel": {
    "enabled": true,
    "entity": {
      "enabled": true,
      "query-text": true,
      "repository": {
        "enabled": true
      }
    }
  }
}
sh
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

АтрибутЗначение
telemetry.distro.nameautumn-opentelemetry
telemetry.distro.versionверсия пакета

Атрибуты заполняет детектор ОтелДетекторРесурсаДистрибутива. Адрес схемы его ресурса — https://opentelemetry.io/schemas/1.44.0.

Остальные атрибуты ресурса — service.*, telemetry.sdk.*, атрибуты встроенных детекторов — заполняет ядро, см. Ресурс в семантических соглашениях opentelemetry.

Code ​

Code

АтрибутКто заполняет
code.function.nameспаны &Наблюдаемый, гистограммы &Замеряемый, счётчики &Подсчитываемый: полное имя метода ИмяЖелудя.ИмяМетода

Исключения ​

Exceptions in logs

Исключение, вышедшее из метода &Наблюдаемый, записывается записью лога в контексте спана метода:

ПолеЗначение
Имя событияexception: метод желудя не относится к операции какой-либо предметной области семантических соглашений
СерьёзностьERROR у спанов server и consumer, WARN у остальных
Атрибутыexception.* из исключения, code.function.name

Атрибуты exception.* заполняет ядро, см. Исключения в семантических соглашениях opentelemetry.

Error ​

Error

АтрибутКто заполняет
error.typeспаны &Наблюдаемый, гистограммы &Замеряемый и счётчики &Подсчитываемый, если из метода вышло исключение: ОтелУтилиты.ТипОшибки — код ошибки библиотеки errors, код нативной ошибки OneScript или _OTHER. У успешных вызовов атрибута нет

Описание статуса такого спана — текст исключения, по recording-errors.

Инструментирование entity ​

Спаны и метрики работы с базой данных через autumn-data пишет opentelemetry-instrumentation-entity. Их атрибуты описаны в семантических соглашениях opentelemetry-instrumentation-entity.