간단한 Log4J 요점 정리 학술

Log4j 요점 정리

소개
일반적으로 로깅 인터페이스는 아주 단순한데 반해서, 실제 로그가 출력되는 양상은 굉장히 다양한 모습을 띄고 있기 때문에 이미 잘 만들어진 로깅 라이브러리가 필수적이다. 가령 개발이나 디버깅 시에 일반적으로 사용하는 콘솔 로깅 모드부터 시작해서, 단순히 파일 하나에 누적해서 로그를 기록하거나, 여러 개의 파일을 돌려가면서 로그를 기록하거나, 데이터베이스에 로그를 기록하거나, 심지어 디스크가 여의치 않은 경우 또는 보안을 이유로 네트워크를 통해 로그를 기록하는 경우도 있다. 이 모든 다양한 경우의 로깅을 직접 구현하기란 시간 소모적이면서 피곤한 일이다. 여러가지 출력 방법을 동시에 사용하는 경우도 있다. (가령 콘솔에 출력하면서 롤링 로그 파일로 남긴다든지.)

게다가 상황에 따라 출력할 요소를 설정 가능하게 하는 것도 역시 귀찮은 일이다. 가령 어떤 경우에는 스레드 ID를 찍거나, 클래스, 메소드, 줄 번호를 기록하고 싶을 때도 있고, 날짜 포맷도 원하는대로 쓰고 싶을 것이다. 개행을 몇 번 할 것인가 등등 사소한 로그 포맷팅도 실제로는 꽤 중요한 문제가 된다.

소개는 이 정도로 하고 실제 당장 쓰는데 필요한 정도만 알아보도록 하자. 사실 다양한 로그 설정은 개발 다 끝나고 나서 알아도 설정 파일만 바꾸면 되기 때문에 처음부터 다 알고 시작할 필요는 없다. 필요하면 설정을 복사해서 고쳐 쓰자.

구성
Log4j는 3개의 구성 요소가 있다. Logger, Appender, Layout.

Logger 계층
Logger는 이름이 붙어있다. 이름은 대소문자를 구분하고, 계층적 작명 규칙을 따른다. 가령 “com.foo”라는 이름을 가진 Logger는 “com.foo.Bar”라는 Logger의 부모가 된다. Root Logger는 최상위 계층에 존재하는데, 항상 존재하고 이름이 따로 없다는게 좀 다르다. 굳이 Root logger를 쓰려면 Logger.getRootLogger를 쓰면 된다. 보통은 아래와 같이 Logger.getLogger를 호출한다.

보통은 굳이 문자열로 Logger 이름을 지정하기보단 그냥 클래스 자체를 넘겨서 사용한다. 알아서 해준다. Logger.getLogger(ClassName.class); 이렇게.

로그 레벨 쓰는 것으로 DEBUG, INFO, WARN, ERROR, FATAL이 있다. 물론 레벨 재정의도 가능하긴 하지만 굳이 그럴 필요 없다. 이 로그 레벨을 INFO로 지정해놨으면, DEBUG 로그 아무리 찍어도 기록되지 않는다.

그러면 아까 말했던 계층은 어디에 써먹으라고 있느냐. 상위 계층의 Logger를 대상으로 Level을 지정해놓으면 별도의 설정으로 덮어쓰지 않는 한 하위의 모든 Logger에 대해서도 유효하다. 그런고로 Root Logger의 Log Level을 설정하면 그게 기본값으로 다 먹히게 될거고, 특정 라이브러리의 패키지 이름을 찍어놓으면 그 Logger와 하위 Logger에 대해 Log Level이 유효하다. 이게 되기 때문에 하이버네이트 자체적으로도 Log4j를 써서 로그를 찍어내지만 하이버네이트만 “골라내서” 로그를 찍지 않도록 할 수 있는 것이다. 게다가 나중에 로그를 확인할 때, 이 로그가 어느 Logger에서 나온 것인지 확인함으로써 어느 컴포넌트에서 발생한 로그인지 즉각 알 수 있게 된다.

얘기가 길어졌는데, 실제로 쓸 때는 아래와 같이 간단히 쓰면 된다.
import org.apache.log4j.Logger;
private static Logger logger = Logger.getLogger(클래스.class);

logger.info(“info world~”);
logger.debug(“debug world~”);

나머지는 안 봐도 비디오겠지. 그리고 출력할 로그 문자열을 붙이는 것도 비용이 들기 때문에 가끔 logger.isDebugEnabled()를 먼저 확인하는 센스가 있으면 된다. logger.isInfoEnabled() 등 레벨별로 다 있다.

Appender 와 Layout
위에서 말했듯이 아주 다양한 Appender들이 존재한다. 근데 보통 아래 정도의 설정이면 콘솔과 롤링 로그 파일을 쓸 수 있으니 당장 쓰기에는 무난하다. 하이버네이트를 쓰는 경우가 많이 있으니 이쪽은 로그를 ERROR만 찍도록 해놓았다. 루트에 log4j.properties 파일을 아래와 같이 만들어놓자. XML로 설정할 수도 있는데 필요하면 알아서 찾아보자.

레이아웃을 PatternLayout 쓰고 ConversionPattern을 저렇게 써놓으면 지정된 Layout 기능을 이용해서 로그 포맷팅을 해준다. % 붙은 것들도 로그 찍어보면 뭔지 딱 알 수 있을거다. %m은 메시지고 %n은 개행, 뭐 이런 식이다. 이 외에도 HTML layout 이라든지 XMLLayout 같은 것들이 있는데 일반적인 상황에서는 다 필요 없다.

log4j.rootLogger = DEBUG, stdout, dailyfile
log4j.logger.org.hibernate = ERROR

log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d] %5p ({%t} [%M]) - %m%n

log4j.appender.dailyfile.Threshold = DEBUG
log4j.appender.dailyfile = org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyfile.File = blahblah.log
log4j.appender.dailyfile.layout = org.apache.log4j.PatternLayout
log4j.appender.dailyfile.layout.ConversionPattern=[%d] %5p ({%t} [%M]) - %m%n


트랙백

이 글과 관련된 글 쓰기 (트랙백 보내기)
TrackbackURL : http://www.xeraph.com/tb/4400587 [도움말]

덧글

  • 2008/06/04 10:28 # 삭제 답글 비공개

    비공개 덧글입니다.
  • xeraph 2008/06/04 11:00 #

    넹~ 맞아요.. 이글루스 원래 방명록 없어요 ㅎㅎ
    가서 방명록에 인사하려고 했더니 OpenID가 안 먹네요 ㅋㅋ
댓글 입력 영역