BACKEND/SPRING

05. 로깅 라이브버리 - Logback

우진하다 2023. 7. 30. 15:14

 

Logging

로깅(logging)은 컴퓨터 프로그램이나 시스템이 실행 중에 발생하는 이벤트나 데이터를 시간에 따라 순차적으로 기록하는 것을 의미합니다. 이런 로그 데이터는 텍스트 파일, 데이터베이스, 시스템 이벤트 로그 등에 저장될 수 있습니다.

로깅의 목적으로는 
디버깅
소프트웨어 개발 과정에서 버그를 찾아내거나 시스템의 비정상적인 동작을 분석하는데 도움이 됩니다.

시스템 모니터링
로그를 통해 시스템의 상태를 모니터링하고, 성능 문제나 잠재적인 문제를 조기에 발견할 수 있습니다.

보안과 감사 트레일
로그는 누가 시스템에 접근했는지, 어떤 작업을 수행했는지에 대한 기록을 제공하므로, 보안 위반을 추적하거나 법적 요구사항을 충족하는데 필요한 감사 트레일(audit trail)을 제공합니다.

사건 복구
시스템에서 장애가 발생한 경우, 로그 데이터는 문제를 해결하고 장애 발생 원인을 파악하는데 도움이 됩니다.

로깅을 위한 여러 가지 표준 및 도구가 있으며, 자바 환경에서는 Log4j, Logback, SLF4J 등이 널리 사용됩니다. 
이러한 도구들은 로그 메시지의 생성, 필터링, 포맷팅, 출력 등을 쉽게 처리할 수 있도록 도와줍니다.

이 중에서 Logback을 알아보겠습니다.

 

Logback 설정

resource 폴더 안에 생성 logback-spring.xml 파일 참조하도록 생성 
logback 설정은 검색하면 많이 나옵니다. 필요한 방식에 따라 수정해 사용하도록 합시다.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property name="LOG_PATH" value="./logs"/>
    <!-- Appenders -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] %logger %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="INFO_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <file>${LOG_PATH}/info.log</file>
        <append>true</append>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/info_%d{yyyy-MM-dd}.log.gz</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] %logger %msg%n</pattern>
        </encoder>
    </appender>
    <!-- TRACE < DEBUG < INFO < WARN < ERROR < OFF -->
    <!-- Root Logger -->
    <root level="INFO">
        <appender-ref ref="console"/>
        <appender-ref ref="INFO_LOG"/>
    </root>
</configuration>

 

Appender 영역

어펜더 영역은 로그의 형태를 설정하고 어떤 방법으로 출력할지를 설정하는 곳입니다.
어펜더 자체는 하나의 인터페이스를 의미하며 하위에 여러 구현체가 존재합니다.

• Consolekppender: 콘승에 로그를 출력
• FileAppender: 파일에 로그를 저장
• RollingFileAppender: 여러 개의 파일을 순회하면서 로그를 저장
• SNTPAppender: 메일로 로그를 전송
• DBAppender: 데이터베이스에 로그를 저장

다음으로 encoder 요소를 통해 로그의 표현 형식을 패턴(pattern)으로 정의합니다. 
사용 가능한 패턴은 몇 가지 정해져 있으며, 대표적인 패턴은 다음과 같습니다.

%Logger {length} - 로거의 이름
%-5level - 로그 레벨, -5는 출력 고정폭의 값 
%msg(%message) - 로그 메세지%d : 로그 기록 시간
%p : 로깅 레벨
%F : 로깅이 발생한 애플리케이션 파일명
%M : 로깅이 발생한 메서드 이름
%I : 로깅이 발생한 호출지의 정보
%thread : 현재 스레드명
%t : 로깅이 발생한 스레드명
%c : 로깅이 발생한 카테고리
%C : 로깅이 발생한 클래스명
%m : 로그 메시지
%n : 줄바꿈
%r : 애플리케이션 실행 후 로깅이 발생한 시점까지의 시간
%L : 로깅이 발생하는 호출 지점의 라인 수

            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] %logger %msg%n</pattern>

 

Root 영역

Root Logger는 로깅 설정에서 가장 핵심적인 요소입니다. 이는 모든 로거의 조상이며, 명시적으로 로거의 부모가 지정되지 않은 경우 기본적으로 Root Logger가 부모 로거가 됩니다. 로그를 출력할 레벨과 appender를 지정합니다.

Root Logger의 설정은 <root> 태그를 통해 이루어집니다. 일반적인 설정 방식은 다음과 같습니다.

<root level="INFO">
    <appender-ref ref="console" />
    <appender-ref ref="INFO_LOG"/>
</root>

 

<root level="INFO">: 로그 레벨을 INFO로 설정합니다. 이는 로그 레벨이 INFO 이상인 로그 메시지를 출력하겠다는 의미입니다. 즉, DEBUG 레벨의 로그는 출력되지 않습니다. INFO, WARN, ERROR 레벨의 로그는 출력됩니다.

<appender-ref ref="console" />: 로그 메시지를 출력할 Appender를 설정합니다. 여기서는 console라는 이름의 Appender를 참조하고 있습니다. 이는 콘솔에 로그를 출력하겠다는 의미입니다.

<appender-ref ref="INFO_LOG"/>: 로그 메시지를 출력할 Appender를 추가로 설정합니다. 여기서는 INFO_LOG라는 이름의 Appender를 참조하고 있습니다. 이는 로그를 파일(INFO_LOG)에 기록하겠다는 의미입니다.

Root Logger의 로그 레벨 설정은 다음 중 하나로 설정할 수 있습니다: TRACE, DEBUG, INFO, WARN, ERROR, OFF. 이 중 TRACE가 가장 낮은 레벨이고 ERROR가 가장 높은 레벨입니다. OFF는 모든 로그를 출력하지 않겠다는 설정입니다.

다른 로거들은 Root Logger의 설정을 상속받습니다. 하지만 각 로거는 필요에 따라 별도의 로그 레벨과 Appender를 지정하여 사용할 수 있습니다. 이렇게 하면 각 로거별로 다른 로그 레벨과 출력 방식을 가질 수 있습니다.

 

Logback 적용하기

만들어진 컨트롤러에 logback을 생성하고 적용합시다.

public class GetController {
    private final Logger LOGGER = LoggerFactory.getLogger(GetController.class);

    // http://localhost:8080/api/v1/get-api/hello
    @GetMapping("/hello")
    public String getHello() {
        LOGGER.info("getHello() 메서드 호출");
        return "Hello World!";
    }
    //...
 }

GET getHello 메서드를 요청하면 logs 폴더가 생성되고 파일안에 log 기록이 남겨진 것을 확인할 수 있고 콘솔창에서도 로그가 남겨진 것을 확인할 수 있습니다.