Spring Boot, Logback을 이용한 로그관리

Jihu Kim·2024년 1월 15일
0

Spring 입문

목록 보기
5/14
post-thumbnail

로그(log)란?

로그(log)란 컴퓨터 등에 접속한 기록이 컴퓨터 내에 남아있는 것을 의미하며, 로깅(logging)은 애플리케이션이 동작하는 동안 동작 정보를 시간순으로 기록하는 것을 의미한다.

로깅은 디버깅하거나 개발 이후 발생한 문제를 해결할 때 원인을 분석하는데 꼭 필요한 요소이다.

Logback은 자바 진영에서 가장 많이 사용되는 로깅 프레임워크이다.

Logback의 특징

  • 크게 5개의 로그 레벨(TRACE, DEBUG, INFO, WARN, ERROR)을 설정할 수 있다.
    • ERROR: 로직 수행 중에 시스템에 심각한 문제가 발생해서 애플리케이션의 작동이 불가능한 경우를 의미한다.
    • WARN: 시스템 에러의 원인이 될 수 있는 경고 레벨을 의미한다.
    • INFO: 애플리케이션의 상태 변경과 같은 정보 전달을 위해 사용된다.
    • DEBUG: 애플리케이션의 디버깅을 위한 메시지를 표시하는 레벨을 의미한다.
    • TRACE: DEBUG 레벨보다 더 상세한 메시지를 표현하기 위한 레벨을 의미한다.
  • 실제 운영환경과 개발환경에서 각각 다른 출력 레벨을 설정해서 로그를 확인할 수 있다.
  • Logback의 설정 파일을 일정 시간마다 스캔해서 애플리케이션을 재가동하지 않아도 설정을 변경할 수 있다.
  • 별도의 프로그램 지원 없이도 자체적으로 로그 파일을 압축할 수 있다.
  • 저장된 로그 파일에 대한 보관 기간 등을 설정해서 관리할 수 있다.

Logback 설정

스프링 부트에서는 간단히 application.properties에 값만 세팅해도 설정 가능 하지만, xml 설정파일을 만들어 설정을 해보자.

스프링 부트의 spring-boot-starter-web 라이브러리 내부에 내장돼 있어 별도의 의존성을 추가하지 않아도 사용할 수 있다.

  • spring-boot-starter-web 안에 spring-boot-starter-logging에 구현체가 있다.

Logback을 사용하기 위한 설정 파일을 만들어야한다. 클래스패스에 있는 설정 파일을 자동으로 참조하므로 Logback 설정파일은 리소스 폴더 안에 생성한다. 일반적인 자바 또는 스프링 프로젝트에서는 logback.xml이라는 이름으로 참조하지만 스프링 부트에서는 logback-spring.xml 파일을 참조한다.

▶ TRACE  <  DEBUG  <  INFO  <  WARN  <  ERROR

  1. ERROR : 요청을 처리하는 중 오류가 발생한 경우 표시한다.
  2. WARN  : 처리 가능한 문제, 향후 시스템 에러의 원인이 될 수 있는 경고성 메시지를 나타낸다.
  3. INFO  : 상태변경과 같은 정보성 로그를 표시한다.
  4. DEBUG : 프로그램을 디버깅하기 위한 정보를 표시한다. 
  5. TRACE : 추적 레벨은 Debug보다 훨씬 상세한 정보를 나타낸다. 
  • 로그에 설정할 수 있는 레벨은 총 5가지다.
  • 위의 순서대로 높은 레벨을 가진다. 출력 레벨의 설정에 따라 설정 레벨 이상의 로그를 출력 한다.
  • 예를 들어 로깅 레벨 설정을 "INFO"로 하였을 경우 "TRACE", "DEBUG" 레벨은 무시한다.

설정파일(logback-spring.xml) 예시

<?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_${type}.%d{yyyy-MM-dd}.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>
  • 3번 라인: property영역
  • 6~13, 15~28번 라인: appender영역
  • 10~12, 25~27번 라인: encoder영역
  • 11, 26번 라인: pattern영역
  • 23~35번 라인: root영역

15~28번, 34번 라인은 파일로 로그를 저장하고자 할 때 설정한다.

Logback 설정에서 가장 중요한 Appender 영역과 Root 영역에 대해서 자세히 알아보자

Appender 영역

Appender 영역: 로그의 형태를 설정하고 어떤 방법으로 출력할지를 설정하는 곳이다.

  • Appender의 대표적인 구현체(Class)
    • ConsoleAppender: 콘솔에 로그를 출력
    • FileAppender: 파일에 로그를 저장
    • RollingFileAppender: 여러개의 파일을 순회하면서 로그를 저장
    • SMTPAppender: 메일로 로그를 전송
    • DBAppender: 데이터베이스에 로그를 저장
  • appender 요소의 class 속성에 각 구현체를 정의
  • filter 요소로 Appender가 어떤 레벨로 로그를 기록하는지 지정
  • encoder 요소를 통해 로그의 표현 형식을 pattern으로 정의
  • 대표적인 패턴(pattern)
    • %Logger{length} : Logger name을 축약할 수 있다. {length}는 최대 자리 수, ex)logger{35}
    • %-5level : 로그 레벨, -5는 출력의 고정폭 값(5글자)
    • %msg : 로그 메시지 (=%message)
    • ${PID:-} : 프로세스 아이디
    • %d : 로그 기록시간
    • %p : 로깅 레벨
    • %F : 로깅이 발생한 프로그램 파일명
    • %M : 로깅일 발생한 메소드의 명
    • %l : 로깅이 발생한 호출지의 정보
    • %L : 로깅이 발생한 호출지의 라인 수
    • %thread : 현재 Thread 명
    • %t : 로깅이 발생한 Thread 명
    • %c : 로깅이 발생한 카테고리
    • %C : 로깅이 발생한 클래스 명
    • %m : 로그 메시지
    • %n : 줄바꿈(new line)
    • %% : %를 출력
    • %r : 애플리케이션 시작 이후부터 로깅이 발생한 시점까지의 시간(ms)

Root 영역

설정 파일에 정의된 Appender를 활용하려면 Root 영역에서 Appender를 참조해서 로깅 레벨을 설정한다.

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

Logback 적용하기

출력할 메시지를 Appender에게 전달할 Logger 객체를 각 클래스에 정의해 사용한다.

LOGGER 전역변수로 Logger 객체를 정의한다.

@RestController
@RequestMapping("/api/v1/get-api")
public class GetController {

    // 예제 5.26
    private final Logger LOGGER = LoggerFactory.getLogger(GetController.class);

   
}

다음과 같이 메서드에서 LOGGER.info("getHello 메소드가 호출되었습니다.");로 로그를 출력할 수 있다.

    // http://localhost:8080/api/v1/get-api/hello
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String getHello() {
        // 예제 5.27
        LOGGER.info("getHello 메소드가 호출되었습니다.");
        return "Hello World";
    }

LOGGER.info("@PathVariable을 통해 들어온 값 : {}", variable);를 통해서 변수의 값을 로그로 출력할 수도 있다.

// http://localhost:8080/api/v1/get-api/variable1/{String 값}
    @GetMapping(value = "/variable1/{variable}")
    public String getVariable1(@PathVariable String variable) {
        // 예제 5.28
        LOGGER.info("@PathVariable을 통해 들어온 값 : {}", variable);
        return variable;
    }


참고 블로그: https://goddaehee.tistory.com/206 [갓대희의 작은공간:티스토리]

profile
Jihukimme

0개의 댓글