본문 바로가기
Web Program/Java Lecture

Log4j란

by 현이빈이 2008. 8. 13.
반응형
JAVA & WebPrograming 블로그 | 승진이
원문 http://blog.naver.com/sj99yang/140000945742

1.     LOG4J 란 ?
Log for Java 란 뜻이다. Jakarta-project 에서 Java를 위한 프로젝트중 하나이다.

현재 Java 1.4 스팩에 포함 되어 있는 내용이기도 하다.

log4j는 프로그래머가 로그문의 출력을 다양한 대상으로 할 수 있도록 도와주는 도구이다.

애플리케이션에 문제가 생겼을 때, 로깅을 활성화하면 문제의 위치를 찾을 수 있으므로 도움이 된다. log4j를 사용하면 애플리케이션의 실행코드를 수정하지 않고 런타임에 로깅의 활성화를 할 수 있다. log4j 패키지는 성능상의 높은 비용을 들이지 않으면서도 배포코드에 로그문장을 남겨놓을 수 있도록 디자인되었다. 그러므로 로깅의 속도(정확히 말하자면 로깅을 하지 않을 때의 속도)가 중요하게 다루어졌다.

동시에 로그 결과는 짧은 시간에 감당하기 어렵게 될만큼 커질 수 있다. log4j의 독특한 특징 중 하나는 계층적 로거라는 개념이다. 로거를 사용하면, 어떤 로그문이 출력되게 할 지 임의의 단위로 조정할 수 있다.

log4j는 속도와 유연성, 이 두 마리의 토끼를 염두에 두고 디자인 되었다. 이 두 요구사항 사이에서 균형잡기는 꽤나 까다로운데, log4j는 잘 하고 있다고 생각한다.

참고 : Log는 기록을 남긴다는 명령어 이기도 하며 OS 에서의 감시자 기록자로서의 역할을 한다.


2.     LOG4J는 신뢰성(reliablity)이 있는 로깅 시스템인가?
log4j는 신뢰성(작업 혹은 통신이 손실, 중복 없이, 선입선출로 합리적인 시간 안에 반드시 수행되어야 신뢰성을 있다고 한다:역주)을 갖고 있지 않다. log4j는 best-effort(UDP 프로토콜처럼 불완전한 신뢰성을 제공할 때 best-effort라 한다:역주)와 fail-stop(오류 발생시, 불완전한 동작을 하지 않고 바로 멈추는 것을 의미한다:역주)의 성질을 가진 로깅 시스템이다

fail-stop은 log4j가 잠재적으로 프로그램의 오동작을 유발할 수 있는, 예상치 못한 예외를 던지지 않을 거라는 의미이다. 만일 어떤 이유로든, log4j가 예외를 던지면, log4j-user@jakarta.apache.org 메일링 리스트로 알려주기 바란다. 예상치 못한 예외는 즉각적인 조치가 필요한 심각한 버그로 간주된다.

이에 더해서 log4j는 출력 스트림을 열 수 없거나, 쓸 수 없거나, 스트림이 다 찼을 때 출력을 System.out 이나 System.err로 대신 내보내지 않는다. 이것은 로깅 실패 때문에 사용자의 화면이 엉망이 되는 일이 없게 하기 위해서이다. 하지만, log4j가 로깅을 할 수 없을 때, 이를 알리기 위해 하나의 메시지를 System.err로 출력하기는 한다.




3. LOG4J의 특징
      log4j는 속도에 최적화되어있다.

      log4j는 이름있는 로그 계층에 기반한다.

      log4j는 fail-stop이지만 신뢰성은 없다.

      log4j는 thread-safe하다(멀티스레드 환경에서 사용해도 안전하다:역주).

      log4j는 융통성이 풍부하다.

      설정 파일은 property 파일과 XML 형식으로 실행 중 수정 적용 가능하다

      log4j는 처음부터 자바의 예외를 처리하기 위해 디자인되었다.

      log4j는 출력을 파일, 콘솔, java.io.OutputStream, java.io.Writer, TCP를 사용하는 원격서버,
     원격 Unix Syslog 데몬, 원격 JMS 구독자, 윈도우NT EventLog로 보낼 수 있고, 심지어는
     e-mail로 보낼 수도 있다.

      log4j는 다음 5단계의 장애레벨을 사용한다. DEBUG, INFO, WARN, ERROR, FATAL.

      로그 출력의 형식은 Layout 클래스를 확장함으로써 쉽게 바꿀 수 있다.

      로그가 출력될 대상과 출력 방법은 Appender 인터페이스로 할 수 있다.

      log4j는 로거 하나에 다수의, 출력을 담당하는 appender를 할당할 수 있다.

      log4j는 국제화를 지원한다.

4.     로그 출력 형태
로그 출력은 여러가지 방법으로 커스터마이즈될 수 있다. 더 나아가 독자적인 Layout 인터페이스를 구현해서 완전하게 출력 형식을 변경할 수 있다.

"%r [%t] %-5p %c{2} %x - %m%n" 패턴으로 PatternLayout을 사용했을 때 출력 예는 다음과 같다.


176 [main] INFO  examples.Sort - Populating an array of 2 elements in reverse order.

