[Spring] 로그 설정 - Logback

·2024년 5월 30일

spring

목록 보기
14/18

Logback이란?

  • 자바 오픈소스 로깅 프레임워크,  SLF4J의 구현체
  • 스프링 부트 사용 시 기본으로 설정되어 있어 별도로 라이브러리를 추가하지 않아도 된다.
  • logback을 이용하여 로깅을 수행하기 위해서 필요한 주요 설정요소로는 Logger, Appender, Encoder의 3가지가 있다.

1. Logback 설정

  • 스프링, 일반 자바프로그램의 logback.xml 파일을 resources 디렉토리에 만들어서 참조한다.
  • 스프링 부트 logback-spring.xml 파일을 resources 디렉토리에 만들어서 참조한다.

2. 로그 레벨 순서 및 사용방법

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

스프링부트에서는 간단히 application.properties에 값만 세팅해도 설정 가능하다.

logging.level.root=info // 전체(루트) 로깅 레벨 설정
// 패키지별 로깅 레벨 설정
logging.level.com.project.blog=info // info
logging.level.com.project.blog.service=debug // debug

controller

package com.project.blog.controller;

@Controller
@Slf4j // Slf4j
public class TestController {
		// logger 등록
    // private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @RequestMapping(value = "/test")
    public void test() throws Exception{
        log.trace("Trace Level 테스트");
        log.debug("DEBUG Level 테스트");
        log.info("INFO Level 테스트");
        log.warn("Warn Level 테스트");
        log.error("ERROR Level 테스트");
    }
}

service

package com.project.blog.service;

@Service
@Slf4j // Slf4j
public class TestService {
		// logger 등록
    // private final Logger logger = LoggerFactory.getLogger(this.getClass());

    public void selectTest() {
        logger.trace("Trace Level 테스트");
        logger.debug("DEBUG Level 테스트");
        logger.info("INFO Level 테스트");
        logger.warn("Warn Level 테스트");
        logger.error("ERROR Level 테스트");
    }
}

결과

controller
INFO  24-02-12 17:22:35[Test worker] [TestController:13] - INFO Level 테스트
WARN  24-02-12 17:22:35[Test worker] [TestController:14] - Warn Level 테스트
ERROR 24-02-12 17:22:35[Test worker] [TestController:15] - ERROR Level 테스트
service
DEBUG 24-02-12 17:22:35[Test worker] [TestService:11] - DEBUG Level 테스트
INFO  24-02-12 17:22:35[Test worker] [TestService:12] - INFO Level 테스트
WARN  24-02-12 17:22:35[Test worker] [TestService:13] - Warn Level 테스트
ERROR 24-02-12 17:22:35[Test worker] [TestService:14] - ERROR Level 테스트

3. logback-spring.xml 설정

  • name attribute를 반드시 지정해야 한다.
  • logback-spring.xml은 appender와 logger 크게 두개로 구분된다.
  • Dynamic Reloading 기능을 지원한다.

60초 주기마다 로그파일(logback-spring.xml)이 바뀌었는지 검사하고 바뀌었으면 갱신한다.

**<?xml version="1.0" encoding="UTF-8"?>
<!-- 60초마다 설정 파일의 변경을 확인 하여 변경시 갱신 -->
<configuration scan="true" scanPeriod="60 seconds">
    로그백 설정 부분
</configuration>**

appender

log의 형태를 설정, 로그 메시지가 출력될 대상을 결정하는 요소(콘솔, 파일)

  • appender의 class 종류 ch.qos.logback.core.ConsoleAppender : 콘솔에 로그를 찍음, 로그를 OutputStream에 작성하여 콘솔에 출력되도록 한다. ch.qos.logback.core.FileAppender : 파일에 로그를 찍음, 최대 보관 일 수 등을 지정 할 수 있다. ch.qos.logback.core.rolling.RollingFileAppender : 여러개의 파일을 롤링, 순회하면서 로그를 찍는다. (FileAppender를 상속받는다. 지정 용량이 넘어간 Log File을 넘버링 하여 나누어 저장할 수 있다.) ch.qos.logback.classic.net.SMTPAppender : 로그를 메일에 찍어 보낸다. ch.qos.logback.classic.db.DBAppender : DB에 로그를 찍는다.

