jhhan의 블로그

Spring boot - Logback을 활용해서 log 파일 생성하기 본문

Spring

Spring boot - Logback을 활용해서 log 파일 생성하기

jhhan000 2024. 5. 6. 21:00

이번 포스트에서는 Spring boot에서 로그 파일을 남겨보는 방법 중 한 개를 알아보려고 합니다.
(정말 오랜만에 정리해보는 Spring boot 관련 포스트입니다.)

 

참조 : https://cl8d.tistory.com/96

 

[Spring] 에러 로깅하기 - Logback을 사용해서 ERROR 레벨만 파일로 로그를 남겨보자!

🌱 들어가기 전 이번 장바구니 미션에서는 프론트 크루들과 협업을 해야 했기 때문에 앞으로 에러 로그를 볼 일이 많아질 것 같다고 생각했다. 배포 스크립트를 작성하면서 스프링이 띄워질 때

cl8d.tistory.com

 

아래에서 진행하는 내용들은 모두 vscode 기준으로 진행합니다.

  • Spring boot version : 3.1.11
  • java version               : 17
  • pom.xml

을 사용해서 진행했습니다.

 

 

Spring boot 프로젝트를 실행해서 진행하면 로그가 적히는 것을 볼 수 있습니다.

근데 이것은 Spring boot 프로젝트가 실행되면서 Terminal에서 나타나는 것일 뿐

이러한 로그를 저장하는 파일은 따로 없습니다.

그리고 아직까지는 자동으로 로그 파일을 남기는 방법은 없는 것으로 압니다.

개발자가 직접 설정해줘야 로그파일을 남길 수 있습니다.

 

 

그러면 로그파일 생성 이전에

logback에 대해서 알아보고 넘어가겠습니다.

 

1. logback

logback은 Logging Framework로, 로그 라이브러리라고 볼 수 있습니다.

기존에 log4j를 많이들 썼지만, 기능들을 추가해서 logback이라는 것이 나오게 되었다고 합니다.

logback은 log4j보다 기능을 보완하고 안정성을 높였다고 합니다.

그리고 slf4j도 지원하기 때문에 log4j를 원하지 않는다면 다른 방향으로 진행할 수 있다고 합니다.

(아마 예전에 log4j 취약점 문제로 인해 logback이 활성화된 듯 합니다... 뇌피셜)

 

logback은 Spring boot 기반의 프로젝트에는 기본 설정이 되어있어서 별도의 추가 작업이 필요하지 않다고 합니다.

그래도 혹시 모르니 다음의 내용을 pom.xml에 추가하면 될 것 같습니다.

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>${logback.version}</version>
</dependency>

 

logback의 경우 3개의 기본구성으로 되어있습니다.

  • logger : 로그 메시지에 대한 일종의 컨텍스트로, 어플리케이션이 로그 메시지를 생성하기 위해 상호작용하는 클래스
  • appender : 로그 메시지를 배치하는 역할, logger는 2개 이상의 appender를 가질 수 있음
  • layout : 출력될 메시지를 준비, 메시지 formatting을 위한 클래스 생성 지원

 

그 외에 logback에 대해서 찾아보게 되면 다른 블로그에 다양한 내용들이 정리되어 있는 것을 볼 수 있습니다.
(저는 로그 파일 만들기 위주로 설명하려 합니다.)

 

 

2. log파일 생성해보기

프로젝트 구조입니다.

스프링 프로젝트를 몇 번 만들어봤다면 익숙하게 봤을 것입니다.

그리고 중간에 처음보는 파일이 있을 것입니다.

  • logback-variables.properties : 꼭 필요하지 않지만 현재 설정한 내용들이 들어가 있는 파일
  • logback-spring.xml : 로그 파일을 만들기 위한 필수 설정 xml
  • 이 2개의 파일을 중점적으로 볼 것 입니다.

(파일이름에 logback이 들어간 이유는 logback이라는 것을 활용해서 진행하기 때문입니다.)

 

이제 logback-spring.xml 파일을 생성해보도록 합니다.

위치는 src/main/resources 밑에 위치하도록 했습니다.

