[Spring Boot] Logback

2021. 3. 31. 16:39Spring/Spring Boot

1. Logback

1) Logback 이란?

Logback은 Java 오픈 소스 로깅 프레임워크 SLF4J의 구현체이다. 스프링 부트의 기본으로 설정('spring-boot-starter-web'에 spring-boot-starter-logging' 존재)되어 있어 별도의 라이브러리가 필요하지 않다. log4j, log4j2 등과 비교했을 때, logback이 더 훌륭한 성능을 보여준다. Logback을 이용하여 로깅ㅇ르 수행하기 위해서 필요한 주요 설정요소로는 Logger, Appender, Encoder의 3가지가 있다.

2) 설정

  • Spring, Java - logback.xml 파일을 resources 디렉토리에 만들어서 참조
  • Spring Boot - logback-spring.xml 파일을 resource 디렉토리에 만들어서 참조

 

참조 순서는 다음과 같다.

1. classpath(resources)에 logback-spring.xml 파일이 있을 경우 설정파일을 읽어간다.

2. logback-spring.xml 파일이 없을 경우 .yml 파일의 설정을 읽어간다.

3. logback-spring.xml 파일과 .yml 파일이 동시에 있을 경우 .yml 파일 적용 후 xml 파일이 적용된다.

 

Spring Boot에서는 logback-spring.xml을 사용해서 Spring이 logback을 구동할 수 있도록 지원해주며 이를 이용하여 배포 환경에 따른 설정 properties를 읽어올 수 있다.

spring.profiles.active=local
logback-local.properties => console-logging
logback-dev.properties => file-logging
logback-prod.properties => file-logging,remote-logging

3) 로그 레벨 순서 및 사용 방법

"TRACE < DEBUG < INFO < WARN < ERROR"

 

로그에 설정할 수 있는 레벨은 총 5개가 존재한다.

로그 레벨 설명
ERROR 요청을 처리하는 중 오류가 발생한 경우
WARN 처리 가능한 문제, 향후 시스템 에러의 원인이 될 수 있는 경고성 메시지
INFO 상태변경과 같은 정보성 로그
DEBUG 프로그램을 디버깅하기 위한 정보
TRACE DEBUG보다 훨씬 상세한 정보 (추적)

출력 레벨의 설정에 따라 설정 레벨 이상의 로그를 출력한다. 만약 로깅 레벨을 INFO로 했을 경우, TRACE, DEBUG 레벨은 무시하게 된다.

 

로깅 레벨은 전체적으로 지정할 수 있고, 패키지 별로 로깅 레벨을 application.properties 파일에 세팅하여 이용할 수 있다.

logging.level.root=info

logging.level.com.example=info

4) 예시

LoggerFactory에서 객체를 불러온 후 객체를 이용해서 코드의 원하는 부분에 로그를 찍으면 된다.

@Controller 
public class TestController { 

    private final Logger logger = LoggerFactory.getLogger(this.getClass()); 

    @RequestMapping(value = "/test") 
    public ModelAndView test() throws Exception { 
    
        logger.trace("Trace Level 테스트"); 
        logger.debug("DEBUG Level 테스트"); 
        logger.info("INFO Level 테스트"); 
        logger.warn("Warn Level 테스트"); 
        logger.error("ERROR Level 테스트"); 
        
        return mav;
    } 
}
@Service 
public class TestService { 

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Autowired 
    public TestMapper mapper;
    
    public List<TestVo> selectTest() { 
    
        logger.trace("Trace Level 테스트"); 
        logger.debug("DEBUG Level 테스트"); 
        logger.info("INFO Level 테스트"); 
        logger.warn("Warn Level 테스트"); 
        logger.error("ERROR Level 테스트"); 
        return mapper.selectTest(); 
    }
}

5) 기본 특징

  • 기본적으로 대소문자를 구별하지 않는다. (<logger> == <LOGGER>)
  • name attribute를 반드시 지정해주어야 한다.
  • Logback-spring.xml은 appender와 logger로 구분된다.
  • Dynamic Reloading 기능을 지원한다. (60초 주기로 로그 파일이 변경되었는지 검사하고 변경되었다면 프로그램 갱신)

6) appender

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

클래스 설명
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에 로그를 찍는다. 

7) root, logger

설정한 appender를 참조하여 패키지와 레벨을 설정한다.

  • root - 전역 설정, 지역적으로 선언된 logger가 있을 시 해당 logger 설정이 default로 적용
  • logger - 지역 설정, additivity 값은 root 설정 상속 유무 설정 (기본 true)

8) property

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

9) layout, encoder

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

encoder는 바이트를 소유하고 있는 appender가 관리하는 OutputStream에 쓸 시간과 내용을 제어할 수 있다. FileAppender와 하위 클래스는 encoder를 필요로 하고 더 이상 layout은 사용하지 않는다. 결국, layout보다는 encoder를 사용하면 된다.

10) 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)

11) 태그

태그 설명
<file> 기록할 파일명과 경로를 설정한다.
<rollingPolicy class> ch.qos.logback.core.rolling.TimeBasedRollingPolicy (일자별 적용)
ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP (일자별 + 크기별 적용)
<fileNamePattern> 파일 쓰기가 종료된 log 파일명의 패턴을 지정한다. .gz나 .zip으로 자동으로 압축할 수도 있다.
<maxFileSize> 한 파일당 최대 파일 용량을 지정한다. log 내용의 크기도 IO성능에 영향을 미치기 때문에 되도록이면 너무 크지 않은 사이즈로 지정하는 것이 좋다. (최대 10MB 내외 권장)

용량의 단위는 KB, MB, GB 3가지를 지정할 수 있다.
RollingFile 이름 패턴에 .gz 이나 .zip을 입력할 경우 로그파일을 자동으로 압축해주는 기능도 있다.
<maxHistory> 최대 파일 생성 갯수를 의미한다. 예를 들어 maxHistory가 30이고 Rolling정책을 일 단위로 하면 30일동안만 저장되고, 월 단위로 하면 30개월간 저장된다.
<Filter> 해당 패키지에 무조건 로그를 찍는 것 말고도 필터링이 필요한 경우에 사용하는 기능이다.

12) 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>
    <springProfile name="dev"> 
        <property resource="logback-dev.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>
                

[참고] goddaehee.tistory.com/206

728x90