MyBatis는 내부적으로 JDBC의 PreparedStatement를 이용해서 SQL을 처리합니다.
따라서 SQL에 전달되는 파라미터는 JDBC에서와 같이 '?' 로 치환되어서 처리됩니다.
따라서 SQL 로그를 제대로 보기 위해서는 log4jdbc-log4j2 라이브러리를 사용해야 합니다.
1. mvnrepository.com/artifact/org.bgee.log4jdbc-log4j2/log4jdbc-log4j2-jdbc4.1/1.16
pom.xml 에 라이브러리를 설정합니다.
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
<version>1.16</version>
</dependency>
라이브러리를 추가한 후에는 다음 작업을 해야 합니다.
- 로그 설정 파일 추가
- JDBC 연결 정보 수정
1) 로그 설정 파일 추가
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
2) JDBC 연결 정보 수정
log4jdbc를 이용하는 경우는 JDBC 드라이버와 URL 정보를 수정해야 합니다.
root-context.xml의 일부를 수정합니다.
(기존)
(변경 후)
이렇게 하고 웹서버를 띄운다고 해도, Log가 보이지 않는 경우가 있습니다.
src/main/resources의 log4j.xml 에 "WARN" 레벨일 때만 로그가 찍히도록 설정되어 있는 경우입니다.
<!-- Root Logger -->
<root>
<priority value="warn" />
<appender-ref ref="console" />
</root>
"warn" 을 "info" 로 바꾸면 모든 로그가 보이게 되지만, 너무 많이 나오기 때문에 지저분해 보일 수 있습니다.
log4j.xml에
커스터마이징을 하여 좀 더 높은 레벨의 로그만 기록하게 수정하면 이전에 비해 로그의 양이 줄어드는 것을 확인할 수 있습니다.
<!-- SQL Logger -->
<logger name="jdbc.connection" additivity="false">
<level value="warn" />
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.audit" additivity="false">
<level value="warn"/>
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.resultset" additivity="false">
<level value="warn" />
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.sqlonly" additivity="false">
<level value="info"/>
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.resultsettable" additivity="false">
<level value="info"/>
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.sqltiming" additivity="false">
<level value="warn" />
<appender-ref ref="console"/>
</logger>
jdbc.connection | 열려있는 모든 번호와 연결 수립 및 해제 이벤트를 기록. 이는 연결 문제를 찾아내는데 매우 유용 (Connection Pool 설정) |
jdbc.audit | ResultSet을 제외한 모든 JDBC 호출 정보를 로그로 남긴다. 많은 양의 로그가 생성되므로 특별히 JDBC 문제를 추적해야 할 필요가 있는 경우를 제외하고는 사용을 권장하지 않는다. |
jdbc.resultset | ResultSet을 포함한 모든 JDBC 호출 정보를 로그로 남기므로 매우 방대한 양의 로그가 생성된다. |
jdbc.sqlonly | SQL문만을 로그로 남기며, PreparedStatement일 경우 관련된 argument 값으로 대체된 SQL문이 보여진다. (원래는 ? 로 표시되는데, log4j 덕분에 완전한 쿼리로 보여지는 것임) |
jdbc.resultsettable | SQL 결과 조회된 데이터의 table을 로그로 남긴다. |
jdbc.sqltiming | SQL문과 해당 SQL을 실행시키는데 수행된 시간 정보(milliseconds)를 포함한다. |
log4j.xml 전체 모습
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
<!-- Application Loggers -->
<logger name="com.exe.hotel">
<level value="info" />
</logger>
<!-- 3rdparty Loggers -->
<logger name="org.springframework.core">
<level value="info" />
</logger>
<logger name="org.springframework.beans">
<level value="info" />
</logger>
<logger name="org.springframework.context">
<level value="info" />
</logger>
<logger name="org.springframework.web">
<level value="info" />
</logger>
<!-- SQL Logger -->
<logger name="jdbc.connection" additivity="false">
<level value="warn" />
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.audit" additivity="false">
<level value="warn"/>
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.resultset" additivity="false">
<level value="warn" />
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.sqlonly" additivity="false">
<level value="info"/>
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.resultsettable" additivity="false">
<level value="info"/>
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.sqltiming" additivity="false">
<level value="warn" />
<appender-ref ref="console"/>
</logger>
<!-- Root Logger -->
<root>
<priority value="warn" />
<appender-ref ref="console" />
</root>
</log4j:configuration>