root, logger

설정한 appender를 참조하여 package와 level을 설정한다.

  • root
    • 전역 설정
    • 지역적으로 선언된 logger 설정이 있다면 해당 logger 설정이 default로 적용된다.
  • logger
    • 지역 설정
    • additivity 값은 root 설정 상속 유무 설정

property

설정파일에서 사용될 변수값 선언

layout, encoder

  • Layout : 로그의 출력 포맷을 지정한다.
  • encoder : Appender에 포함되어 사용자가 지정한 형식으로 표현될 메시지를 변환하는 역할

encoder는 바이트를 소유하고 있는 appender가 관리하는 OutputStream에 쓸 시간과 내용을 제어할 수 있다.

FileAppender와 하위 클래스는 encoder를 필요로 하고 더 이상은 layout은 사용하지 않는다.

pattern

  • 패턴에 사용되는 요소 %Logger{length} : Logger name을 축약할 수 있다. length는 최대 자리 수 %-5level : 로그 레벨, -5는 출력의 고정폭 값 5글자 %msg : 로그 메시지 %{PID:-} : 프로세스 아이디 %d : 로그 기록 시간 %p : 로깅 레벨 %F : 로깅이 발생한 프로그램 파일명 %M : 로깅이 발생한 메소드명 %l : 로깅이 발생한 호출지의 정보 %L : 로깅이 발생한 호출지의 라인 수 %thread : 현재 Thread 명 %t : 로깅이 발생한 Thread 명 %c : 로깅이 발생한 카테고리 %C : 로깅이 발생한 클래스 명 %m : 로그메시지 %n : 줄바꿈 %% : %를 출력 %r : 애플리케이션 시작 이후부터 로깅이 발생한 시점까지의 시간

기타

  • 기록할 파일명과 경로를 설정한다.
  • ch.qos.logback.core.rolling.TimeBasedRollingPolicy => 일자별 적용
  • ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP => 일자별 + 크기별 적용
  • 파일 쓰기가 종료된 log 파일명의 패턴을 지정한다.
  • .gz나 .zip으로 자동으로 압축할 수도 있다.
  • 한 파일당 최대 파일 용량을 지정한다.
  • log 내용의 크기도 IO성능에 영향을 미치기 때문에 되도록이면 너무 크지 않은 사이즈로 지정하는 것이 좋다.(최대 10MB 내외 권장)
  • 용량의 단위는 KB, MB, GB 3가지를 지정할 수 있다.
  • RollingFile 이름 패턴에 .gz 이나 .zip을 입력할 경우 로그파일을 자동으로 압축해주는 기능도 있다.
  • 최대 파일 생성 갯수
  • maxHistory가 30이고 Rolling정책을 일 단위로 하면 30일동안만 저장되고, 월 단위로 하면 30개월간 저장된다.
  • 해당 패키지에 무조건 로그를 찍는 것말고도 필터링이 필요한 경우에 사용하는 기능이다.

1) 스프링 프로필 설정 - application.properties

추후 dev, stg, prod 등의 환경을 별도로 선언 가능하다.

# 프로필 설정
# springBoot 2.4 이전
# spring.profiles.active=local

# springBoot 2.4 이후
spring.config.activate.on-profile=local

2) logback-local.properties 파일 생성

#로그파일 경로
#절대 경로
#(앞에 /를 넣어주면 해당 경로 아래 파일 생성)
log.config.path=/logs/local
#상대 경로
#(앞에 /없이 경로 설정 시 프로젝트 내에 파일 생성)
log.config.path=logs/local

#로그파일 이름
log.config.filename=local_log

