본문 바로가기
Spring

Spring boot 환경 logback 설정 및 날짜별 로그 저장

by yang sing 2024. 5. 31.

안녕하세요.

이번 포스팅은 spring boot에서 log를 남길 수 있는 logback 설정에 대해서 작성을 해보려고 합니다.

제가 회사에서 클라이언트의 요청에 따라 로그의 위치와 디렉토리 구조를 알맞게 설정을 해야하는 업무가 있었는데요.

해당 업무를 하면서 매번 써오던 logback 설정에 대해서 놓쳤었던 부분을 잊지 않고자 포스팅을 하게 되었습니다.

사실 해당 포스팅은 개념적인 내용을 담기보다는 실제로 제가 프로젝트를 진행하다 삽질했던 부분에 대해서 작성을 하려고 했기 때문에

개념 정리가 좀 부족할 수 있습니다. 😂

 

log란

프로그램에서 log란 개발자 혹은 어플리케이션 관리자 등에게 있어서 매우 중요한 운영 기록이라고 할 수 있습니다.
어플리케이션을 개발할 때 혹은 운영중에 예기치 못한 장애가 발생했을 때 해당 원인을 빠르게 확인하기 위해 log를 미리 설정하고
이러한 상황에 직면 했을 때 log 파일을 보며 문제를 해결하는데 도움을 주게 됩니다.
따라서 로그는 단순 프로그램의 동작을 기록하기보다는 어떤 이벤트가 실행이 되었는지 어떤 장애가 발생했는지 장애의 내용은 무엇인지 
보다 다양하게 로그를 남겨서 어플리케이션을 개발 또는 운영하기에 용의하게 만들어줘서 
개발자인 우리에게는 선택이 아닌 필수인것 같습니다.

 

loggin 라이브러리

Spring에서 사용되는 logging 라이브러리는 대표적으로 log4j, log4j2, logback이 있습니다. 
log4j는 여러 취약점이 발견되어 요즘 사람들은 많이 사N용하지 않는 라이브러리로 
그 다음 개발된 logback과 log4j의 취약점을 보완한 log4j2를 많이 사용하고 있습니다.
오늘 포스팅은 logback 설정에 대해서 알아보려고 합니다.

 

logback

- logback의 가장 큰 장점은 spring boot 환경에서 spring-boot-starter-web이라는 패키지 안에 기본적으로 탑재가 되어있어 별도의 dependency(의존성)을 추가하지 않고도 사용할 수 있습니다.
- slf4j의 구현체 라이브러리를 사용할 수 있으며 추후 다른 logging 라이브러리로 교체를 하더라도 log쪽 코드를 수정하지는 않아도 됩니다.

 

logback의 요소 

1. appender  

로그 파일을 어디에 출력을 할지 지정해주는 설정 부분으로 console, log file로 로그를 남길 위치를 지정할 수 있습니다.

- ConsoleAppender : 로그를 콘솔에 출력

- FileAppender : 로그를 파일로 출력 및 저장

- RollingFileAppender : 로그를 용량, 시간 또는 일자별로 출력 및 저장

2. encoder

로그 파일을 남길 때 어떤 식으로 남길지 로그 메세지의 출력 패턴을 지정할 수 있게 해주는 설정입니다.

로그 패턴에 대해서는 추후에 다른 포스팅으로 자세하게 남기도록 해보겠습니다.

3.  logger 

실제로 로깅을 수행하는 객체로 로깅을 남기고 싶은 대성을 지정하고 해당 대상에 대해서 어느 레벨로 로깅을 남길지 지정할 수 있습니다.

 

 

logback-spring.xml

정말 간단하게 logback과 3가지 요소에 대해서 알아봤으니 이제 실제로 logback이 어떤식으로 작성이 되는지에 대해서 알아보겠습니다.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

	<!-- 로그 console 출력 설정 -->
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%thread] %highlight(%-5level) %cyan(%logger{15})[%line] - %msg%n</pattern>
        </encoder>
    </appender>

    <!--로그 파일 저장 위치-->
    <property name="LOGS_PATH" value="./logs"/>
    
    <!--로그 파일 rolling 저장 -->
    <appender name="DAILY_ROLLING_FILE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 기본 로그 파일명 설정 --> 
        <file>${LOGS_PATH}/application-logging.log</file>
        
        <!-- 로그를 남길 패턴 설정 -->
        <encoder>
            <pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{35}[%line] - %msg%n</pattern>
        </encoder>
        
        <!-- 로그 파일을 일자, 크기 별로 생성 설정 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOGS_PATH}/application-logging-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>60</maxHistory>
        </rollingPolicy>
    </appender>
    
    <!-- 로그를 남길 대상 및 로그 레벨 설정 -->
    <logger name="com.test.project" level="DEBUG">
        <appender-ref ref="DAILY_ROLLING_FILE_APPENDER"/>
    </logger>
    <logger name="org.springframework.web.client" level="trace">
        <appender-ref ref="DAILY_ROLLING_FILE_APPENDER"/>
    </logger>
