티스토리 뷰

study/Java

Log4j - 로깅 API

비회원 2008. 3. 19. 00:00

로깅 API의 필요성
 
애플리케이션을 개발할 때 디버깅을 위해서 System.out.println을 사용하는 경우가 많다. 윈도우의 경우 명령 프롬프트에서 출력 결과를 볼 수 있어 디버깅 툴로 IDE를 쓰지 않을 때에 가장 단순하고 편리한 방법으로 인식되어 왔다. 간단한 애플리케이션인 경우에는 System.out.println을 사용하여도 크게 관계는 없다. 그렇지만 간단한 테스트 정도가 아니고 애플리케이션이 일정 정도의 규모를 넘어서는 복잡성을 지닐 때는 이 방법에는 몇 가지 문제가 있다.
 
문제가 되는 지점 찾기
시스템 출력을 사용하여 널 포인터 에러를 찾거나 애플리케이션이 어느 곳까지 실행되었는지 찾아야 하는 경우가 있다. 어디까지 에러없이 실행되었는지 알고자 할때는 출력 내용상 별 의미가 없는 문장을 출력하는 등의 방법을 사용하게 되는데, 일단 문제가 없는지를 찾고 해결하고 나서 그냥 놔두면 소스 코드가 지저분하고 속도에도 영향을 미칠 수 있는 가능성이 많기 때문에 출력문을 주석 처리하거나 지우는 것이 일반적이다. 그러나 애플리케이션이라는 것이 프로그래머가 생각할 수 있는 일반적인 데이터만 들어가는 것이 아니고 여러 상황에 의해서 어디서든지 에러가 날 가능성이 있다. 어떤 데이터를 넣었는데 에러가 났다고 하면 다시 출력문을 추가하거나 주석 처리 부분을 주석처리를 제거하고 다시 컴파일하여 에러가 나는 데이터를 입력해보아서 문제가 되는 지점을 찾아야만한다.
 
원격 컴퓨터에서의 출력
시스템 출력이 원격 컴퓨터에서 실행되는 것이라면 시스템 출력문을 볼 수 있는 방법이 한정되어 있다. 원격으로 접속하여 java명령어를 실행하여 자바 버추얼 머신을 실행한 화면에서만 출력을 볼 수 있으며 몇몇 웹 애플리케이션 서버의 경우 시스템 출력을 별도의 로그 파일로 만드는 기능도 제공하고 있지만 방법이 한정되어 있는 것은 마찬가지다.
 
운영자 수준의 정보
애플리케이션이 실행될 때 프로그래머 수준에서는 디버깅을 위한 정보가 가장 필요할 수 있지만 애플리케이션 운영자의 입장에서는 다른 실행 정보가 더 중요할 수 있다. 아파치 웹서버의 접속정보 로그 파일과 같은, 운영자 수준에서 필요한 정보를 출력하는 것은 시스템 출력문을 사용해서는 적합하지 않다.
 
로깅 API의 기능
 
레벨별 로그 출력
프로그래머 수준에서 DEBUG레벌이 필요하다면 운영자 수준에서는 INFO레벨이 필요할 것이다. 출력문을 제거하는 등의 방법으로 소스를 수정하지 않고도 간단한 설정을 변경하는 것만으로 개발시에는 DEBUG레벨, INFO레벨을 모두 다 출력하고 운영시에는 DEBUG레벨의 출력문은 출력하지 않고 INFO레벨만을 출력하게 한다면 로그 출력이 애플리케이션의 성능에 큰 영향을 미치지 않을 것이다.
 
로그 출력 정보 제어
로그에 출력하는 정보를 쉽고 간단하게 제어한다. 기본적으로 필요한 정보로는 현재의 클래스명, 현재 라인 위치, 실행 경과시간 등이 있을 수 있는데, 예를 들어 클래스명 출력을 위하여 logger.log("[클래스Xpert]Error ocurred " + e.getMessage()); 또는 logger.log("[클래스" + this.getClass().getName() + "]Error ocurred " + e.getMessage());와 같이 작성해야 한다면 상당히 귀찮고 번거로울 것이다 .로깅 API에서는 클래스명을 가져오는 메소드가 무엇인지, 현재 라인 위치를 가져오는 방법이나 실행 결과시간을 얻는 방법을 알 필요 없이 로깅을 할 수 있다면 상당히 편리할 것이다.
 
다양한 방식으로 출력
단순 텍스트 파일 뿐 아니라 HTML 파일, 데이터베이스, 메일 등 다양한 방법으로 로그를 출력한다. 만일 실행되는 애플리케이션에 심각한 문제가 발생하였는데 로그 파일에 기록을 남기는 정도로는 부족하다. 심각한 문제에 대해서는 메일로 로그를 보낸다는가 하는 조치가 필요할 것이다.
 
이러한 요구를 가장 잘 수용하고 있는 로깅 API가 바로 아파치 자카르타의 Log4J이다. 로깅 API로는 JDK1.4에서 포함된 java.util.logging 패키지에 있는 로깅 API와 아파치 자카르타의 Commons Logging  API도 있는데, Log4J는 이들에 비해 더 풍부한 기능을 제공하고 JDK1.1에서부터 사용가능하며 충분히 안정적이라는 장점을 가지고 있다.
 
 
 