225 [main] INFO  examples.SortAlgo - Entered the sort method.

262 [main] DEBUG SortAlgo.OUTER i=1 - Outer loop.

276 [main] DEBUG SortAlgo.SWAP i=1 j=0 - Swapping intArray[0] = 1 and intArray[1] = 0

290 [main] DEBUG SortAlgo.OUTER i=0 - Outer loop.

304 [main] INFO  SortAlgo.DUMP - Dump of interger array:

317 [main] INFO  SortAlgo.DUMP - Element [0] = 0

331 [main] INFO  SortAlgo.DUMP - Element [1] = 1

343 [main] INFO  examples.Sort - The next log statement should be an error message.

346 [main] ERROR SortAlgo.DUMP - Tried to dump an uninitialized array.

        at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58)

        at org.log4j.examples.Sort.main(Sort.java:64)

467 [main] INFO  examples.Sort - Exiting main method.


첫번째 항목은 프로그램이 시작한 후 얼마만큼의 시간이 흘렀는지를 밀리세컨드 단위로 표시한다. 두번째 항목은 로그문을 출력하고 있는 스레드이다. 세번째 항목은 로그문의 레벨이다. 네번째 항목은 로그 요청을 하는 로거의 오른쪽 두 마디를 표시한다. 다섯번째 항목('-' 바로 앞 부분)은 내포검사항목(Nested Diagnostic Context : NDC) 이다. 처음 두 줄처럼 내포검사항목은 비어있을 수도 있다는 것을 기억하기 바란다. '-' 다음에 오는 것들은 로그문의 메시지이다.

5.     사용방법
5.1.   LOGGER의 사용
5.1.1.   LOG4J
Log4J 의 문서에도 있듯이, log4j 객체를 생성해서 main 메소드가 있는 클래스에 public static으로 선언해 놓고 사용하는 것이 가장 보편적이다. 우선적으로 log4j에는 기본적인 3가지 Logger, Appender, Layout 클래스가 있는데 각 클래스들의 연관관계는 아래와 같이 간단하게 이야기할 수 있다.                 

"Logger 는 Appender 가 지정한 곳에 Layout 형식으로 로그를 기록한다".

5.1.2 LOGGER
Log4j 패키지의 핵심클래스이다. 설정을 제외한 대부분의 로깅작업을 수행한다. 로깅작업은 Category에 있는 debug, info, warn, error, fatal의 다섯 가지 메소드를 이용해서 수행할 수 있다. Log4j의 최신문서를 보면 Logger의 parent class인 Category는 deprecated 되었고 Logger 클래스로 대치되었으며 호환성을 위해 2003년 중반까지는 API에서 제거하지 않는다고 되어 있으나 앞으로 없어질 클래스이므로 Category를 사용하지 말고 Logger 클래스의 메소드들을 사용하기 바란다. (이전에 나온, 혹은 최근에 나온 몇몇 how-to 문서들을 보면 여전히 Category를 쓰는 코드를 볼 수 있는데 빠른 시일 내에 모두 수정되어야 할 것이다)


5.1.3 로그레벨 지정하기
앞에서도 언급했듯이 log4j에서는 기본적으로 debug, info, warn, error, fatal의 다섯 가지 로그레벨이 있다. 각각은 메소드 debug(), info(), warn(), error(), fatal()라는 5가지 메소드를 이용해서 로그를 남길 수 있다. 다만 이때 Logger의 setLevel에서 지정된 로그레벨이 있다면 지정된 로그레벨 이하의 로깅이벤트는 무시된다. 따라서 로그도 남지 않는다. 즉, 아래와 같이

logger.setLevel(Level.INFO);

코드내에 지정되어 있다면, 다음의 세 코드 중

logger.debug("debug 로그");

logger.info("info 로그");

logger.warn("warning 로그");

debug 로그는 남지 않고 info 와 warn 로그만 남는다. 자바에서는 C와 같이 전처리기의 기능이 없기 때문에 #ifdef DEBUG와 같은 형태와 같이 디버깅 때와 릴리즈 때의 디버깅코드를 각각 별도로 생성할 수가 없다. 따라서 log4j의 이러한 기능은 로그관리에 있어서 상당히 편리하다.


5.1.3 APPENDER
log4j 의 api를 보면 실로 다양한 로그방식을 지원한다. 가장 단순한 Console부터 시작해서 파일, SMTP, 기타 등등… 의 방식들을 지원하는데 이들은 log4j 객체에 Appender의 객체로서 할당된다.

ConsoleAppender: 콘솔화면으로 출력하기 위한 appender이다.

FileAppender: FileAppender는 로깅을 파일에 하고 싶을 때 사용한다.

RollingFileAppender: FileAppender는 지정한 파일에 로그가 계속 남으므로 한 파일의 크기가 지나치게 커질 수 있으며, 계획적인 로그관리가 불가능해진다. RollingFileAppender는 파일의 크기 또는 파일백업인덱스 등의 지정을 통해서 특정크기 이상 파일의 크기가 커지게 되면 기존파일을 백업파일로 바꾸고, 다시 처음부터 로깅을 시작한다.

