Приветствую, дорогие друзья! Меня зовут Алексей, я разработчик по кадровому производству. В этой статье предлагаю обсудить способы логирования Hebernate.
Hibernate — это прекрасный инструмент для работы, особенно когда функционирует быстро и исправно, но когда возникают проблемы — необходимо посмотреть, что происходит под капотом. Примеры конфигурации будут приводится на Spring.
Первый и самый простой способ
Указать в application.properties: spring.jpa.show-sql=true
илиspring.jpa.properties.hibernate.show_sql=true).
Этот подход позволяет быстро решить проблему и помочь в локальном поиске багов. Но есть два очевидных недостатка:
1. Вывод sql не проходит через наш логгер и не имеет удобный для нас формат.
2. Вместо параметров запроса мы видим вопросики.
Второй подход — установка уровня логирования либо в properties, либо в конфигурации логера
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
Этот подход полностью решает проблемы с форматом, и частично решает проблему с вопросами. Вопросы остались, но после запроса мы видим их поочередное перечисление со значениями.
Третий подход — использование proxy драйвера
Например log4jdbc или p6spy. Оба прокси рабочие и на них есть стартеры, хотя на log4jdbc давно не было коммитов.
<groupId>com.integralblue</groupId>
log4jdbc-spring-boot-starter
<groupId>com.github.gavlyukovskiy</groupId>
p6spy-spring-boot-starter
В принципе, нашей цели мы добились. Но есть одна проблема: иногда запросов очень много, а нам нужен всего один. Расскажу на примере p6spy.
Во-первых у нас есть ограничение в самой библиотеке.
decorator.datasource.p6spy.log-filter.pattern=.*insert.*
покажет нам все insert запросы.
Но иногда нам нужно выводить в лог всего один или несколько методов. Сделаем реализацию такой аннотации сами. Объявим аннотацию:
По сути нам нужно отфильтровать нужные логи по какому то признаку. Я решил сделать это с помощью MDC, у него область видимости как раз ThreadLocal, что нам на руку. Сделаем фильтр:
Обработчик аннотации я сделал через аспект:
ну и конфигурация на примере Logback:
Создадим дополнительный appender с фильтром и пропустим через него логи p6spy уровня info и не забудем указать additivity=«false», что бы root appender не обрабатывал этот же пакет. Вот и всё. Не забываем, что мы сделали это через proxy, а значит у нас есть ограничения в выборе методов, над которыми можно ставить новую аннотацию.
На этом все. Надеюсь, был полезен!