3) logback-spring.xml 생성

<?xml version="1.0" encoding="UTF-8"?>
<!-- 60초마다 설정 파일의 변경을 확인 하여 변경시 갱신 -->
<configuration scan="true" scanPeriod="60 seconds">
    <!--springProfile 태그를 사용하면 logback 설정파일에서 복수개의 프로파일을 설정할 수 있다.-->
    <springProfile name="local">
        <property resource="logback-local.properties"/>
    </springProfile>
    <!--Environment 내의 프로퍼티들을 개별적으로 설정할 수도 있다.-->
    <springProperty scope="context" name="LOG_LEVEL" source="logging.level.root"/>

    <!-- log file path -->
    <property name="LOG_PATH" value="${log.config.path}"/>
    <!-- log file name -->
    <property name="LOG_FILE_NAME" value="${log.config.filename}"/>
    <!-- err log file name -->
    <property name="ERR_LOG_FILE_NAME" value="err_log"/>
    <!-- pattern -->
    <property name="LOG_PATTERN" value="%-5level %d{yy-MM-dd HH:mm:ss}[%thread] [%logger{0}:%line] - %msg%n"/>

    <!-- Console Appender -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- File Appender -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 파일경로 설정 -->
        <file>${LOG_PATH}/${LOG_FILE_NAME}.log</file>

        <!-- 출력패턴 설정-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>

        <!-- Rolling 정책 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- .gz,.zip 등을 넣으면 자동 일자별 로그파일 압축 -->
            <fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- 파일당 최고 용량 kb, mb, gb -->
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!-- 일자별 로그파일 최대 보관주기(~일), 해당 설정일 이상된 파일은 자동으로 제거-->
            <maxHistory>30</maxHistory>
            <!--<MinIndex>1</MinIndex>
            <MaxIndex>10</MaxIndex>-->
        </rollingPolicy>
    </appender>

    <!-- 에러의 경우 파일에 로그 처리 -->
    <appender name="Error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>error</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${LOG_PATH}/${ERR_LOG_FILE_NAME}.log</file>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
        <!-- Rolling 정책 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- .gz,.zip 등을 넣으면 자동 일자별 로그파일 압축 -->
            <fileNamePattern>${LOG_PATH}/${ERR_LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- 파일당 최고 용량 kb, mb, gb -->
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!-- 일자별 로그파일 최대 보관주기(~일), 해당 설정일 이상된 파일은 자동으로 제거-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- root레벨 설정 -->
    <root level="${LOG_LEVEL}">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
        <appender-ref ref="Error"/>
    </root>

    <!-- 특정패키지 로깅레벨 설정 -->
    <logger name="org.apache.ibatis" level="DEBUG" additivity="false">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
        <appender-ref ref="Error"/>
    </logger>
</configuration>

결과

1. Console Appender 설정

INFO  24-02-16 00:08:13[Test worker] [MessageSourceTest:42] - INFO Level 테스트
WARN  24-02-16 00:08:13[Test worker] [MessageSourceTest:43] - Warn Level 테스트
ERROR 24-02-16 00:08:13[Test worker] [MessageSourceTest:44] - ERROR Level 테스트

%-5level %d{yy-MM-dd HH:mm:ss}[%thread][%logger{0}:%line] - %msg%n
= > INFO 24-02-16 00:08:13[Test worker][MessageSourceTest:42] - INFO Level 테스트

2. File Appender 설정

경로와 파일 이름 설정 확인

3. Filter 설정(error레벨의 로그 설정)

ERROR 24-02-12 17:04:14[Test worker] [MessageSourceTest:44] - ERROR Level 테스트
ERROR 24-02-12 17:13:58[http-nio-8080-exec-1] [PostController:38] - log test
ERROR 24-02-12 17:18:40[Test worker] [MessageSourceTest:44 / logTest] - ERROR Level 테스트

에러 레벨의 로그내용만 따로 로그파일로 저장

0개의 댓글