Skip to content

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

opentelemetry-instrumentation-entity подписывается на события источника данных entity и превращает их в телеметрию OpenTelemetry SDK. Библиотека устроена как инструментирования JDBC и Hibernate в Java: ORM не зависит от OpenTelemetry и отдает события через собственный интерфейс НаблюдательИсточникаДанных, а этот пакет реализует наблюдателя.

Регистрация

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

Сдк = ОтелАвтоконфигурация.Инициализировать();

Наблюдатель = Новый ОтелНаблюдательИсточникаДанных(
    Сдк.ПолучитьТрассировщик("entity"),
    Сдк.ПолучитьМетр("entity")
);

Источник = Новый ИсточникДанных("Основной", Тип("КоннекторPostgreSQL"), СтрокаСоединения);
Источник.ДобавитьНаблюдателя(Наблюдатель);

МенеджерСущностей = Новый МенеджерСущностей(Источник);
МенеджерСущностей.ДобавитьКлассВМодель(Тип("Автор"));
МенеджерСущностей.Инициализировать();

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

Второй способ инструментирования — вокруг вызовов методов хранилища сущностей. Наблюдатель видит операции entity, но не видит, из какого метода прикладного хранилища сущностей они пришли; ОтелИнструментированиеХранилищаСущностей оборачивает хранилище и замеряет каждый вызов:

bsl
Инструментирование = Новый ОтелИнструментированиеХранилищаСущностей(Сдк.ПолучитьМетр("entity"));

ХранилищеСущностей = Инструментирование.Обернуть(
    МенеджерСущностей.ПолучитьХранилищеСущностей(Тип("Автор")),
    "ХранилищеАвторы"
);

Обертка дает только метрику. Спанов вокруг вызовов она не создает: в трейсе видны операции entity и запросы к СУБД, которые метод выполнил, а сам вызов метода виден в гистограмме entity.repository.invocation.duration с атрибутами entity.repository и code.function.name.

Подробности — в справочнике.

В приложениях на Autumn регистрацию делает связка autumn-data и autumn-opentelemetry: наблюдатель создается завязью при включенном otel.entity.enabled и регистрируется на всех источниках данных.

Трейс

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

text
Получить Автор                      INTERNAL  entity.type=Автор entity.result.count=2
├─ SELECT Авторы                    CLIENT    db.system.name=postgresql db.operation.name=SELECT
├─ ПолучитьОдно Издательство        INTERNAL  entity.depth=1
│  └─ SELECT Издательства           CLIENT
└─ ПолучитьОдно Издательство        INTERNAL  entity.depth=1
   └─ SELECT Издательства           CLIENT

Операция из прикладного кода - корень с entity.depth = 0. Разыменование ссылок и чтение подчиненных таблиц - дочерние операции с большей глубиной, запросы к СУБД - листья. Каскад и N+1 видны как вложенность: два ПолучитьОдно Издательство под одним чтением - повод для отбора по ссылке.

Спан операции:

АтрибутЗначение
code.namespaceМенеджерСущностей
code.function.nameоперация: Сохранить, Получить, ПолучитьОдно, Удалить, Инициализировать, ВыполнитьСКоннектором, ВычислитьСКоннектором
entity.typeтип сущности
entity.tableтаблица сущности
entity.depthвложенность операции
entity.result.countстрок прочитано (после выполнения)
error.typeтип ошибки, если операция ею завершилась

Спан запроса:

АтрибутЗначение
db.system.namepostgresql, sqlite, inmemory, json
db.namespaceбаза данных, путь к файлу или каталогу
db.collection.nameтаблица запроса
db.operation.nameSELECT, INSERT, DELETE, CREATE TABLE, BEGIN, COMMIT, ROLLBACK
db.query.textтекст запроса с плейсхолдерами; у коннекторов без SQL отсутствует
db.response.returned_rowsстрок вернул SELECT
server.address, server.portсервер СУБД; у файловых баз отсутствуют
error.typeтип ошибки

Ошибка операции или запроса записывается в спан событием exception, статус спана становится Error. Сама ошибка при этом доходит до вызывающего кода как обычно.

Транзакции долгоживущего спана не получают: BEGIN, COMMIT и ROLLBACK приходят обычными спанами запроса внутри операций, которые их вызвали.

Метрики

ИнструментИмяЕдиницаАтрибуты
Гистограммаdb.client.operation.durationсdb.system.name, db.namespace, db.collection.name, db.operation.name, server.address, server.port, error.type
Гистограммаentity.operation.durationсentity.operation, entity.type, error.type
Счетчикentity.entities{entity}entity.operation, entity.type
Счетчикentity.transactions{transaction}entity.transaction.result: commit, rollback, failed, abandoned
Датчикdb.client.connection.count{connection}db.client.connection.pool.name, db.client.connection.state: used, idle
Датчикdb.client.connection.max{connection}db.client.connection.pool.name
Датчикdb.client.connection.pending_requests{request}db.client.connection.pool.name
Гистограммаdb.client.connection.wait_timeсdb.client.connection.pool.name
Гистограммаdb.client.connection.create_timeсdb.client.connection.pool.name
Счетчикdb.client.connection.timeouts{timeout}db.client.connection.pool.name
Гистограммаentity.repository.invocation.durationсentity.repository, code.function.name, entity.repository.state (success или error), error.type

entity.entities считает сущности, прошедшие через операции: сохранение и удаление - по одной, чтение - по числу прочитанных строк. entity.transactions считает исходы: failed - фиксация или отмена завершились ошибкой, abandoned - поток исполнения завершился, не закрыв транзакцию, и пул откатил ее.

Метрики пула пишутся из снимка, который entity прикладывает к каждому захвату и освобождению соединения, поэтому датчики отражают состояние после последнего события. Имя пула - источник данных без секретов: postgresql://localhost:5432/shop или sqlite:/var/lib/shop.db.

Гистограммы длительности - в секундах с границами бакетов из semantic conventions (0.001 … 10 с), как у db.client.operation.duration.

Настройки

КлючПо умолчаниюДействие
ТекстЗапросаИстинаПисать текст запроса в db.query.text
МетрикиИстинаРегистрировать инструменты и писать метрики

Настройки передаются структурой третьим параметром конструктора. Неопределено вместо трассировщика выключает спаны, вместо метра - метрики. Выключенный в SDK трассировщик дает незаписывающие спаны без накладных расходов на экспорт, метрики при этом продолжают писаться.

Накладные расходы

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