다음글



Logback이란?
어떤 어플리케이션이든 실제로 사용자에게 판매 배포되는 경우 분석이 필요할때가 있고 개발자는 로그(기록)을 분석합니다. 예를 들어 버그가 발생했든 단순히 모니터링이 되었든 어플리케이션에 어떤 일이 발생하고 있는지 혹인 과거에 어떤 일이 발생했었는지 등.. 여러가지 경우가 있습니다.

Logback은 Java에서 가장 많이 사용되었던 로깅 라이브러리인 log4j의 후속 버전입니다. Logback은 log4j를 설계한 Ceki Gülcü에 의해 설계되었습니다. 같은 개발자에 의해 개발되었다 보니 logback을 사용하다보면 log4j를 사용하는 듯한 익숙함을 느낄 수 있습니다. 어떻게 보면 logback은 더욱 좋아진 log4j라고 보아도 무방합니다.


log4j와 Logback 비교. Logback의 특징들
logback은 log4j보다 이후에 개발된 프로젝트인 만큼 log4j보다 여러가지 기능이 추가되고 성능또한 향상되었는데, 모두 나열하자면 광범위 하지만 대표적으로 다음과 같은 점들이 있습니다.


logback-classic은 SLF4J를 구현합니다.
logback-classic의 Logger 클래스는 SLF4J의 API 스펙을 구현하므로 SLF4J의 API를 그대로 사용하여도 되는 이점이 있습니다. 마치 JDBC API를 사용하면 어떤 종류의 DBMS의 JDBC Driver를 사용해도 코드에 변경이 없는것과 같습니다.


광범위한 지원 문서
logback은 세부적인 공식문서를 제공하며 지속적으로 업데이트 됩니다. (다만 영어의 압박이..)

또한 아래에서 설명하겠지만 logback는 Groovy 코드를 통한 설정을 지원하는데, XML에서 사용하는 설정이 Groovy로 바뀌었을때 어떤식으로 사용되는지도 문서로 지원합니다. 공식문서 페이지에서 .groovy로 보기 버튼을 클릭하면 볼 수 있습니다.



XML과 Groovy 설정을 지원
XML설정뿐만 아니라 XML을 대신할 수 있는 그루비(Grooby) 설정을 지원합니다.
그루비 설정 참고 -> https://logback.qos.ch/manual/groovy.html

또한 기존 XML설정을 그루비 설정으로 마이그레이션 하는 도구 또한 지원합니다. 방법은 기존의 logback XML 코드를 다음의 사이트에 접속하여 입력창에 넣고 Translate 버튼을 누르면 됩니다. -> https://logback.qos.ch/translator/asGroovy.html



설정 변경시 설정 자동 reload(재로드)
설정파일의 <configuration> 에서 scan속성을 true로 설정하게 되면 설정이 변경시 자동으로 변경된 설정을 다시 로드하게 됩니다.
<configuration scan="true">   ... </ configuration>
cs


또한 scanPeriod 값을 설정하게 되면 스캔 검사 간격(주기)를 지정할 수 있습니다. 단위로는 milliseconds(밀리초), seconds(초), minutes(분) or hours(시간) 단위로 지정할 수 있습니다. 만약 단위를 사용하지 않고 값만 적게 되는 경우에는 밀리초 단위가 설정되기 때문에 주의해야 합니다.
<configuration scan="true" scanPeriod="30 seconds" >
  ...
</configuration>
cs


로그 I/O (입출력) 오류 발생시 우아한 복구
아무래도 Logging은 콘솔이나 터미널로 표준입출력을 수행하기도 하지만 반영구적으로 보관하기 위해 .log 등의 File로 관리하기도 합니다. 따라서 로깅시에 파일 입출력을 수행하는데, logback에서 로깅시 I/O 작업을 하다가 실패하는 경우 logback을 작동시키기 위해 어플리케이션을 재시작할 필요가 없습니다. FileAppender 및 RollingFileAppender의 하위 클래스들은 I/O 오류를 자동 복구할 수 있습니다.


필요없는 로그 파일 자동 제거
TimeBasedRollingPolicy이나 SizeAndTimeBasedFNATP의 maxHistory 속성값을 설정하여 그동안 저장되어 쌓인 로그파일의 최대 수를 제어 할 수 있습니다. 시간이 지나거나 크기 제한을 벗어나는 경우 이전 로그는 삭제되고 새로운 파일로 로깅을 시작할 수 있습니다.


