반응형
현재 학습 기록용으로 블로그를 작성하고 있습니다.
부족한 내용이 있거나 맞지 않은 내용이 있으면 댓글 부탁드립니다!
하단의 블로그에서 상세하게 설명해주신 자료를 참고했습니다.
Spring MVC Project에서 Log4j를 이용해서 인터셉터 구현 및 쿼리 로그 출력과 정렬을 진행하겠습니다.
스프링(Spring) 개발 - (8) 로그 (Log4j) 및 인터셉터 (Interceptor) 설정
이번글에서는 앞으로 개발을 하는데 필요한 정보를 보여줄 수 있는 로그와 관련된 내용을 이야기합니다. 지금 당장은 크게 눈에 보이는게 없을수도 있겠지만, 한번 하고나면 개발하는데 굉장히
addio3305.tistory.com
TODO
1. Spring Log4j를 이용해서 인터셉터로 로그를 남긴다.
2. lo4jdbc-remix를 추가해서 MyBatis 쿼리 정렬을 한다.
1. Spring Log4j를 이용해서 인터셉터로 로그를 남긴다.
1.1 pom.xml 구성
- log4j를 사용하기 위해서는 commons.logging 라이브러리 ( Apache의 JCL, Jakarta Commons Logging )을 사용합니다.
- 기본적으로 아래와 같은 항목들이 추가가 되어 있기에 별 다른 설정을 하지 않고 넘어갑니다.
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<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>
1.1 log4.xml
- log4j.xml의 설정은 다음과 같이 해줍니다.
- 20행에는 자신의 패키지명으로 변경해줍니다.
<?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">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %5p [%c] %m%n" />
</layout>
</appender>
<appender name="console-infolog" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %5p %m%n" />
</layout>
</appender>
<!-- Application Loggers -->
<!-- kr.co.devst 를 여기서는 자신의 패키지명으로 바꿔서 적어 주시면 됩니다. -->
<logger name="kr.co.devst" additivity="false">
<level value="debug" />
<appender-ref ref="console"/>
</logger>
<!-- Query Loggers -->
<logger name="jdbc.sqlonly" additivity="false">
<level value="INFO"/>
<appender-ref ref="console-infolog"/>
</logger>
<logger name="jdbc.resultsettable" additivity="false">
<level value="INFO"/>
<appender-ref ref="console"/>
</logger>
<!-- Root Logger -->
<root>
<priority value="off"/>
<appender-ref ref="console" />
</root>
</log4j:configuration>
1.3 LoggerInterceptor.java
- HandlerInterceptorAdapter을 상속받아서 preHandle, postHandle를 오버 라이딩합니다.
- 하단에 preHandle, postHandle에 다음과 같은 내용을 넣어줍니다.
package kr.co.devst.logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class LoggerInterceptor extends HandlerInterceptorAdapter {
protected Log log = LogFactory.getLog(LoggerInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (log.isDebugEnabled()) {
log.debug("========== START =========== START ========== START ==========");
log.debug(" Request URI \t: " + request.getRequestURI());
}
return super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
if (log.isDebugEnabled()) {
log.debug("========== END =========== END ========== END ==========");
}
}
}
1.4 servlet-context.xml
- 30~36행에 있는 <mvc:interceptors> 태그를 추가해줍니다.
- <mvc:mapping path="/**"/>는 모든 경로에서 들어오는 요청을 인터셉트해준다는 것입니다.
- beans태그의 class는 실제 LoggerInterceptor를 작성한 [패키지명. 클래스명]입니다.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing
infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving
up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources
in the /WEB-INF/views directory -->
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<beans:bean id="loggerInterceptor"
class="kr.co.devst.logger.LoggerInterceptor"></beans:bean>
</mvc:interceptor>
</mvc:interceptors>
<context:component-scan
base-package="kr.co.devst" />
</beans:beans>
1.5 TestController.java
- 인터셉터가 정상적으로 작동을 하는지 테스트해보겠습니다.
package kr.co.devst.test;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@Controller
public class TestController {
private static final Log log = LogFactory.getLog(TestController.class);
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String goTest() {
return "test";
}
}
1.5 test.jsp
- test.jsp를 webapp/WEB-INF/views 밑에 생성을 해줍니다.
- TestController에서 test를 리턴해주면 servlet-context.xml에서 설정해준 접두사인 prefix="/WEB-INF/views"와 접미사인 suffix=". jsp"가 test의 앞 뒤에 붙어서 /WEB-INF/views/test.jsp가 됩니다. 그래서 다음과 같은 경로에 test.jsp를 찾아가게 되는 것입니다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>인터셉터 test jsp입니다.</h1>
</body>
</html>
- 실행을 하고 TestController.java에서 /test 경로로 클라이언트에서 요청이 들어오면 test를 리턴해줘서 경로에서 localshost:8080/test를 입력하면 아래의 콘솔과 같이 나오게 됩니다.
2. log4jdbc-remix를 추가해서 MyBatis 쿼리 정렬을 한다.
- Spring에서 위와 같은 설정을 하고 추후에 DAO와 MyBatis에 DB 작업까지 하면 위의 설정만으로는 쿼리가 길어져도 정렬되어 보이지 않아서 불편한 경우가 있습니다.
- log4jdbc-remix 라이브러리를 추가해서 해결해보도록 하겠습니다.
2.1 pom.xml
- log4j-remix를 추가해줍니다.
<!-- log4jdbc-remix -->
<dependency>
<groupId>org.lazyluke</groupId>
<artifactId>log4jdbc-remix</artifactId>
<version>0.2.7</version>
</dependency>
2.2 root-context.xml
- 2행에서 bean id="dataSourceSpied'를 13행에서 <constructor-arg ref="dataSourceSpied" /> ref로 설정해줍니다.
- property에는 자신의 db와 username, password를 입력해줍니다.
<!-- Root Context: defines shared resources visible to all other web components -->
<bean id="dataSourceSpied"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="com.mysql.cj.jdbc.Driver"></property>
<property name="url"
value="jdbc:mysql://${your mysql ip/port}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</bean>
<bean id="dataSource" class="net.sf.log4jdbc.Log4jdbcProxyDataSource">
<constructor-arg ref="dataSourceSpied" />
<property name="logFormatter">
<bean class="net.sf.log4jdbc.tools.Log4JdbcCustomFormatter">
<property name="loggingType" value="MULTI_LINE" />
<property name="sqlPrefix" value="SQL : " />
</bean>
</property>
</bean>
2.3 서버 실행해서 SQL 쿼리 정렬여부 확인하기
- 여기서는 따로 코드 Controller, Service, DAO, MyBatis 작성은 하지 않겠습니다.
- 자신의 SQL 결과를 콘솔에서 확인을 하시면 보시는 거와 같이 깔끔하게 정렬이 되어서 나오는 것을 볼 수 있습니다.
지금까지 Spring에서 log4j를 이용해서 클라이언트가 요청하는 url 을 남기는 것과 SQL 쿼리를 정렬해서 출력하는 것을 살펴봤습니다.
반응형
'Spring' 카테고리의 다른 글
Spring Boot jsp 사용 (0) | 2024.03.17 |
---|---|
nGrinder & Spring Boot API 성능 테스트 (0) | 2023.03.05 |
nGrinder 성능 테스트 플랫폼 설치 (0) | 2023.03.05 |
[spring] Lombok 이란? (0) | 2020.09.10 |
[jsp][servlet] Forward VS Redirect(차이점) (0) | 2020.09.03 |