오늘은 어디로 갈까...

log4j Filter 본문

낙서

log4j Filter

剛宇 2009. 2. 27. 11:53
log4j에는 필터(Filter)기능이 존재한다. (1.2 기준으로 설명하겠다.)
log4j 로깅이 일어날때, 즉, LoggingEvent가 발생하게 될때, 이 필터를 이용해해서 해당 이벤트를 무시할 수 있는것이다.
즉, 로깅(logging) 할때 특정 부분은 출력을 안할 수도 있고, 특정 부분만 출력하게 할 수 있다는 것이다.
하지만 주의할것은 DOMConfigurator은 이 필터 기능을 지원하는데, PropertyConfigurator은 지원하지 않는다.
쉽게 말하자면 xml 설정파일을 이용하면 필터기능을 사용할 수 있고, property 설정 파일을 사용하면 필터기능을 사용할 수 없다는 것이다.

이 필터 기능을 사용하기위해서는 org.apache.log4j.spi.Filter 클래스를 상속받아 decide(LoggingEvent) 메소도를 구현해줘야한다.
이 decide(LoggingEvent)  메소드는 3가지의 값(DENY, NEUTRAL, ACCEPT)을 반환하게 된다.
DENY는 로그 이벤트를 버린다는 뜻이다. 다음 필터가 존재하도 그 필터들은 무시해버린다. 즉, 무조건 로그 출력을 안하겠다는 것이다.
NEUTRAL은 다음 필터에게 그 결과를 인도하겠다는 뜻이다. 다음 필터가 존재하면 그 필터의 결과값을 사용하고, 다음 필터가 존재하지 않으면 이벤트 로그를 출력한다는것이다.
ACCEPT은 로그 이벤트를 출력한다는 뜻이다. 다음 필터가 존재하도 그 필터들은 무시해버린다. 즉, 무조건 로그 출력을 하겠다는 것이다.

일단 한번 만들어보자. MessageException이 발생하면 로그에 출력을 안하게 하는 필터를 만들어보겠다.

MessageException 클래스를 만들자.
package test.log4j.filter;

public class MessageException extends Exception {

	private static final long serialVersionUID = 7274464247199185938L;

	public MessageException(String message) {
		super(message);
	}
	
    public MessageException(String message, Throwable cause) {
        super(message, cause);
    }
}


간단하 log4j.xml을 만들어보자.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%d{HH:mm:ss.SSS}] %-5p %C{1}.%M(%F:%L) - %m%n"/>
        </layout>
    </appender>

    <!-- Root -->
    <root>
        <level value="DEBUG"/>
        <appender-ref ref="console"/>
    </root>
</log4j:configuration>


log4j로 로그를 출력해보겠다.(당연히 log4j.jar가 클래스패스에 잡혀있어야 작동한다.)
package test.log4j.filter;

import org.apache.log4j.Logger;

public class FilterTest {

	public static void main(String[] args) {
		Logger logger = Logger.getLogger(FilterTest.class);
		logger.debug("안녕하세요.");
		
		MessageException me = new MessageException("저는 메시지익셉션입니다.");
		logger.debug("메시지익셉션 발생", me);
		
		Exception e = new Exception("저는 그냥 익셉션입니다.");
		logger.debug("익셉션 발생", e);
	}
}

설정 파일에 정의한데로, 아래처럼 출력이 된다.

[11:50:10.484] DEBUG FilterTest.main(FilterTest.java:9) - 안녕하세요.
[11:50:10.500] DEBUG FilterTest.main(FilterTest.java:12) - 메시지익셉션 발생
test.log4j.filter.MessageException: 저는 메시지익셉션입니다.
    at test.log4j.filter.FilterTest.main(FilterTest.java:11)
[11:50:10.500] DEBUG FilterTest.main(FilterTest.java:15) - 익셉션 발생
java.lang.Exception: 저는 그냥 익셉션입니다.
    at test.log4j.filter.FilterTest.main(FilterTest.java:14)

자 그럼, test.log4j.filter.MessageException은 로그에서 출력이 안되도록 필터를 만들자.
package test.log4j.filter;

import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;

public class ExceptionFilter extends Filter {

	@Override
	public int decide(LoggingEvent event) {
		ThrowableInformation info = event.getThrowableInformation();
		if (info != null && info.getThrowable() instanceof MessageException) {
			return DENY;
		} else {
			return NEUTRAL;
		}
	}
}

log4j 설정 파일에 필터를 추가하자.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%d{HH:mm:ss.SSS}] %-5p %C{1}.%M(%F:%L) - %m%n"/>
        </layout>
        <filter class="test.log4j.filter.ExceptionFilter" />
    </appender>

    <!-- Root -->
    <root>
        <level value="DEBUG"/>
        <appender-ref ref="console"/>
    </root>
</log4j:configuration>

다시 실행해보자. 아래와 같은 결과가 나올것이다.
[11:51:17.921] DEBUG FilterTest.main(FilterTest.java:9) - 안녕하세요.
[11:51:17.937] DEBUG FilterTest.main(FilterTest.java:15) - 익셉션 발생
java.lang.Exception: 저는 그냥 익셉션입니다.
    at test.log4j.filter.FilterTest.main(FilterTest.java:14)

우리가 의도한데로 MessageException은 로그에 출력되지 않는다.