레넌의 개발 일기

Logback을 통한 Logging 본문

Spring

Logback을 통한 Logging

brorae 2022. 8. 29. 17:49

로깅이란?

로깅이란 시스템이 동작할 때 시스템의 상태 및 동작 정보를 시간 경과에 따라 기록하는 것을 의미한다.

 

로깅이 필요한 이유

  • 개발 과정 혹은 개발 후에 발생할 수 있는 예상치 못한 애플리케이션의 문제 진단 가능
  • 다양한 정보 수집 가능
  • 사용자 로그의 경우 분석 데이터로 활용 가능

하지만 로깅을 하는 단계에서 적절한 수준의 로그 기록 기준을 잡지 못하면 방대한 양의 로그 파일이 생성되는 문제를 겪거나, 의미 있는 로그를 쌓지 못하는 경우가 발생할 수 있다. 결국 효율적으로 로깅을 하는 방법을 이해하는 것이 중요하다.

 

로깅하는 방법

대표적으로 Log4j  Logback이 있다. Log4j는 2015년 개발이 중단되었고, 현재 널리 사용되고 있는 Logback으로 설명하도록 하겠다. LogbackSLF4j 의 구현체이며 Spring Boot 환경이라면 별도의 dependency 추가 없이 기본적으로 포함되어 있다. SLF4jLogger 추상체로 Logback이나 log4j2와 같은 로깅 프레임워크의 인터페이스의 역할을 한다.

 

SLF4j

  1. SLF4j Bridging Module
     - 다른 로깅 API -> Bridge(redirect) -> SLF4j API
     - 다른 로깅 API에서의 Logger 호출을 SLF4j 인터페이스로 연결(redirect)하여 SLF4J API가 대신 처리할 수 있도록 하는
       일종의 어댑터 역할을 하는 라이브러리
  2. SLF4j API :
     - 로깅에 대한 추상 레이어를 제공
  3. SLF4j Binding
     - SLF4j 인터페이스를 로깅 구현체로 연결하는 어댑터 역할을 하는 라이브러리
     - SLF4j에 구현체(Logging Framework)를 바인딩하기 위해 사용
     - 여러 바인딩 중 하나만 사용
  4. Logging Framework
     - 실제 로깅 코드를 실행할 Logging Framework 를 정한다.

 

LogBack 

Log4j에 비해 향상된 성능과 향상된 필터링 옵션을 제공한다. 또한, 자동 리로드를 제공해준다.

Linux 서버 내에서 log4j를 사용할 시에는 log level을 변경하게 되면, 서버를 재가동하여 변경 사항을 적용해줘야 하는 반면에 logback은 서버를 재가동할 필요 없이 즉각 자동 리로드를 지원해준다.

 

spring boot 환경의 경우 spring-boot-starter-web > spring-boot-starter-logging에 기본적으로 logback 구현체가 포함되어 있다. 그렇기 때문에 spring boot 환경에서 로깅 프레임워크를 따로 설정하지 않으면 logback이 기본으로 적용된다.

 

로그레벨

Logback 은 5단계의 로그 레벨을 가진다.
심각도 수준은 Error > Warn > Info > Debug > Trace 이다.

  • Error : 예상하지 못한 심각한 문제가 발생하는 경우, 즉시 조취를 취해야 할 수준의 레벨
  • Warn : 로직 상 유효성 확인, 예상 가능한 문제로 인한 예외 처리, 당장 서비스 운영에는 영향이 없지만 주의해야 할 부분
  • Info : 운영에 참고할만한 사항, 중요한 비즈니스 프로세스가 완료됨
  • Debug : 개발 단계에서 사용하며, SQL 로깅을 할 수 있음
  • Trace : 모든 레벨에 대한 로깅이 추적되므로 개발 단계에서 사용함

Debug 와 Trace 레벨은 많은 양의 로그가 쌓이므로 자칫 운영 단계에서 해당 레벨의 로깅을 할 경우 용량 감당이 안 될 수 있다. 

Debug, Trace 레벨의 로깅은 개발 단계에서만 사용하고 배포 단계에서는 사용하지 말자

 