DailyRollingFileAppender: 설정한 날짜 또는 조건에 맞춰 로깅을 수행한다. 생성자 DailyRollingFileAppender(Layout layout, String filename, String datePattern);를 이용해서 객체의 생성과 함께 log가 roll 되는 시간을 지정해줄 수도 있고 기본 생성자로 생성 후 setDatePattern()을 이용해서 지정해 줄 수도 있다. DatePattern의 몇 가지 포맷은 다음과 같다.

'.'yyyy-MM: 매달 첫번째날에 로그파일을 변경한다.

'.'yyyy-ww: 매주의 시작싱 로그파일을 변경한다.

'.'yyyy-MM-dd: 매일 자정에 로그파일을 변경한다. (필자는 주로 이 옵션을 이용한다)

'.'yyyy-MM-dd-a: 자정과 정오에 로그파일을 변경한다.

'.'yyyy-MM-dd-HH: 매 시간의 시작마다 로그파일을 변경한다.

'.'yyyy-MM-dd-HH-mm: 매분마다 로그파일을 변경한다.

보다 자세한 내용은 아파치 api 문서를 참고하기 바란다.

5.1.3 LAYOUT
단순히 메시지 외에도 현재 로그하는 대상의 스레드명, 로그시간 등등 많은 정보를 조합할 수 있다. Layout에는 HTMLLayout, PatternLayout, SimpleLayout, XMLLayout 등이 있다. SimpleLayout과 XMLLayout 등도 많이 사용할 수 있겠지만, 아무래도 자신이 원하는 스타일의 로그메세지를 남기기 불편한 면이 있다. 필자가 자주 사용하는 레이아웃은 PatternLayout으로서, c 함수의 printf처럼 다양한 로그 메시지 조합을 만들어 낼 수가 있다.

%p : debug, info, warn, error, fatal 등의 priority 가 출력된다.

%m : debug(), info(), warn(), error(), fatal() 등의 함수로 지정한 로그내용이 출력된다.

%d : 로깅 이벤트가 발생한 시간을 기록한다. 출력포멧은 %d후의 브레이스내에 지정된 형태를 따른다. %d{HH:mm:ss, SSS}라든가 %d{yyyy MMM dd HH:mm:ss, SSS}와 같은 형태로 사용하면 된다. Java 의 SimpleDateFormat 의 형식대로 사용하면 된다.

%t : 로그이벤트가 발생된 쓰레드의 이름이 출력된다.

%% : % 표시를 출력하기 위해 사용한다.

%n : 플랫폼 종속적인 개행문자가 출력된다. \r\n 또는 \n 일것이다.

5.1.3 예제
아래 예제는 DailyRollingFileAppender를 이용해서 분당 하나의 로깅파일을 만들어내도록 했으며, 5초마다 Hello, DEBUG와 Hello, INFO 그리고 Hello, WARN을 출력하도록 되어 있다. 그리고 화면으로도 로그결과를 확인하기 위해서 ConsoleAppender도 추가하였다. 기본적인 priority 모드는 INFO로 설정되어 있다. 각각 어떤 값들이 로그에 남고 DailyRollingFileAppender가 어떻게 동작하는지, 그리고 각각의 파라미터들을 어떻게 세팅하였는지 등을 중심으로 코드를 보기 바란다.


import java.io.*;

import org.apache.log4j.*;

public class Test {

    public Test(){

        initLog();

    }

   

    public void initLog(){

        // log4j 설정

     logger.setLevel(Level.INFO);

     DailyRollingFileAppender appender = null;

     Appender consoleAppender = null;

      try {

            String logPattern = "%r [%t] %-5p %c %x - %m %d{yyyy MMM dd HH:mm:ss, SSS} \n";

            appender = new DailyRollingFileAppender(

 new PatternLayout(logPattern), "syslog.log", "'.'yyyy-MM-dd-HH-mm" );

            consoleAppender = new ConsoleAppender(new PatternLayout(logPattern));

        } catch(IOException e){

            e.printStackTrace();

            System.out.println("로그설정에 문제가 있습니다. 실행권한 체크등을 해보길 바랍니다.");

            System.exit(-1);

        }

logger.addAppender(appender);

        logger.addAppender(consoleAppender);

        logger = Logger.getRootLogger();

        logger.debug("LBSGateway 객체 생성");

    }

public static Logger logger = Logger.getRootLogger();

   

    public void go(){

        for ( int I = 0; I < 3; I++)

            new testThread().start();

    }

   

    public static void main(String[] args){

        Test t = new Test();

        t.go();

    }

}


class testThread extends Thread {

public void run(){

 while ( true ) {

Test.logger.debug("Hello, DEBUG");

Test.logger.info("Hello, INFO");

  Test.logger.warn("Hello, WARN");

  Thread.sleep(5000);

}

    }

}

    참고한 자료
http://network.hanbitbook.co.kr/view_news.htm?serial=565

http://jakarta.apache-korea.org/log4j/FAQ.html

http://jakarta.apache.org/log4j/docs/index.html



작성자 :임 장 빈  ieepun@hotmail.com

Last Update :2003년 6월 04일

반응형