====== Hibernate Log 남기기 ======
Hibernate는 Log4j 옵션 설정을 통해 SQL 실행 로그 등을 세세히 남기도록 조정할 수 있다.
* hibernate 프라퍼티중 ''hibernate.show_sql=true'' 로 설정하면 로거용 로그와 hibernate가 System.out 으로 찍는 로그 두개씩 찍힌다. 따라서 로거를 사용할 때는 hibernate.show_sql=false 로 설정해야 한다.
* ''hibernate.format_sql=true'' 로 하면 Log4j 로그를 찍을때 알아보기 편한 상태로 줄바꿈 해서 출력해준다.
* org.hibernate.type 로그에는 한가지 문제가 있다, 클래스가 로딩되는 순간 Log level을 저장해 놓고, 그 이후로는 그 저장된 값을 사용한다는 것이다. 이 때문에 처음에는 Log4J 설정을 DEBUG 이상의 레벨로 실행하다가 프로그램 실행중에 동적으로 TRACE로 바꾼다고 해서 JDBC 파라미터가 로그로 남지는 않는다. 따라서 항상, 이 로그를 남기려면 **Hibernate의 클래스들이 로딩되기 전에 Logger의 설정이 TRACE로 되어 있어야 한다.**
* statistics를 남기기 위해 ''hibernate.generate_statistics=true'' 로 지정하고 ''org.hibernate.stat'' Logger를 ''DEBUG''로 지정한다.
Hibernate 의 로깅을 사용하지 않고 다음과 같은 방법들을 사용할 수도 있다.
* [[java:jdbc|JDBC]]
* [[database:mysql:jdbc|MySQL JDBC]] 처럼, JDBC 드라이버 자체의 로깅
* [[https://log4jdbc.brunorozendo.com|log4jdbc]]
* [[java:jdbc:datasource_proxy|DataSource Proxy]]
JDBC 드라이버 자체 로깅을 사용하면 프레임워크등에 의해 실행되는 너무 세세한 로그가 남는 반면, 파라미터까지 정확하게 정확한 호출 순서에 따라 로그를 볼 수 이는 장점이 있다.
===== Log Categories =====
* ''org.hibernate'' : 모든 메시지
* ''org.hibernate.SQL = DEBUG'' : SQL 구문
* ''org.hibernate.type.descriptor.sql = TRACE'' : 바인딩된 파라미터 값(Hibernate 4,5)
* ''org.hibernate.type = TRACE'' 은 모든 JDBC 파라미터를 찍으며, 이 경우 로그가 과도하게 찍히기 때문에
* ''org.hibernate.type.BasicTypeRegistry = WARN'' 으로 로그 출력을 줄여줄수도 있다.
* ''org.hibernate.orm.jdbc.bind = TRACE'' : 바인딩된 파라미터 값(Hibernate 6)
* ''org.hibernate.SQL_SLOW = INFO'' : Hibernate 5.4.5 이상 버전에서 Slow Query
* ''hibernate.session.events.log.LOG_QUERIES_SLOWER_THAN_MS=밀리초'' property 를 지정해주면 이 값을 따름.
* ''org.hibernate.pretty'' : flush 시점의 세션이 있는 Entity 들의 상태(최대 20 개만)
* ''org.hibernate.cache'' : 2차 캐시 상태
* ''org.hibernate.stat = DEBUG'' : 모든 쿼리의 분석 통계
* ''org.hibernate.tool.hbm2ddl = DEBUG'' : DDL 로그
* ''org.hibernate.transaction'' : 트랜잭션 정보
* ''org.hibernate.jdbc'' : JDBC 리소스 처리 상태 로깅
* ''org.hibernate.hql.ast.AST'' : Log HQL and SQL ASTs during query parsing
* ''org.hibernate.secure'' : Log all JAAS authorization requests
===== logback =====
===== Log4j =====
log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug
# http://blog.naver.com/jdkim528/140027638234 에서 가져옴. -> 쿼리 파라미터는 잘못돼 있음
### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug
### log just the SQL
log4j.logger.org.hibernate.SQL=debug
### log JDBC bind parameters ###
log4j.logger.org.hibernate.type=TRACE # 혹은 과거버전 log4j에서는 DEBUG
### log schema export/update ###
log4j.logger.org.hibernate.tool.hbm2ddl=info
### log HQL parse trees
#log4j.logger.org.hibernate.hql=debug
### log cache activity ###
log4j.logger.org.hibernate.cache=info
### log transaction activity
#log4j.logger.org.hibernate.transaction=debug
### log JDBC resource acquisition
#log4j.logger.org.hibernate.jdbc=debug
### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace
디버깅시 가장 중요한 SQL로그와 파라미터/결과 로그는 **log4j.logger.org.hibernate.SQL=debug**와 **log4j.logger.org.hibernate.type=TRACE** 이다.
===== SQL Formatter =====
* [[https://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/engine/jdbc/internal/class-use/FormatStyle.html|FormatStyle]] 과 [[https://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/engine/jdbc/internal/Formatter.html|Formatter]] 클래스를 통해 SQL을 포매팅할 수 있다.
===== 참조 =====
* [[https://stackoverflow.com/questions/1710476/how-to-print-a-query-string-with-parameter-values-when-using-hibernate|java - How to print a query string with parameter values when using Hibernate - Stack Overflow]]
* [[https://thorben-janssen.com/hibernate-tips-how-to-log-sql-statements-and-their-parameters/|Hibernate Tips: How to log SQL statements and their param]]
* [[https://thorben-janssen.com/hibernate-slow-query-log/|Hibernate Slow Query Log - The easiest way to find slow queries]]
* [[https://thorben-janssen.com/hibernate-logging-guide/|Logging Guide for Hibernate 4, 5 & 6 - Use the right config for dev and prod]]
* [[https://vladmihalcea.com/log-sql-spring-boot/|The best way to log SQL statements with Spring Boot - Vlad Mihalcea]]