LogBack 구조

  • logback-core
  • logback-classic
  • logback-access

logback-core: 다른 두 모듈을 위한 기반 역할을 하는 모듈이다.(Appender와 Layout 인터페이스가 이 모듈에 속한다)

logback-classic: logback-core에서 확장된 모듈로, logback-core와 SLF4J API 라이브러리를 가진다. (Logger 클래스가 이 모듈에 속한다)

logback-access: Servlet Container와 통합되어 HTTP 액세스에 대한 로깅을 제공한다. logback-core는 기반 기술이기 때문에 필요하지만, logback-classic 및 SLF4j와는 무관한다. 웹 애플리케이션 레벨이 아닌 컨테이너 레벨에 설치되어야한다.

 

설정

Logback을 이용해 로깅을 수행하기 위해서 필요한 주요 설정요소로는 Logger, Appender, Layout(Encoder)의 3가지가 있다.

Core

 

Appender

Appender는  로그 메세지가 출력될 대상을 결정한다.

ConsoleAppender와 FileAppender에 대해서 알아보자.

ch.qos.logback.core.ConsoleAppender

콘솔에 System.out 또는 System.err를 이용하여 로그 이벤트를 append한다.
사용자가 지정한 encoder를 통해 이벤트의 포맷 형식을 지정할 수 있다.

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>${LOG_PATTERN}</pattern>
    </encoder>
</appender>

${LOG_PATTERN}은 property 설정으로 아래와 같이 설정해주었다.

<property name="LOG_PATTERN"
          value="[%d{yyyy-MM-dd HH:mm:ss}:%-4relative] %green([%thread]) %highlight(%-5level) %boldWhite([%C.%M:%yellow(%L)]) - %msg%n"/>

ch.qos.logback.core.FileAppender

파일에 로그 이벤트를 append한다.

ch.qos.logback.core.rolling.RollingFileAppender

FileAppender를 상속하여 로그 파일을 rollover한다. 여기서 rollover는 타겟 파일을 바꾸는 것으로 이해할 수 있다.

<appender name="FILE-DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_LOCATION}/${DEBUG_LOCATION}/debug-${BY_DATE}.log</file>
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>DEBUG</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
    <encoder>
        <pattern>${LOG_PATTERN}</pattern>
    </encoder>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <fileNamePattern>${BACKUP_LOCATION}/${DEBUG_LOCATION}/debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
        <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
        <maxHistory>${MAX_HISTORY}</maxHistory>
    </rollingPolicy>
</appender>

SizeAndTimeBaseRollingPolicy로 파일의 치대 크기와 갯수를 설정해주었다.

여기서 filter란?

LevelFilter는 지정한 level과 같은 level 로그 이벤트를 필터링한다.
로그 이벤트가 지정한 level과 같다면 onMatch, 같지 않다면 onMismatch에 따른 FilterReply를 수행한다.

  • ACCEPT: 로그 이벤트를 정상적으로 동작시키고, 남아있는 Filter에 대해 검증하지 않는다.
  • DENY: 로그 이벤트 동작을 취소한다.
  • NEUTRAL: 다음 Filter에게 검증을 넘긴다. 만약 남아있는 filter가 없다면 로그 이벤트가 정상적으로 동작된다.

위의 작성된 코드에서는 DEBUG 레벨의 로그만 찍는다는 의미이다.

 

Encoder

Encoder는 로그 이벤트를 바이트 배열로 변환하고, 해당 바이트 배열을 OutputStream에 쓰는 작업을 담당한다.
즉, Appender에 포함되어 사용자가 지정한 형식으로 표현될 로그메시지를 변환하는 역할을 담당하는 요소이다.

 

참고

https://livenow14.tistory.com/64

https://logback.qos.ch/manual/appenders.html

https://minkwon4.tistory.com/161

https://tecoble.techcourse.co.kr/post/2021-08-07-logback-tutorial/

'Spring' 카테고리의 다른 글

REST Docs 적용기  (0) 2022.07.31