기록하기

logback 설정 - 특정 변수에 따라 log 파일 다른 위치에 저장하기 본문

Server/Spring Boot

logback 설정 - 특정 변수에 따라 log 파일 다른 위치에 저장하기

jjungdev 2022. 8. 25. 17:44

회사에서 프로젝트를 진행하던 중 logback 설정을 수정해야 했는데 이때 적용한 방법을 정리해보고자 한다.

 

기존 프로젝트를 리팩토링하는 과정에서, 기존과는 다르게 특정 변수에 따라 log 파일의 위치가 다르게 저장이 되어야 하는 요구사항이 추가되었다. 이 요구사항을 적용하기 전과 후의 상태를 간단하게 살펴보기 위해 logback 프로젝트를 생성해보았다.

 

프로젝트 구조 및 api 상황

  • Spring Boot
  • Java 8
  • Spring Data JPA
  • H2 Database

 

요구사항 적용 전

예시를 통해 설명을 하자면,

만약 DB 에서 어떤 값을 조회해오는 api 하나가 있다고 할 때, 성공/실패의 결과만 구분되어 log 가 쌓이고 있었다고 가정하자

이 경우에는 아래와 같이 설정을 하면 success, error 로그가 각 위치에 저장이 될 것이다.

 

AS-IS
로그 저장 방법 file 로 저장
저장 위치 /log/success or /log/error
저장 파일 success.log
error.log

 

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">

    <appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
        <param name="Target" value="System.out" />
        <encoder>
            <pattern>%5p [%d] [%C:%M] - [%m]%n</pattern>
        </encoder>
    </appender>

    <appender name="SuccessRollingAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>./log/success/success.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>./log/success/success.log.%d{yyyy-MM-dd-HH}</fileNamePattern>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <encoder>
            <pattern>%5p [%d] [%C:%M] - [%m]%n</pattern>
        </encoder>
    </appender>

    <appender name="DailyAndErrorRollingAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>./log/error/error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>./log/error/error.log.%d{yyyy-MM-dd-HH}</fileNamePattern>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <encoder>
            <pattern>%5p [%d] [%C:%M] - [%m]%n</pattern>
        </encoder>
    </appender>

    <!-- SuccessLogger -->
    <logger name="com.example.logback.service.SuccessLogger" additivity="true" level="INFO">
        <appender-ref ref="SuccessRollingAppender" />
    </logger>

    <!-- ErrorLogger -->
    <logger name="com.example.logback.service.ErrorLogger" additivity="true" level="ERROR">
        <appender-ref ref="DailyAndErrorRollingAppender" />
    </logger>

    <root level="INFO">
        <appender-ref ref="Stdout"/>
    </root>
</configuration>

 

요구사항 적용 전에는 아래와 같이 파일이 저장된다.

 

요구사항 적용 후

만약, Log 엔티티에 들어오는 값 중에서 key 컬럼에 따라 success/error 를 구분하여 log 파일이 생성되도록 하려면 어떻게 해야할까?

즉, success/error 아래에 KEY1.log, KEY2.log 등 따로 저장되도록 하고 싶다면 아래와 같이 설정해주면 이를 해결할 수 있다.

 

TO-BE
로그 저장 방법 file 로 저장
저장 위치 /log/success or /log/error
저장 파일 ${KEY}.log

 

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">

    <appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
        <param name="Target" value="System.out" />
        <encoder>
            <pattern>%5p [%d] [%C:%M] - [%m]%n</pattern>
        </encoder>
    </appender>

    <appender name="siftSuccess" class="ch.qos.logback.classic.sift.SiftingAppender">
        <discriminator>
            <key>key</key>
            <defaultValue>dev</defaultValue>
        </discriminator>
        <sift>
            <appender name="SuccessRollingAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <file>./log/success/${key}.log</file>
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <fileNamePattern>./log/success/${key}.log.%d{yyyy-MM-dd-HH}</fileNamePattern>
                </rollingPolicy>
                <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                    <level>INFO</level>
                </filter>
                <encoder>
                    <pattern>%5p [%d] [%C:%M] - [%m]%n</pattern>
                </encoder>
            </appender>
        </sift>
    </appender>

    <appender name="siftError" class="ch.qos.logback.classic.sift.SiftingAppender">
        <discriminator>
            <key>key</key>
            <defaultValue>dev</defaultValue>
        </discriminator>
        <sift>
            <appender name="DailyAndErrorRollingAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <file>./log/error/${key}.log</file>
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <fileNamePattern>./log/error/${key}.log.%d{yyyy-MM-dd-HH}</fileNamePattern>
                </rollingPolicy>
                <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                    <level>DEBUG</level>
                </filter>
                <encoder>
                    <pattern>%5p [%d] [%C:%M] - [%m]%n</pattern>
                </encoder>
            </appender>
        </sift>
    </appender>

    <!-- SuccessLogger -->
    <logger name="com.example.logback.service.SuccessLogger" additivity="true" level="INFO">
        <appender-ref ref="siftSuccess" />
    </logger>

    <!-- ErrorLogger -->
    <logger name="com.example.logback.service.ErrorLogger" additivity="true" level="ERROR">
        <appender-ref ref="siftError" />
    </logger>

    <root level="INFO">
        <appender-ref ref="Stdout"/>
    </root>
</configuration>

 

그러면 아래와 같이 저장이 된다.

 

여기서 logback-spring.xml 파일에서 ShiftingAppender 라는 구조를 사용한 것인데, 여기서 구분자가 되어주는 key 는 log 를 찍는 SuccessLogger, ErrorLogger 에서 MDC 를 활용해 다음과 같이 값을 넣어주었다.

MDC.put("key", key);

 

그러면 이 값의 key 값으로 "key" 를 넣었기 때문에 그 값에 해당하는 값을 가져와서 파일을 만들어주도록 설정을 한다면 이에 따라 다른 log 파일을 생성할 수 있게 된다.

<appender name="siftSuccess" class="ch.qos.logback.classic.sift.SiftingAppender">
        <discriminator>
            <key>key</key>
            <defaultValue>dev</defaultValue>
        </discriminator>
        <sift>
        
        ...
        
</appender>

 

 

간단한 예제를 통해 log 파일 설정을 살펴보았는데 좀 더 보강이 필요한 프로젝트이나 logback 설정 방법을 찾아보던 중 유용한 정보라고 생각되어 정리를 해보았다.

추후에는 logback 의 기본 구조에 대해서도 좀 더 정리를 해보겠다.

 

 

참고

https://jeong-pro.tistory.com/199

 

Spring에서 Logback을 이용해서 필터없이 별도의 디렉토리에 로그를 남기는 방법 (Logback MDC 사용법,

로그를 분류해야하는 경우 스프링에서 로그를 남길 때 대부분 Logback을 사용한다. 보통 한 파일에 모든 로그를 남기기보다는 기능, 모듈별로 로그를 남기거나 어떠한 기준(로그 레벨등...)에 의해

jeong-pro.tistory.com

 

https://livenow14.tistory.com/64

 

[Logging] Logback이란?

블로그를 작성하고, 테코톡을 진행했어요. 더 쉽게 이해하고 싶다면 아래 영상을 시청해주세요! [10분 테코톡] ☂️ 검프의 Logging(로깅) #2 Logback 로깅 프레임워크 중 하나로, SLF4J의 구현체에요. SL

livenow14.tistory.com