logback 사용하기(1)

logback에 대한 자세한 설명은 다른사이트를 참조하세요.

https://beyondj2ee.wordpress.com/2012/11/09/logback-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0-reasons-to-prefer-logback-over-log4j/

 

logback을 사용하려면 maven을 사용할경우  아래와 같이 추가하시면 

기본적인 기능들은 사용하실 수 있습니다.

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.1.3</version>
</dependency>

 

logback은 자체적으로 설정 파일을 reloading 할 수 있는 기능을 제공한다.

<configuration scan="true" scanPeriod="30 seconds" >

 

logback 테스트 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BasicLog {

	private static Logger logger = LoggerFactory.getLogger(BasicLog.class);
	
	public static void main(String[] args) {
		logger.trace("BasicLog.");
		logger.debug("BasicLog.");
		logger.info("BasicLog.");
		logger.warn("BasicLog.");
		logger.error("BasicLog.");

	}

}

logback.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds" >

	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<layout class="ch.qos.logback.classic.PatternLayout">
		      <encoder>
		      <Pattern>
		      	<!--
		      	%d{yyyy-MM-dd HH:mm:ss} : 년월일 시분초
		      	%thread : thread name 
		      	%-5level : log level , -5는 출력 고정폭 값
		      	%logger{length} :Logger name의 이름, {length}는 자리수
		      	%msg : log message %message은 alias
		      	%n : 줄바꿈
		      	
		      	org.fusesource.jansi:jansi:1.8 가 필요함.
                        Linux ,Mac OS X 기본적으로 지원함
                        <withJansi>true</withJansi>설정후 사용해야함
		      	%highlight : log level 별로 color가 다르게 나옴
		      	-->
		    %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
		      	
		      </Pattern>
		      </encoder>
		</layout>
	</appender>

	 
	<root level="debug" >
		<appender-ref ref="STDOUT" />
	</root>

</configuration>

 

위와 같이 생성한후 실행을 하시면 아래와 같이 콘솔을 이용한 출력을 볼수 있습니다.

2016-02-04 15:21:50 [main] DEBUG com.hello.logback.basic.BasicLog - BasicLog.
2016-02-04 15:21:50 [main] INFO  com.hello.logback.basic.BasicLog - BasicLog.
2016-02-04 15:21:50 [main] WARN  com.hello.logback.basic.BasicLog - BasicLog.
2016-02-04 15:21:50 [main] ERROR com.hello.logback.basic.BasicLog - BasicLog.

 

좀더 다양한 로그를 이용하기 위해서는 다른종류의 appender를 이용하시면됩니다.

appender 종류 확인하기

 

1.mdc를 이용한 logging

아래와 같이 MDC.put 을 logging에 필요한 다양한것들을 추가할수 있습니다.

MDC.put("userid", "scott");
logger.info("start application.");
		
logger.info("end application.");
	    
MDC.remove("userid");

 logback.xml파일에 아래와 같은 pattern을 추가하시면 로그에 출력되는것을 확인할수 있습니다.

%X{userid} : userid의 값
%mdc : all mdc key=value (host=127.0.0.1, userid=dec)

 

2016-02-04 15:28:01 [userid=scott] [scott] [main] INFO  com.hello.logback.mdc.MdcLog - start application.

2016-02-04 15:28:01 [userid=scott] [scott] [main] INFO  com.hello.logback.mdc.MdcLog - end application.

 

web application을 개발할 경우 filter를 이용하여

 public class MDCServletFilter implements Filter{
	
     public void doFilter(ServletRequest request, ServletResponse response,
                 FilterChain chain) throws IOException, ServletException {
	            
	HttpServletRequest httpRequest = (HttpServletRequest) request;
	MDC.put(REMOTE_HOST, httpRequest.getRemoteHost());
	HttpSession session = httpRequest.getSession();
	if (session != null && session.getAttribute(USER_ID_MDC_KEY) != null){
	     MDC.put(USER_ID, (String)session.getAttribute(USER_ID));
	} 
	try{
	     chain.doFilter(request, response); 
	}finally{
	     MDC.clear();
	}	
    }	
}

 MDC.put 을 추가하여  원하는 값을 logging 할수 있습니다.

 

2.파일로그

ch.qos.logback.core.rolling.RollingFileAppender을 이용하면 일자별 로그를 생성할수 있습니다.

