스프링 부트 ( 2.7.0) mybatis 사용
인터셉터 설정
인터셉터란? 가로챈다는 뜻이다.
스프링의 Spring Context(ApplicationContext)기능으로 인터셉터는 임의의 URI를 호출시 DispatcherServlet에서 해당 Controller가 처리 되기 전과 후에 발생하는 이벤트이다. 비슷한 역할로는 필터(Filter)가 있다. 둘다 역할은 비슷하지만 차이가 있다.
1. BaseHandlerInterceptor 추가
BaseHandlerInterceptor
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import lombok.extern.slf4j.Slf4j; @Slf4j public class BaseHandlerInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("\n\n\n*** [preHandle] URI : {} - 시작 " , request.getRequestURI()); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("\n***[postHandle] URI : {} - 종료 \n\n\n", request.getRequestURI()); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex) throws Exception { //log.info("[afterCompletion]"); } }
2. WebMvcConfig 클래스에서 WebMvcConfigurer 인터페이스 구현
import org.springframework.boot.web.servlet.view.MustacheViewResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewResolverRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; import kr.so.songjava.configuration.handler.BaseHandlerInterceptor; @Configuration public class WebMvcConfig implements WebMvcConfigurer { /** * 머시태시 템플릿을 html 확장자 명으로 변경 */ @Override public void configureViewResolvers(ViewResolverRegistry registry) { MustacheViewResolver resolver = new MustacheViewResolver(); resolver.setCharset("UTF-8"); resolver.setContentType("text/html;charset=UTF-8"); resolver.setPrefix("classpath:/templates/"); resolver.setSuffix(".html"); registry.viewResolver(resolver); } /** * Locale 값이 변경되면 인터셉터가 동작한다. url의 query parameter에 지정한 값이 들어올 때 동작한다. ex) * http://localhost:8080?lang=ko * * @return */ @Bean public LocaleChangeInterceptor localeChangeInterceptor() { LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor(); interceptor.setParamName("lang"); return interceptor; } /** * BaseHandlerInterceptor 빈 설정 */ @Bean public BaseHandlerInterceptor baseHandlerInterceptor() { return new BaseHandlerInterceptor(); } /** * 인터셉터 등록 LocaleChangeInterceptor 를 스프링 컨테이너에 등록한다. WebMvcConfigurer 를 상속받고 * addInterceptors를 오버라이딩 한다. */ @Override public void addInterceptors(InterceptorRegistry registry) { // 로그을 찍기 위해 - BaseHandlerInterceptor 인터셉터 등록 registry.addInterceptor(baseHandlerInterceptor()); //다국어 설정을 위한 localeChangeInterceptor 을 인터셉터에 등록 registry.addInterceptor(localeChangeInterceptor()); } }
3. application.properties 설정
# logback 위치지정 logging.config= classpath:logback/logback-default.xml
4. logback-default.xml 추가
<?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/base.xml"/> <!-- 1. 유형 - 콘솔로 로그를 남김 색깔 적용 --> <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender"> <withJansi>true</withJansi> <encoder> <charset>UTF-8</charset> <!-- 로그 메시지 패턴 --> <Pattern> %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n </Pattern> </encoder> </appender> <!-- 2.유형 : 파일로 로그를 남김 --> <appender name="dailyRollingFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <prudent>true</prudent> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>logs/applicatoin.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>error</level> </filter> <encoder> <pattern>%d{yyyy:MM:dd HH:mm:ss.SSS} %-5level --- [%thread] %logger{35} : %msg %n</pattern> </encoder> </appender> <!-- 3.유형 : 파일로 로그를 남김 --> <appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- <file>c:\LogExample\logexample2.log</file> --> <file>logs/logexample2.log</file> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <Pattern> %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n </Pattern> </encoder> <!-- 로그를 남기는 파일의 용량이 50KB가 넘으면 이를 압축 파일로 만들고 새로 로그 파일로 만들라는 정책 --> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>50KB</MaxFileSize> </triggeringPolicy> <!-- 파일을 덮어쓰는 정책 --> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <!-- <FileNamePattern>C:\LogExample\logexample2.%i.log.zip</FileNamePattern> --> <FileNamePattern>logs/zip/logexample2.%i.log.zip</FileNamePattern> <!-- MinIndex가 1이고, MaxIndex가 10이므로, 위의 파일 이름 패턴에 따라 아래의 로그 파일이 생길 것이다. logexample2.1.log.zip logexample2.2.log.zip .... logexample2.10.log.zip 이 상태에서 또 10KB가 넘으면 logexample2.1.log.zip이 된다. --> <MinIndex>1</MinIndex> <MaxIndex>10</MaxIndex> </rollingPolicy> </appender> <logger name="org.springframework.web" level="info"/> <logger name="org.thymeleaf" level="info"/> <logger name="org.hibernate.SQL" level="info"/> <logger name="org.quartz.core" level="info"/> <logger name="org.h2.server.web" level="info"/> <logger name="org.mariadb.jdbc" level="info"/> <logger name="org.mysql.jdbc" level="info"/> <!-- log4jdbc 옵션 설정 --> <logger name="jdbc" level="OFF" /> <!-- 커넥션 open close 이벤트를 로그로 남긴다. --> <logger name="jdbc.connection" level="OFF" /> <!-- SQL문만을 로그로 남기며, PreparedStatement일 경우 관련된 argument 값으로 대체된 SQL문이 보여진다. --> <logger name="jdbc.sqlonly" level="OFF" /> <!-- SQL문과 해당 SQL을 실행시키는데 수행된 시간 정보(milliseconds)를 포함한다. --> <logger name="jdbc.sqltiming" level="DEBUG" /> <!-- ResultSet을 제외한 모든 JDBC 호출 정보를 로그로 남긴다. 많은 양의 로그가 생성되므로 특별히 JDBC 문제를 추적해야 할 필요가 있는 경우를 제외하고는 사용을 권장하지 않는다. --> <logger name="jdbc.audit" level="OFF" /> <!-- ResultSet을 포함한 모든 JDBC 호출 정보를 로그로 남기므로 매우 방대한 양의 로그가 생성된다. --> <logger name="jdbc.resultset" level="OFF" /> <!-- SQL 결과 조회된 데이터의 table을 로그로 남긴다. --> <logger name="jdbc.resultsettable" level="info" /> <logger name="springfox" level="WARN"/> <logger name="org.hibernate" level="WARN"/> <logger name="org.apache" level="WARN"/> <logger name="org.apache.http.imp.conn" level="WARN"/> <!-- root는 글로벌 로거를 의미하며, 위의 logger에 해당하지 않으면 root 로거가 실행된다. --> <root level="info"> <!-- 3.유형 로그 사용 --> <appender-ref ref="fileAppender" /> </root> </configuration>
5. DriverSpy 라이브러리 사용 및 SQL 로그 보기
1) 라이브러리 등록
<dependency> <groupId>org.bgee.log4jdbc-log4j2</groupId> <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId> <version>1.16</version> </dependency>
2) log4jdbc.log4j2.properties 파일을 resouces 위치에 생성후 다음과 같이 입력
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator log4jdbc.dump.sql.maxlinelength=0
3) application.properties
드라이브 클래스네임 다음과 같이 변경
spring.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
jdbc와 mysql 사이에 log4jdbc 추가
jdbc:log4jdbc:mysql:
#MySQL 연결설정 #spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #spring.datasource.url=jdbc:mysql://localhost:3306/songjava?serverTimezone=UTC spring.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy spring.datasource.url=jdbc:log4jdbc:mysql://localhost:3306/songjava?characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.username=songjava spring.datasource.password=1111
6. 로그 최대한 출이기
<logger name="org.springframework.web" level="info"/> <logger name="org.thymeleaf" level="info"/> <logger name="org.hibernate.SQL" level="info"/> <logger name="org.quartz.core" level="info"/> <logger name="org.h2.server.web" level="info"/> <logger name="org.mariadb.jdbc" level="info"/> <logger name="org.mysql.jdbc" level="info"/> <!-- log4jdbc 옵션 설정 --> <logger name="jdbc" level="OFF" /> <!-- 커넥션 open close 이벤트를 로그로 남긴다. --> <logger name="jdbc.connection" level="OFF" /> <!-- SQL문만을 로그로 남기며, PreparedStatement일 경우 관련된 argument 값으로 대체된 SQL문이 보여진다. --> <logger name="jdbc.sqlonly" level="OFF" /> <!-- SQL문과 해당 SQL을 실행시키는데 수행된 시간 정보(milliseconds)를 포함한다. --> <logger name="jdbc.sqltiming" level="DEBUG" /> <!-- ResultSet을 제외한 모든 JDBC 호출 정보를 로그로 남긴다. 많은 양의 로그가 생성되므로 특별히 JDBC 문제를 추적해야 할 필요가 있는 경우를 제외하고는 사용을 권장하지 않는다. --> <logger name="jdbc.audit" level="OFF" /> <!-- ResultSet을 포함한 모든 JDBC 호출 정보를 로그로 남기므로 매우 방대한 양의 로그가 생성된다. --> <logger name="jdbc.resultset" level="OFF" /> <!-- SQL 결과 조회된 데이터의 table을 로그로 남긴다. --> <logger name="jdbc.resultsettable" level="info" /> <logger name="springfox" level="WARN"/> <logger name="org.hibernate" level="WARN"/> <logger name="org.apache" level="WARN"/> <logger name="org.apache.http.imp.conn" level="WARN"/>
7. LOG 파일로 남기기
<!-- 3.유형 : 파일로 로그를 남김 --> <appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- <file>c:\LogExample\logexample2.log</file> --> <file>logs/logexample2.log</file> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <Pattern> %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n </Pattern> </encoder> <!-- 로그를 남기는 파일의 용량이 50KB가 넘으면 이를 압축 파일로 만들고 새로 로그 파일로 만들라는 정책 --> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>50KB</MaxFileSize> </triggeringPolicy> <!-- 파일을 덮어쓰는 정책 --> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <!-- <FileNamePattern>C:\LogExample\logexample2.%i.log.zip</FileNamePattern> --> <FileNamePattern>logs/zip/logexample2.%i.log.zip</FileNamePattern> <!-- MinIndex가 1이고, MaxIndex가 10이므로, 위의 파일 이름 패턴에 따라 아래의 로그 파일이 생길 것이다. logexample2.1.log.zip logexample2.2.log.zip .... logexample2.10.log.zip 이 상태에서 또 10KB가 넘으면 logexample2.1.log.zip이 된다. --> <MinIndex>1</MinIndex> <MaxIndex>10</MaxIndex> </rollingPolicy> </appender>
소스 :
참조:
2) https://congsong.tistory.com/24
댓글 ( 4)
댓글 남기기