<configuration>
    <property resource="logback-variables.properties" />

    <timestamp key="ToDay" datePattern="yyyyMMdd" />

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>
                ${LOG_PATTERN}
            </Pattern>
        </layout>
    </appender>

    <appender name="FILE1" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${LOG_PATH}/info/${ToDay}_${LOG_FILE_NAME}.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>
                ${LOG_PATH}/info/%d{yyyyMMdd}_${LOG_FILE_NAME}_%i.log
            </fileNamePattern>
            <maxFileSize>10MB</maxFileSize>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="FILE1" />
        <appender-ref ref="CONSOLE" />
    </root>

</configuration>

 

그리고 동일한 위치에 logback-variables.properties 파일도 생성해 봅니다.

LOG_PATH = ./logs
LOG_FILE_NAME = sample-logger
LOG_PATTERN = %d{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] [%logger{36}] - %msg%n

 

먼저 logback-variables.properties 파일의 경우

특정 변수들을 전역 변수로 관리하기 위해 만든 파일입니다.

필요하지 않다면 logback-spring.xml 파일에 모든 내용을 적어서 진행해도 상관없습니다.

 

다음은 logback-spring.xml 파일입니다.

대부분 처음보는 내용들이어서 하나하나 자세히 보려고 합니다.

 

  • 아까 만든 전역변수가 담겨져 있는 파일을 import 했다고 생각하면 됩니다.

  • 로그 이벤트에 대한 timestamp 정의
  • 로그 패턴에서 사용될 예정
    • datePattern : 날짜 포맷을 지정하는 패턴
    • 'yyyyMMdd' 라고 했지만 본인 취향에 따라 'yyyy-MM-dd' 이런 식으로 해도 됩니다.

 

  • appender 태그: 로그를 출력하기 위해 appender 정의.
    • name: 나중에 name을 통해 참조하게 됨
    • name="CONSOLE" 인 이유는 콘솔 출력을 위한 로깅 설정이기 때문
  • layout 태그 : 로그 메시지의 레이아웃을 어떻게 설정할 지 정의
    • 이 부분에서는 '패턴 레이아웃'을 사용하게 설정함
  • Pattern 태그 : 어떤 패턴을 사용할지 정의하는 태그
    • LOG_PATTERN의 경우 아까 만들었던 logback-variables.properties에 들어있음.

 

  • %d{yyyy-MM-dd HH:mm:ss.SSS} : 로그가 발생한 시간 & ms까지 설정함
  • [%level] : 로그의 레벨 (trace, debug, info, warn, error 가 출력됨)
  • [%thread] : 로그 이벤트가 발생한 스레드 이름
  • [%logger{36}] : 로그 이벤트를 발생한 주체의 이름 & 최대 36자 까지 출력되도록 설정
  • %msg : 로그 이벤트의 메시지
  • %n : 줄바꿈
  • 발생시간 - 로그 레벨 - 스레드 - 발생 주체 - 메시지 순서로 출력.

 

  • appender 태그 : 로그를 출력하기 위해 appender 정의
    • name="FILE1" 인 이유 → 파일 출력을 위한 로깅 설정이기 때문
  • filter 태그 : 특정 로그 레벨에서 사용하기 위한 필터 정의
    • level 태그 : 로그의 레벨을 정의할 수 있는 부분 (trace, debug, info, warn, error)
    • onMatch, onMismatch 태그 : 정의된 로그 레벨일 경우와 아닌 경우 어떻게 처리할 지 설정
      ACCEPT : 로그 출력 진행
      DENY : 로그 출력 안 함
  • file 태그 : 로그 파일에 대한 이름 및 경로 지정
    • LOG_PATH , LOG_FILE_NAME : ogback-variables.properties 파일에서 정의된 변수들
  • rollingPolicy 태그 : 롤링 정책 사용 & 로그 파일의 크기나 시간에 따라 파일 롤링 정책을 적용
    • 간단히 말해 새로운 로그 파일이 언제 생기게 할지 설정
    • fileNamePattern 태그 : 롤링된 로그 파일의 이름 및 경로 지정
      • _%i를 통해서 생성된 파일 이름 세팅
      • (새로운 파일들은 _0, _1 이 뒤에 붙어서 생성됨)
      • 해당 태그를 넣지 않으면 에러가 발생한다고 함. 반드시 설정해줘야 할 부분
    • maxFileSize 태그 : 파일의 최대 크기 설정 → 여기서는 10MB로 제한
    • maxHistory 태그 : 로그 파일의 최대 유지 개수 → 30일이 지나면 오래된 로그 순서대로 삭제
  • encoder 태그 : 로그 메시지의 출력 형식 지정
    • pattern 태그 안에 로그 메시지 출력 형식을 넣으면 됨

 

  • root 태그 : 루트 로거의 레벨 정의
    • level="INFO" : info로 정의했기 때문에 info 이상 단계의 로그만 출력
  • appender-ref 태그 : 앞에서 정의했던 appender 태그들을 참조
    • ref="{NAME}" : 앞에서 정의한 이름을 사용하면 됨
  • 루트 로거의 경우 1개 만 지정 가능
    • 여러번 설정해도 마지막에 선언한 것만 처리됨
    • 루트 로거를 설정하지 않으면 로그에 아무것도 뜨지 않게 됨

 

