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