프로그램을 개발하거나 운영할 때 발생하는 문제점을 추적하거나 운영 상태를 모니터링하기 위한 텍스트 형식의 데이터.
애플리케이션에서 로깅 객체를 사용할 수 있는 기본적인 구조만을 제공하고 실제 로깅처리는 다른 구현체를 쓸 수 있도록 해주는 범용 프레임워크.
라이브러리 추가설치 필요(https://logging.apache.org/log4j/1.2/download.html)
- slf3j-simple-1.7.4.jar : 간단한 콘솔 출력
- slf4j-log4j-1.7.5.jar : LOG4J 연동에 필요한 것
두 개의 구현체는 절대 동시에 사용 불가
1. 라이브러리 설치
- log4j-1.2.17.jar
- slf4j12-1.7.5.jar (slf4j와 연동)
2. log4j 설정 파일 만들기 : 로그 메시지의 형식, 저장 방식 등을 다양하게 지정할 수 있다.
-> [src] 루트 폴더에 넣기
- 자바의 속성 파일
- xml 형식
3. 요소
- root : 기본 로그 설정
- logger : 관리할 로거를 정의
- appender : root에서 설정한 appender 이름에 대한 실제적인 appender와 레이아웃 등을 지정한다.
root(공통기본설정)와 logger(특정로그설정)는 기본적으로 같은 개념으로 로깅 설정에 필요한 그룹
4. appender 종류
- ConsoleAppender : 콘솔에 로그메시지 출력
- FileAppender : 파일에 로그메시지 기록
- RollingFileAppender : 파일에 기록하되, 파일크기가 일정수준 이상이 되면 다른 이름으로 저장하고 새롭게 기록
- DailyRolling FileAppender : 파일에 로그 메시지 기록하되, 하루 단위로 파일을 변경해서 저장
- SMTPAppender : 로그메시지를 메일로 전송
5. layout 종류
- DateLayout : 로그 메시지를 날짜 중심으로 간단히 기록
- HTMLLayout : HTML 형식으로 기록
- PatternLayout : 사용자 지정패턴에 따라 기록
- SimpleLayout : 레벨-메시지 형식의 가장 간단한 로그
- XMLLayout : xml 형식으로 기록
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN"
"http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
//xml 파일 선언부
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
//appender 1 : stdout 이름의 콘솔에 로그메시지를 출력하는 appender
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="[%d{HH:mm:ss}] [%c{1}] [%p] %m %n" />
</layout>
</appender>
// appender 2 : dailyout 이름의 파일에 하루 단위로 파일을 변경하여 저장하는 appender
<appender name="dailyout" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="c:/tmp/dailyout.log"/>
<param name="Append" value="true"/>
<param name="DatePattern" value="'.'yyMMdd"/>
<layout class="org.apache.log4j.PatternLayout">
//로그 메시지를 사용자지정패턴에 따라 기록
<param name="ConversionPattern" value="%t>
[%d{yyyy-MM-dd HH:mm:ss}] [%c{1}] [%L] [%p] %m %n"/>
</layout>
</appender>
//appender 3 : 로그파일이 특정 크기가 되면 새로운 파일을 생성하는 RollingFileAppender
//레이아웃은 HTMLLayout으로 지정 : 웹브라우저를 통해 더욱 깔끔한 로그 기록 조회가능
<appender name="rolling" class="org.apache.log4j.RollingFileAppender">
<param name="file" value="c:/tmp/rolling.log.html"/>
<param name="Append" value="true"/>
<param name="MaxFileSize" value="10kb"/>//로그파일크기
<param name="MaxBackupIndex" value="1"/>
<layout class="org.apache.log4j.HTMLLayout" />
//로그메시지를 html 형식으로 기록
</appender>
//해당 패키지의 클래스에서 출력되는 로그들을 처리하려는 로거
//INFO 레벨 이상에 대해 stdout과 dailyout appender를 이용해 로그처리
<logger name="jspbook">//java 패키지의 클래스에 대한 로그처리
<level value="INFO" />
<appender-ref ref="dailyout" />
</logger>
<logger name="org.apache.jsp">//jsp파일에 대한 로그 처리
'org.apache.jsp'가 해당 jsp파일의 패키지 이름이 된다.
<level value="WARN" />
<appender-ref ref="rolling" />
</logger>
<root>
<level value="INFO" />
<appender-ref ref="stdout" />
<appender-ref ref="dailyout" />
</root>
</log4j:configuration> //log4j 설정
웹 애플리케이션 로깅은 기본적으로 사용할 수 있는 로깅 방법으로, 주로 시스템 로깅 처리를 위해 이용한다. 컨테이너 제공 로깅은 javax.servlet.ServletContext 클래스에서 제공하는 API를 이용한다.
메서드 | 내용 |
---|---|
public void log(String msg) | 컨테이너 로깅 시스템을 통해 문자열 형태의 내용을 출력한다. |
public void log(String msg, Throwable throwable) | Throwable 클래스는 모든 자바 오류와 예외의 슈퍼 클래스 |
웹 애플리케이션 요청에 대해 request 및 response를 가로채고, 체인 형식의 적용을 통해 동적인 애플리케이션 운영을 가능하게 하는 서블릿 스펙이다. 필터속성을 이용해 시스템 로그와 애플리케이션 로그의 중간적인 정보를 제공하는 로깅을 구현할 수 있다.
필터와 마찬가지로 리스너 역시 표준 서블릿 스펙이므로, 모든 웹 애플리케이션에서 호환 가능한 로깅을 구현할 수 있다. 리스너의 경우 컨테이너의 특정 이벤트에 기반을 둔 로깅 구현에 적합하며, 필터와 동일하게 시스템 로그와 애플리케이션 로그의 중간적인 정보를 처리한다.
//해당 패키지의 클래스에서 출력되는 로그들을 처리하려는 로거
//INFO 레벨 이상에 대해 stdout과 dailyout appender를 이용해 로그처리
<logger name="jspbook">//패키지명
<level value="INFO" />
<appender-ref ref="dailyout" />
</logger>
//
<logger name="org.apache.jsp">//패키지명
<level value="WARN" />
<appender-ref ref="rolling" />
</logger>
ServletContextListener를 통해 웹 애플리케이션을 시작하고 종료할 때 로그를 생성하도록 한다.
package jspbook;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.slf4j.*;
@WebListener
public class LogContextListener implements ServletContextListener {
Logger log; //로그 처리를 위한 로거 객체
//리스너 종료 시 로그 메시지 출력
public void contextDestroyed(ServletContextEvent arg0) {
log.info("LogContextListener stop");
}
//리스너 초기화 시 로그 메시지 출력
public void contextInitialized(ServletContextEvent arg0) {
log = LoggerFactory.getLogger(this.getClass());
log.info("LogContextListener start");
}
}
package jspbook;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import org.slf4j.*;
//모든 폴더 요청에 대해서 필터 적용
@WebFilter("/*")
public class LogFilter implements Filter {
//로그 처리를 위한 로거 객체
Logger log;
//필터 종료 시 로그메시지
public void destroy() {
log.info("LogFilter stop");
}
//필터 실행 시 로그메시지
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain arg2) throws IOException, ServletException {
log.debug("LogFilter run"+request.getRemoteAddr());
arg2.doFilter(request, response);
}
//필터 초기화 시 로그메시지
public void init(FilterConfig arg0) throws ServletException {
log = LoggerFactory.getLogger(this.getClass());
log.info("LogFilter start");
}
}