이렇게 하면 logback을 사용해서 로그 파일을 생성하는 작업을 완료한 것입니다.

이제 스프링 부트 프로젝트를 실행하면?

터미널에서 로그가 뜨는 것을 확인할 수 있습니다.

(참고로, 색상 설정은 안 해줬기 때문에 가독성이 떨어질 수 는 있습니다..

  색상 설정도 가능하지만, 굳이 필요하다고 생각하지는 않아서 색상 설정에 대한 부분은 설명하지 않았습니다..)

 

 

해당 경로의 폴더로 가보면

restful 폴더와 함께 log 폴더가 생성된 것을 확인할 수 있고

그 아래에는 info 폴더 & 그 아래에는 로그 파일들이 생성된 것을 확인할 수 있습니다.

그리고 sample-logger.log 파일의 내용 중 일부입니다.

잘 찍히는 것을 확인할 수 있습니다.

 

근데 이미지에서 error 폴더가 따로 있는 것을 볼 수 있네요

그러면 error 폴더가 생성되도록 설정해 봅시다!

(info 폴더 안의 로그들은 info 레벨의 로그만, error 폴더 안의 로그들은 error 레벨의 로그만 나올 수 있게 했습니다.)

 

 

도전해보고 아래를 보시면 좋을 것 같습니다.

 

 

에러 로그에 대한 설정입니다.

이름은 FILE2라고 했고,

로그 레벨의 경우 error로 설정했습니다.

경로도 error 폴더 밑에 생성되도록 했습니다.

 

루트 로거 역시도 추가로 설정해주면 됩니다.

 

그런 다음 스프링 부트 프로젝트를 실행하면...??

info 폴더와 error 폴더가 생성된 것을 확인할 수 있고,

각각 info 로그, error 로그가 생성되는 것을 확인할 수 있을 것입니다.

 

예시로 확인하는 방법이라면 다들 아시겠지만 그래도 한 번 추가해보겠습니다.

@RestController
@RequestMapping("api")
public class RestfulController {

    private final Logger log = LoggerFactory.getLogger(this.getClass());
    
    @GetMapping("/sample")
    public String getSampleOne() {
        log.error("error from log");
        log.warn( "warn from log");
        log.info( "info from log");
        log.debug("debug from log");
        log.trace("trace from log");
        
        return "This is your sample";
    }
    
}
  • RestfulController 를 하나 만들고
  • 그 안에서 로그를 출력하게 했습니다.
  • error, warn, info, debug, trace 단계의 로그가 찍히도록 설정해봤습니다.
  • 그런 다음 실행하면 어떻게 될까요?

이것에 대한 결과는 직접 확인하면 좋을 것 같습니다.

 

 

이렇게 해서 로그 파일이 생성될 수 있게 프로젝트 구성을 해봤습니다.

저는 info 레벨, error 레벨의 로그가 찍히도록 설정했는데,

추가하고 싶은 레벨의 로그나 다른 방식으로 로그가 찍히게 하는 것을 알아보는 것도 괜찮을 것 같습니다.

 

 

이렇게 해서 logback을 사용해서 로그 파일을 생성하는 방법에 대해서 알아봤습니다.