본문으로 바로가기
반응형

spring boot상에서 Log4jdbc를 사용해 실행된 쿼리 로그를 효과적으로 확인하고 분석할 수 있는 방법을 알아보자.


Spring boot는 자체적으로 log4j등 여러 종류의 logging API를 제공하고, apprication.properties에서의 간단한 설정만으로 옵션을 셋팅할 수 있다.

(spring boot logging : http://www.leafcats.com/20 참조)

하지만 이것만 가지고는 실행된 sql 로그를 보는 것에 다소 불편함이 있다.

일반적인 로그 셋팅만 하고 쿼리를 실행하면 아래와 같은 형식의 sql 로그를 볼 수 있다.


Preparing: SELECT CODE_NAME FROM COMMON_CODE WHERE CODE_ID = ?  

Parameters: 25(Integer) 


위 예시는 길이가 짧은 쿼리지만, 길이가 긴 쿼리도 한줄로 표시될 뿐 아니라 파라미터가 들어갈 곳에 "?"가 들어있는 preparing 상태의 sql문과 파라미터들을 따로 출력한다.

또한, 이 정보 외에 다른 부가적인 정보들을 로그로 확인할 수 없다.

쿼리 로그를 조금 더 보기 편하고 상세하게 출력하기 위해서는 Log4jdbc를 사용해야 한다.



spring boot 에서 Log4jdbc 설정


spring boot를 사용할 경우, 일반 spring 환경보다 훨씬 간단하게 설정이 가능하다.



1. log4jdbc를 dependency에 추가한다.


나는 maven을 사용하기 때문에, pom.xml에 아래 dependency를 추가했다.

gradle을 사용하는 경우 역시 해당 라이브러리를 추가해 주면 되겠다.

1
2
3
4
5
6
<!-- log4jdbc -->
<dependency>
    <groupId>org.bgee.log4jdbc-log4j2</groupId>
    <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
    <version>1.16</version>
</dependency>    
cs



2. application.properties 설정(중요)


기존에 이미 spring datasource 설정을 해 둔 부분이 있을 것이다.

그중 driverClassName과 url을 아래 빨간색처럼 변경해준다.

spring.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy

spring.datasource.url=jdbc:log4jdbc:mariadb://localhost:3306/test



3. log4jdbc.log4j2.properties 생성


resources 폴더에 log4jdbc.log4j2.properties 파일을 이름 그대로 생성해 준다.

생성된 파일에아래 내용을 넣은 후 저장한다.

log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator

log4jdbc.dump.sql.maxlinelength=0

(maxlinelength는 sql문을 최대 몇 라인까지 출력할 것인가를 결정한다. 0으로 하면 제한 없이 실행된 그대로 출력이 되고, 설정하지 않으면 그냥 한줄로 쭉 출력된다.)

여기까지만 해도 서버 구동 후 쿼리 수행하는 기능을 작동해 보면 이전과는 다른, 매우 디테일한 수많은 로그들이 올라올 것이다. 별다른 셋팅을 해 주지 않으면, 기본적으로 log4jdbc가 제공하는 모든 로깅 옵션들이 다 켜진 상태로 로그를 출력한다. 



4. logback.xml 설정


logback.xml에서 출력할 로그의 옵션들을 조정할 수 있다.

properties파일과 마찬가지로 resources 폴더에 logback.xml을 아래와 같이 생성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{yyyyMMdd HH:mm:ss.SSS} [%thread] %-3level %logger{5} - %msg %n</pattern>
    </encoder>
  </appender>
  
  <logger name="jdbc" level="OFF"/>
  
  <logger name="jdbc.sqlonly" level="OFF"/>
  <logger name="jdbc.sqltiming" level="DEBUG"/>
  <logger name="jdbc.audit" level="OFF"/>
  <logger name="jdbc.resultset" level="OFF"/>
  <logger name="jdbc.resultsettable" level="DEBUG"/>
  <logger name="jdbc.connection" level="OFF"/>
  
  <root level="INFO">
    <appender-ref ref="STDOUT" />
  </root>
  
</configuration>
cs


log4jdbc는 아래와 같은 옵션들을 제공한다.



 - jdbc.sqlonly : SQL문만을 로그로 남기며, PreparedStatement일 경우 관련된 argument 값으로 대체된 SQL문이 보여진다. 
 - jdbc.sqltiming : SQL문과 해당 SQL을 실행시키는데 수행된 시간 정보(milliseconds)를 포함한다. 
 - jdbc.audit : ResultSet을 제외한 모든 JDBC 호출 정보를 로그로 남긴다. 많은 양의 로그가 생성되므로 특별히 JDBC 문제를 추적해야 할 필요가 있는 경우를 제외하고는 사용을 권장하지 않는다. 
 - jdbc.resultset : ResultSet을 포함한 모든 JDBC 호출 정보를 로그로 남기므로 매우 방대한 양의 로그가 생성된다. 

jdbc.resultsettable : SQL 결과 조회된 데이터의 table을 로그로 남긴다.


각옵션들의 기능을 정확히 알기 위해서는 직접 하나씩 변경해 보며 구동하는 것이 좋을 것이다.




결과 예시


아래는 sqltiming과 resultsettable을 DEBUG로 하고 실행시킨 로그창이다.




실행된 SQL문과 실행 시간 정보, 조회된 데이터의 테이블이 로그로 남은 것을 볼 수 있다.


개발중 뿐 아니라 운영시점에도 로그 정보는 매우 중요하다. 특히 SQL정보는 제대로 된 로그가 아닐 경우 디버깅이 매우 힘들기 때문에, SQL에 대한 로그는 각별히 신경써서 셋팅 하는 것이 좋다.




반응형

 Other Contents