Spring4 Mybatis 쿼리 로그 남기는 방법에 대해서 문의드립니다.
조회수 22546회
이클립스에서 spring 4.25 RELEASE버전으로 spring-webmvc legacy 프로젝트를 생성하였습니다. 디비 접속 정보는 WAS에서 관리하기 위해 META-INF에 JNDI 설정 정보를 넣어 놨고, 디비와 연동은 현재 잘 테스트가 되었습니다.
쿼리 로그를 출력하기 위해서 log4j.xml 설정을 건드려봤는데 잘 해결이 되지 않아서 질문 드립니다. 스프링 레거시 프로젝트의 디펜더시를 보니 slf4j를 사용하는거 같은데 log4j.xml도 기본으로 만들어져 있어서 로거가 어떤식으로 동작하는지 잘 이해가 되지 않습니다..
다시 짧게 요약을 하자면 아래와 같습니다.
- WAS(Tomcat)에서 JNDI를 이용하여 디비 접속 중
- Spring - Mybatis 연동 됨
- 쿼리 로그 출력 안됨
mybatis 설정 경로는 아래와 같이 하였습니다.
- src/main/resources
- mybatis
- mapper.xml
- mybatis-config.xml (마이바티스 설정파일)
- mybatis
[mybatis-config.xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="LOG4J" />
</settings>
<typeAliases>
</typeAliases>
</configuration>
JNDI 설정은 아래와 같이 했습니다.
- src/main/webapp
- META-INF
- context.xml (JNDI 설정파일)
- META-INF
[context.xml]
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<Resource
auth = "Container"
driverClassName = "oracle.jdbc.driver.OracleDriver"
url = "[URL]"
username = "[ID]"
password = "[PASSWORD]"
name = "jdbc/Oracle11g"
type = "javax.sql.DataSource"
factory = "org.apache.tomcat.jdbc.pool.DataSourceFactory"
maxActive = "100"
minIdle = "10"
maxWait = "10000"
initialSize = "10"
validationQuery = "SELECT 1 FROM DUAL"
defaultAutoCommit = "false"
/>
</Context>
web.xml 파일에는 JNDI 정보를 연결했습니다.
- /src/main/webapp/WEB-INF
- web.xml
- web.xml
...
<resource-ref>
<res-ref-name>jdbc/Oracle11g</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
...
스프링에서 공유해서 사용할 JNDI를 root-context.xml에 만들었습니다.
- /src/main/webapp/WEB-INF/spring
- root-context.xml
[root-context.xml]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/Oracle11g" resource-ref="true" />
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
<property name="mapperLocations">
<list>
<value>classpath:mybatis/mapper.xml</value>
</list>
</property>
</bean>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="clearCache">
<constructor-arg ref="sqlSessionFactory" />
</bean>
</beans>
log4j.xml 설정파일에는 아래와 같이 추가했습니다. 아래 설정한 것 외에 java.sql로 시작하는 것도 해봤는데 실패했습니다..
- src/main/resource
- log4j.xml
[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="[패키지명]">
<level value="debug" />
</logger>
<logger name="jdbc.sqlonly">
<level value="debug" />
</logger>
<logger name="jdbc.sqltiming">
<level value="debug" />
</logger>
<logger name="jdbc.audit">
<level value="debug" />
</logger>
<logger name="jdbc.resultset">
<level value="debug" />
</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>
<!-- Root Logger -->
<root>
<priority value="warn" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
Maven은 아래와 같이 되어 있습니다.
[pom.xml]
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
<scope>test</scope>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- SQL Mapper -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
2 답변
-
[root-context.xml]
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- id를 dataSourceOrigin으로 수정 --> <jee:jndi-lookup id="dataSourceOrigin" jndi-name="jdbc/Oracle11g" resource-ref="true" /> <!-- 추가하는 부분 --> <bean id="dataSource" class="net.sf.log4jdbc.Log4jdbcProxyDataSource"> <constructor-arg ref="dataSourceOrigin" /> <property name="logFormatter"> <bean class="net.sf.log4jdbc.tools.Log4JdbcCustomFormatter"> <!-- <property name="loggingType" value="MULTI_LINE" /> --><!-- 여러줄에 출력하려고 하시면 코멘트 해제 --> <property name="sqlPrefix" value="SQL : "/> </bean> </property> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/> <property name="mapperLocations"> <list> <value>classpath:mybatis/mapper.xml</value> </list> </property> </bean> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="clearCache"> <constructor-arg ref="sqlSessionFactory" /> </bean> </beans>
[pom.xml]에 다음 라이브러리 추가.
<dependency> <groupId>org.lazyluke</groupId> <artifactId>log4jdbc-remix</artifactId> <version>0.2.7</version> </dependency>
-
Mybatis 3.1까지는 java.sql.Connection, java.sql.PreparedStatement를 logger name로 지정해서 로그레벨을 debug로 선언해야했습니다. Mybatis 3.2부터는 mybatis에서 지정하는 namespace별로 로그레벨을 지정할 수 있습니다. (관련 commmit : https://github.com/mybatis/mybatis-3/commit/84f31e22b3e50641f61b98b59f25b6eac7f93051 )
예를 들면 아래와 같은 mapper 선언이 있다고 하면
<mapper namespace="com.ksug.mybatis"> <insert id="createTable"> CREATE TABLE user (id INT, name VARCHAR(20)) </insert> </mapper>
위의 mapper에 대한 로깅선언은 아래와 같이 선언해주면 됩니다.
<logger name="com.ksug.mybatis" level="debug" />
logger name에 쿼리의 ID까지포함할수도 있습니다.
log4jdbc 같은 SQL로깅만을 위한 라이브러리를 쓰기보다는 개발환경에서의 로깅은 각각의 프레임워크의 정책에 따라 로그레벨 조정으로, 운영환경에서는 Pinpoint, Jeniffer같은 APM을 이용해서 SQL에 대한 추적을 하는 것이 바람직합니다.
-
(•́ ✖ •̀)
알 수 없는 사용자
-
댓글 입력