Log4j를 이용해 간단히 콘솔에 로그를 출력하는 것을 해봤다면 이제 좀 더 실용적인 로깅 방법에 대해 살펴보자. xml을 이용해서도 가능하지만 properties는 xml보다 직관적이지 않나 싶다. 단지 key와 value로 구성되어 있으니까 ..
먼저 log4j.properties 파일을 생성한다. 이건 그냥 파일이면 상관 없다. 뭐 이클립스에서 무엇을 들어가 생성하고 .. 그런게 전혀 필요없다는 얘기다. 단, 경로는 잘 지켜줘야 한다. 일반적인 app일 경우 .class가 생성되는 위치(일반적으로 이클립스에서 java project를 이용하면 bin에 .class가 생성 된다. 소스는 당연히 src에 ..)에 넣어주면 된다. 웹이라면 WEB-INF를 이용하면 된다.
먼저 간단한 log4j.properties를 보면 다음과 같다.
그냥 보기에도 어렵지 않은 내용이다. 최상단에 있는 log4j.rootLogger 에 Log4j의 설정이 들어가는데 여기에 로그를 출력할 레벨을 설정 한다. 만약 로그를 사용하지 않을경우 'OFF'로 성정하는데 주목하자.
그리고 그 후에 오는 것들은 각각의 로그에 대한 설정이다. stdout와 rolling가 있는데 stdout는 콘솔출력을 위한 로그고 rolling는 파일 출력을 위한 로그 설정이다. 콘솔출력에서 봐야할 것은 log4j.appender.stdout.Threshold 부분인데 지금의 설정대로라면 DEBUG 레벨까지 출력하게 되어있다. 하지만 stdout에선 WARN으로 되어있으므로, stdout에서 출력되는 로그들은 WARN의 레벨 이상만 보여주게 된다. 롤링파일을 보면 남길 파일명을 기록하는 부분과 로그파일 최대크기, 백업 인덱스가있는데 먼저 로그파일의 최대크기는 말그대로 '내가 설정한 로그파일이 가질 최대의 크기'를 의미한다. 그리고 백업은 output.log.1 하는 식으로 인덱스에 숫자를 붙혀 나가게 되는데 이런식으로 로그가 남다가 풀이되면 백업 후 새로운 파일을 만들어 기록하게 된다.
자. 만약 로그파일 최대 크기가 넘어갔고, 백업을 1개만 했는데 이미 백업파일까지 존재한다. 그렇다면 이후의 로그들은 어찌될까? 이럴경우엔 이전 로그정보는 사라지고 계속 추가되게 된다. 만약 이와 반대로 되어있다면 .. 이건 재앙일 것이다.
프로퍼티 설정을 이용한 Log4j 파일 [StartApp_UseProperties.java]
프로그램을 개발하다 보면 오류메시지를 확인하거나 분기에 변수를 확인하기 위해 디버깅모드를 사용한다. 만약 이런 디버깅 모드를 사용하지 못하는 경우라면 java의 경우 System.out.println()을 이용해 콘솔에 로그를 남기고 문제점을 추적하는게 대부분이다.
개발단계에선 로그를 남기며 확인 하지만 실제 서비스를 하거나 배포를 할때 이런식의 로그를 남기는 것은 낭비다. 먼저 배포된 경우 프로그램의 동작 원리가 공개될 수도 있으므로 해선 안되고, 어쩌면 System.out.println()으로 인해 약간의 성능 저하를 감당해야 할 지도 모르겠다.(물론 지금의 시스템이라면 큰 상관은 없다지만..) 그리고 개발이 완료된 후 System.out.println()식의 로그는 일일이 해제를 해주어야 하는데 Log4j를 이용하면 외부의 설정 변경으로 로그출력여부를 결정할 수 있다.
java api에서는 본래 Logger가 존재 했다. 그리고 관대한 apache에선 log4j라는 logging framework를 제공한다. 둘 중 무엇을 사용할지는 사용자의 마음이지만 개인적으로 log4j를 사용하는게 더 좋을듯 하다.(먼저 사용이 간단해서..)
출력 결과는 위와 같다. 여기서 주목해야할 점은 Logger.getLogger(StartApp.class); 코드에서 StartApp.class부분이다. 이것은 그냥 String로 들어가도 되는데 저런식으로 클레스를 지정해주면 해당 클레스의 정보(패키지포함)까지 출력하게 된다. 만약 클레스를 전달하지 못하는경우(예를들어 jsp에서 처리할때)는 Logger.getLogger("CallJsp.jsp");로 해줘도 무관하다.
사용법도 그다지 어렵지 않고, 로그를 출력하는것도 어렵지 않다. Log4j에서 사용하는 주요 객체는 다음과 같다.
1.Logger (로그 본체)
위에서 사용 했던것 처럼 Logger의 본체이다. Logger.getLogger를 이용해 Logger을 가져와 사용한다. 여기에는 로그 출력 여부를 동적으로 확인할 수 있고, 로그레벨을 가지고 있어 출력할 로그의 레벨을 확인 후 출력할 수 있다.
2. Appender (로그 출력위치)
로그를 반드시 콘솔로 출력해야 할 이유는 없다. 파일로 출력할 경우도 있고, db에 저장할 경우도 있다. 이러한 로그 출력 위치를 결정한다.
3. Layout (레이아웃)
로그 출력에 대한 레이아웃이다. 일정 패턴을 갖고 있어 보다 정확한 로그를 확인할 수 있다. 패턴은 다음과 같이 설정할 수 있다. 레이아웃의 종류는 여러가지(DateLayout,XMLLayout, HTMLLayout ..)가 있는데 그중 하나인 PatternLayout를 살펴보도록 하자.
%p
debug, info등의 로그 타입
%d
로그 발생 시간 SimpleDateFormat 포멧을 따름 ( ex> %d{yyyy-MM-dd HH:mm:ss} )
%t
로그 쓰레드 이름
%F
로그 발생 프로그램 파일 명 (만약 패키지가 너무길어 불편하다면 %F {숫자}로 조절 가능)
%M
로그 발생 메소드 명
%r
프로그램 시작 후 로그 발생까지 시간
%m
로그로 전달된 메시지
%n
개행
%L
호출 코드 라인
기본적으로 이정도만 알고 있어도 크게 무리는 없을것 같다. 이제 포멧을 지정해 로그를 출력해 보자.
PatternLayout를 이용한 로그 [StartApp_PatternLayout.java]
출력결과
main> [2008-12-31 22:55:05] [StartApp_PatternLayout] [15] [DEBUG] 로그를 출력 합니다.
main> [2008-12-31 22:55:05] [StartApp_PatternLayout] [16] [DEBUG] 콘솔 Appender를 이용했으므로 콘솔로 출력 됩니다.
main> [2008-12-31 22:55:05] [StartApp_PatternLayout] [17] [DEBUG] 파일, 혹은 db로도 저장 가능 하구요!
작성한 형식대로 잘 출력이 된다. 이제 Log4j의 설정을 변경하여 보다 디테일한 로그를 출력해 보자. 로그 설정은 보통 xml이나 properties로 이용한다. 구체적 사항은 다음 포스트에 작성 하기로 하겠다.