보관 된 로그 파일의 자동 압축
RollingFileAppender를 사용하면 저장된 로그 파일을 자동으로 압축할 수 있습니다. 로그파일 압축은 어플리케이션과 비동기적으로 수행되는 작업이므로 로그파일이 압축되는 과정에서도 어플리케이션이 정지되지 않습니다.


Prudent 모드
Prudent 모드에서는 여러 JVM에서 logback의 FileAppender를 사용할때  하나의 로그파일을 공유하여 로깅할 수 있습니다.


설정 파일에 조건문을 사용
개발자는 여러 환경에 대해 각각의 여러가지 로깅 설정을 해야하는 경우가 있습니다. 예를 들어 개발환경과 운영환경이 다르기에 각각의 환경에 맞게 로깅 정책을 바꿔야할 수 있습니다. (ex: 개발환경은 C:\ 하위에, 운영 환경은 /data 하위에 로그 파일 저장)

이때 logback의 <if>, <then>, <else>를 통해 설정파일을 세밀하게 설정하여 각각의 환경에 맞게 자동 구성되도록 할 수 있습니다.
  <if condition='property("HOSTNAME").contains("torino")'>
    <then>
      <appender name="CON" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
          <pattern>%d %-5level %logger{35} - %msg %n</pattern>
        </encoder>
      </appender>
      <root>
        <appender-ref ref="CON" />
      </root>
    </then>
  </if>
cs



Filter
logback은 log4j가 제공하는것보다 훨씬 많은 필터링 기능을 제공합니다. 예를 들어 사용자가 아주 많은 대규모 어플리케이션이 운영중이라고 가정합니다. 
보통 로깅 수준(level)을 경고(WARN) 정도로 낮추어 오류 등의 로그만 기록되도록 할 것입니다. 왜냐하면 코드에 남겨놓은 모든 로그를 출력하게 되면 어플리케이션에 성능저하를 일으킬 수 있고 로그가 엄청나게 쌓여 로그를 볼 때 분석하기가 오히려 어려워지기 때문입니다.

이때 만약 특정 버그가 발생했다면 개발자는 특정 사용자가 어떤 행동을 했는지 어떤 값들을 넘겼는지 등 세밀한 로그 분석을 해야할 필요가 있습니다. 그러나 이를 위해 로그 레벨을 더욱 낮춘다면 모든 사용자의 로그들이 출력되어버릴 것입니다.

logback에서는 이러한 때를 위해 특정 사용자(특정 조건)에서의 로그레벨을 변경하는 등의 필터 정책을 사용할 수 있습니다. (ex: A사용자가 로그인 한 경우에는 DEBUG 레벨로 로깅)


SiftingAppender
SiftingAppender는 아주 다재다능한 기능이 있는 Appender입니다. 여러가지 런타임 설정에 따라 로깅을 분리, 선별할 수 있는데, 예를 들어 사용자 세션에 따라 각각 개인의 로그 파일을 생성할 수 있습니다.


패키징 데이터로 스택 트레이스 출력
logback에서는 현재 패키징된 라이브러리가 어떤 버전을 사용하는지 스택트레이스 정보에 포함시킬 수 있습니다. 예를 들어 struts는 몇버전을 사용하는지 spring 버전을 몇버전을 사용하는지..
14:28:48.835 [btpool0-7] INFO  c.q.l.demo.prime.PrimeAction - 99 is not a valid value
java.lang.Exception: 99 is invalid
  at ch.qos.logback.demo.prime.PrimeAction.execute(PrimeAction.java:28) [classes/:na]
  at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431) [struts-1.2.9.jar:1.2.9]
  at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236) [struts-1.2.9.jar:1.2.9]
  at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432) [struts-1.2.9.jar:1.2.9]
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) [servlet-api-2.5-6.1.12.jar:6.1.12]
  at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502) [jetty-6.1.12.jar:6.1.12]
cs

이 글의 원문 출처
블로그 이미지

도로락

IT, 프로그래밍, 컴퓨터 활용 정보 등을 위한 블로그

,