</configuration>

 

위 코드에서 보면 STDOUT과 DAILY_ROLLING_FILE_APPENDER 두개의 appender 설정이 있는데 

STDOUT은 ConsoleAppender 클래스를 사용해 해당 appender를 사용하면 콘솔창에 로그를 남기겠다는 설정이고

DAILY_ROLLING_FILE_APPENDER은 RollingFileAppender 클래스를 사용해 로그를 로그 파일로 남기는데 일자와 로그 파일 크기별로 나눠서 저장을 하겠다는 설정이다.

 

RollingFileAppender 설정을 좀 더 자세히 살펴보도록 하겠습니다. 

<property name="LOGS_PATH" value="./logs"/>

 

property 태그를 사용하여 로그 파일을 저장할 기본 경로를 지정할 수 있다.

이렇게 기본 저장 경로를 property로 남겨두면 아래에서 file 설정이나 fileNamePattern에서 재사용을 하기 편하다

 

<file>${LOGS_PATH}/application-logging.log</file>

다음으로 file 태그를 살펴보면 위에서 설정한 로그 파일 경로를 ${}를 사용해 file 경로의 값을 적용 시킬 수 있다.

위 내용으로 보아 로그 파일은 해당 spring boot가 실행이 되고 있는 디렉토리의 logs/application-logging.log가 생성이 될것이다.

 

<encoder>
    <pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{35}[%line] - %msg%n</pattern>
</encoder>

encoder 태그는 로그가 어떤 형식으로 기록이 할지 패턴을 지정해주는 부분이다.

 

%d : 날짜를 의미하고 %d{yyyy-MM-dd HH:mm:ss}의 경우 로그의 시간이 2024-05-30 22:18:00 와 같은 날짜형식으로 출력이 된다.

%-3relative : 초 단위 아래의 밀리초를 표시하고 숫자 3은 몇번째 자리까지 출력할지를 지정한다.

%thread :  현재 실행 되고 있는 스레드명을 출력한다.

%-5level : 로그 레벨을 출력한다. 숫자는 글자 수를 의미한다.

%logger{35} : 단순 %logger는 현재 로그가 출력되는 패키지를 포함하는 클래스 명을 의미하고 {n}의 의미는 해당 클래스 명을 최대 n숫자로 축약해서 표시를 하겠다는 의미이다.

%line : 로그가 출력 되고 있는 부분의 라인을 표시한다.

%msg : 로그 메세지를 출력한다. 

%n : 줄바꿈 

 

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>${LOGS_PATH}/application-logging-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <maxFileSize>100MB</maxFileSize>
    </timeBasedFileNamingAndTriggeringPolicy>
    <maxHistory>60</maxHistory>
</rollingPolicy>

 

마지막으로 로그 파일을 날짜, 용량에 따라 분리해서 저장을 할 수 있게 해주는 rollingPolicy를 살펴 보도록 하겠다.

fileNamePattern 를 설정하여 롤링 규칙에 맞게 로그 파일을 어떤식으로 파일을 저장할지를 설정할 수 있다.

${LOGS_PATH}는 위에서 설정한 property 태그에서 설정한 기본 로그 경로이며

 

%d{yyyy-MM-dd} 설정은 날짜 형식으로 application-logging-2024-05-30 과 같이 표시하겠다는 의미이다.

 

%i 설정은 해당 로그 파일이 같은 날짜에 여러개가 생길 때 카운팅 해주는 숫자를 의미한다

가령 application-logging-2024-05-30 파일의 로그가 하루에 2~3개가 생성이 되면 application-logging-2024-05-30.0.log.gz, application-logging-2024-05-30.1.log.gz, application-logging-2024-05-30.2.log.gz 과같이 날짜 뒤에 숫자를 붙여서 저장을 하게 된다.

 

maxFileSize 태그는 해당 로그 파일의 최대 용량을 설정하며 해당 용량에 맞게 로그 파일이 차게 되면 위와 같이 파일을 나눠서 저장을 하게 된다.

 

maxHistory 태그는 해당 로그 파일을 최대 며칠까지 보관을 할지 지정하고 해당 기간이 지나면 가장 오래된 파일부터 삭제를 하겠다는 설정이다.

 

 

마치며

이렇게 오늘은 logback의 간단한 설명과 실제로 어떻게 사용을 하는지에 대해서 작성을 해보았습니다.

사실 이번 포스팅은 제가 프로젝트를 진행하며 격었던 트러블 슈팅을 위한거였는데 

작성을 하다보니 정작 제가 마주쳤던 이슈에 대해서는 언급을 못했습니다.

 

다음 포스팅에서 이어서 제가 마주했던 상황과 어떻게 해결을 해나갔는지에대해서 포스팅을 하도록 하겠습니다.

 

오늘도 제 글을 읽어주셔서 감사합니다.