maxFileSize값을 설정할경우 maxFileSize값을 넘어갈경우 아래와 같이 생성된다.

K-001

maxHistory값은 월을 뜻하며 설정한 월값을 지난 로그파일은 자동으로 삭제해준다.

<property name="LOG_HOME" value="d:\\log\\" />

<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
	  <file>${LOG_HOME}/log.txt</file>
	  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
	    <!-- rollover daily -->
	    <fileNamePattern>${LOG_HOME}/log-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
	    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
	      <!-- or whenever the file size reaches 100MB -->
	      <maxFileSize>100MB</maxFileSize>
	    </timeBasedFileNamingAndTriggeringPolicy>
	    
	    <!-- maximum number of archive files to keep, deleting older files. For example, if you specify monthly rollover, and set maxHistory to 6, then 6 months worth of archives files will be kept with files older than 6 months deleted. -->
	    <maxHistory>6</maxHistory>
	    
	  </rollingPolicy>
	  <encoder>
	    <pattern>
	    	%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
	    </pattern>
	  </encoder>
</appender>

 

 

3.sift를 이용한 파일별 logging

아래와 같이 파일을 분리해서 logging하고자 하는 값을 설정한다.

MDC.put("userid", "scott");
logger.info("scott start application.");
logger.info("scott end application.");
		
MDC.put("userid", "tiget");
logger.info("tiget start application.");
logger.info("tiget end application.");
	    
MDC.clear();

 

SifingAppender를 이용하여 key에 분리하고자 하는값을 설정한다.

<property name="LOG_HOME" value="d:\\log\\" />
	
<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
     <discriminator>
         <key>userid</key>
         <defaultValue>unknown</defaultValue>
     </discriminator>
         
     <sift>
	  <appender name="FILE-${userid}"
			class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${LOG_HOME}/${userid}.log</file>
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<Pattern>
			%d{yyyy-MM-dd HH:mm:ss} %mdc [%thread] %-5level %logger{36} - %msg%n
			</Pattern>
		</encoder>

		<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
			<FileNamePattern>${LOG_HOME}/${userid}.%i.log.zip</FileNamePattern>
			<MinIndex>1</MinIndex>
			<MaxIndex>10</MaxIndex>
		</rollingPolicy>

		<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
			<MaxFileSize>10MB</MaxFileSize>
		</triggeringPolicy>
		
		
	  </appender>
	</sift>
</appender>

 

아래와 같이 userid별로 생성된 log file을 볼수 있다.

K-002

4.AsyncAppender를 이용한 logging

비동기 logging의 경우 Method name, Line Number 등이 출력되지 않는다.

TRACE, DEBUG and INFO 레벨의 로그는 기본적으로 20% 유실 될 수 있다

비동기 큐에 로그가 쌓인 상태에서 프로세스가 종료되면 해당 로그는 기록되지 않고 종료된다.

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
	<layout class="ch.qos.logback.classic.PatternLayout">
	      <Pattern>
	     	%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
	      </Pattern>
	</layout>
</appender>
	
<appender name="async" class="ch.qos.logback.classic.AsyncAppender">
      <!-- 
		Queue의 크기중에 비어있는 부분이 discardingThreshold 비율 이하인 경우 INFO 레벨 이하의 로그는 저장하지 않는다.
		모든 로그 이벤트를 처리하기 위해서는 0으로 discardingThreshold을 설정합니다 
		 -->
		<discardingThreshold>0</discardingThreshold>
		<!-- 큐의 최대 용량. 기본적으로 QUEUESIZE는 256으로 설정됩니다. -->
	    <queueSize>10000</queueSize>
	    <!-- 해당 로그 이벤트 정보를 Queue에 추가하는 시점에 로그를 호출한 정보 (callerData)를 추출할지 여부를 결정하는 속성
	    <includeCallerData>boolean</includeCallerData>
	     -->
	     <!--
	     (밀리 초) 큐의 최대 flush timeout 시간을 지정합니다.처리 할 수​​없는 이벤트가 삭제됩니다.
	     <maxFlushTime>int</maxFlushTime> 
	      -->
      <appender-ref ref="STDOUT" />
</appender>

 

 테스트 소스 다운로드 : https://github.com/liyobi/logback-appender-case