Log4J
 
Log4J에는 로거(logger),어펜더(appendar),레이아웃(layout)이라는 세가지 주요 컴포넌트가 들어 있어, 런타임에 로그 메시지의 레벨에 따라 포맷형태와 로그가 출력되는 위치를 컨트롤한다. 즉 로거는 지정한 레이아웃대로 어펜더에 로그를 남긴다.
 
- 로거는 로그의 영역(category) 또는 로그의 주체이다. 애플리케이션을 작성할 때 로깅을 시작하기 전에 어떤 로거를 사용할지를 결정하여 패키지에 따라 어떤 패키지에서 발생한 로그는 파일에 출력하고자 하고 다른 패키지에서 발생하나 로그는 시스템 출력을 한다는 식으로 구분하여야 출력하는 것이 가능하게 된다.
 
- 어펜더는 로그를 출력하는 위치이다. 로그에는 하나 이상의 어펜더를 지정할 수 있어 시스템 출력도 하면서 텍스트 파일에 기록할 수 도 있다. 로그 메시지는 시스템 출력, 텍스트 파일, HTML 파일, XML 파일, 소켓, Windows NT Event 로그, 이메일 등으로 출력할 수가 있다.
 
- 어펜더에서 로그를 출력하기 위한 출력 포맷은 레이아웃에 따른다.
 
- 애플리케이션 개발자가 만든 로그 메시지를 출력하는 것 이외에도 일자, 시간, 로깅레벨, 클래스명, 소스코드 라인 번호, 메소드 이름, 스레드 이름 등을 출력하는 것을 레이아웃에 지정하면 된다.
 
Log4J에서 사용하는 로깅 레벌은 다섯 가지이며 순서대로 쓰면 DEBUG < INFO < WARN < ERROR < FATAL 이다. 로그에 할당된 로깅 레벨에 따라 동일하거나 그보다 높은 레벨의 로그 메시지를 출력한다. 예를 들어 로거에 할당된 로깅 레벨이 WARN이라고 하면 WARN, ERROR, FATAL의 로그 메시지를 출력하는 것이다.
 
애플리케이션에서 각 클래스는 각각의 로거를 가지거나 공통의 로거를 가질 수 있다
Log4J는 모든 로거가 상속할 수 있는 루트 로거를 제공한다. log4j.properties를 만들 때도 맨 위에 필요한 것이 루트 로거에 대한 내용이다.
 
<< log4j.properties 사용 >>
애플리케이션 소스 코드에서 로거의 로깅 레벨이나 어펜더 등을 정할 수 있도록 하는 메소드가 있지만 Log4J에서는 이를 권장하지 않는다. 로깅 레벨을 바꾸고 싶다면 소스를 수정해야 하는 그런 고정을 겪지 않으면서도 간단하게 로거에 따른 어펜더와 레이아웃을 런타임에 바꿀수 있는 방법이 log4j.properties를 이용하는 방법이다.
 
log4j.properties에는 맨 위 부분에 rootLogger에 대한 설정이 있다.
따라서 다음과 같은  log4j.properties 파일을 만들어 보자.
 
log4j.rootLogger=DEBUG, stdout, R
 
log4j.appender.stdout=org.apache.log4j.ConseleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p (%F:%L) = %m%n
 
log4j.appender.R.Threshold=INFO
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=sample.log
log4j.appender.R.MaxFileSize=2KB
log4j.appender.R.MaxBackupIndex=2
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%5 (%F:%L) - %m%n
 
rootLogger는 로깅 레벨이 DEBUG로 되어 있고 어펜더는 stdout과 R이라는 이름으로 어펜더를 두개 가지고 있다.아래 stdout이라는 이름의 어펜더에는 ConsoleAppender가 있어서 시스템 출력인 것을 알 수 있으며 R에는 RollingFileAppender가 있어서 (순환)파일에 로그를 출력하게 된다. RollingAppender에는 로깅 레벨이 INFO이상인 로그 메시지만 출력하도록 하였다. MaxFileSize는 여기서는 간단히 테스트해볼 수 있는 정도의 크기로 2KB만 정하였고 실제로는 적정한 크기로 정하면된다. sample.log 파일의 크기가 2KB를 넘으면 sample.log.1로 파일이 백업되고 새로운 sample.log에 로그를 출력한다. MaxBackupIndex=2이므로 백업 파일은 sample.log.1과 sample.log.2까지만 생성된다.
 
R이라는 이름의 어펜더의 Threshold=INFO로 되어 있는데 어펜더에 설정한 Threshold는 로거에 설정한 로깅레벨에서 Threshold보다 레벨이 낮은 것은 걸러내서 출력하지 않도록 하는 역할을 한다. 따라서 로거에서 설정한 로깅 레벨이 Threshold보다 높다면 Threshold는 걸러낼 것이 없기 때문에 의미가 없다.
TAG
댓글
댓글쓰기 폼