Skip to content

Инструментирование 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.* наблюдатель заполняет сам, из событий источника данных - что именно в них попадает, описано в его справочнике.