티스토리 뷰

study/springboot

017. Logback 설정

까오기 2022. 5. 20. 09:31

Log 관련 프레임워크 간단 설명  

Title Desc
log4j Apache에서 개발한 가장 오래된 로깅 프레임워크로 2015년 기준으로 개발이 중단되었다.
log4j2 log4j 다음 버전으로 필터링 및 자동 리로딩 기능 등을 지원한다. 
logback log4j 보다 향상된 기능으로 대중적인 로깅 프레임워크이다. 스프링부트의 기본 로깅 프레임워크이다.
slf4j 직접적으로 로깅을 하는 프레임워크가 아니고 logger의 추상체로 인터페이스와 같은 역할을 한다.
slf4j로 로그를 남기지만 실제 구현 프레임워크는 logback 이나 log4j2가 될 수 있다. 

Log 프레임워크의 기본 구성 

Appender 로그 출력 관련된 설정으로 Console, File, JDBC 등을 설정할 수 있다. 
Logger 로그 메시지를 하나 이상의 appender에 전달한다. log level, appender 등 설정

Log Level

LOG LEVEL DESC
FATAL 심각한 에러 메시지
ERROR 에러 메시지 
WARN 경고 메시지 
INFO 정보성으로 중요한 메시지.
DEBUG 개발 시 필요한 메시지. 운영에서는 제외 시킨다. 
TRACE 상세 메시지 

debug는 개발 시 참고하기 위해 많이 사용 되면 운영 시에는 info 이상의 레벨로 설정합니다. 

error 레벨은 별도 error appender를 추가해서 정보성 로그와 분리해서 관리 합니다. 

Logback 설정 

Dependencies 추가 

// maven  
<dependency>
    <groupId>org.codehaus.janino</groupId>
    <artifactId>janino</artifactId>
</dependency>
// gradle
implementation 'org.codehaus.janino:janino:3.0.12'

로그 처리시 조건을 사용 할려면 위에 디펜던시를 추가해 줘야 합니다. 

설정하기 

logback은 스프링부트의 기본 로깅 프레임워크입니다. 

아무 설정을 하지 않았을 때 resources 아래 logback-spring.xml을 참고합니다. 

 

application.properties 설정 : 다른 이름으로 설정을 하고자 할때 아래처럼 등록해 주면 됩니다. 

logging.config=classpath:[설정파일명]

application.properties에서 기존에 로그 관련 설정은 다 제거합니다. 

##LOG 관련 설정 
#logging.level.root=INFO
#logging.level.org.springframework=INFO
#logging.level.eblo.study.springboot=DEBUG
##output to a temp_folder/file
#logging.file=${java.io.tmpdir}/study-springboot.log
##Logging pattern for the console
#logging.pattern.console= [%d{yyyy-MM-dd HH:mm:ss}] %-5level %logger{36} - %msg%n
## Logging pattern for file
#logging.pattern.file= %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%

profile 별 properties 추가 

/resources/logs/logback-local.properties
#로그파일 저장 분기 ZIP이면 ZIP파일로 저장 LOG이면 LOG파일로 일자별 저장
#log.config.savemode=ZIP
log.config.savemode=LOG
#ZIP모드일 경우에만 사용
#로그파일 최소 개수
log.config.min=1
#로그파일 최대 개수
log.config.max=10
#로그파일 사이즈
log.config.filesizezip=10MB
#로그파일 기간설정
log.config.days=10
#로그파일 사이즈
log.config.filesizelog=100MB
#로그파일 최대 최대 사이즈
log.config.totalfilesize=10GB
#LOG모드일 경우에만 사용
#공통 설정
#프로젝트 패키지 명
log.config.packagename=eblo.study.springboot

#로그파일모드 local/dev/product
log.config.mode=local 
#로그파일 경로
log.config.path=${java.io.tmpdir}/logs
#로그파일 이름
log.config.default.filename=study-springboot-local.log
나머지 dev, product도 생성 

logback-spring.xml 추가 

<?xml version="1.0" encoding="UTF-8"?>
<!-- 30초마다 설정 파일의 변경을 확인한다. 파일이 변경되면 다시 로딩한다 -->
<configuration scan="true" scanPeriod="30 seconds">
    <!-- profile 별 설정 가져오기  -->
    <springProfile name="local"><property resource="logs/logback-local.properties"/></springProfile>
    <springProfile name="dev"><property resource="logs/logback-dev.properties"/></springProfile>
    <springProfile name="product"><property resource="logs/logback-product.properties"/></springProfile>
    <!-- log packagename -->
    <property name="LOG_PACKAGE_NAME" value="${log.config.packagename}"/>
    <!-- log file path -->
    <property name="LOG_PATH" value="${log.config.path}"/>
    <!-- log file name -->
    <property name="LOG_FILE_NAME" value="${log.config.default.filename}"/>
    <!-- log days -->
    <property name="LOG_DAYS" value="${log.config.days}"/>
    <!-- log filesize log -->
    <property name="LOG_FILESIZE_LOG" value="${log.config.filesizelog}"/>
    <!-- log filesize zip -->
    <property name="LOG_FILESIZE_ZIP" value="${log.config.filesizezip}"/>
    <!-- log filesize total -->
    <property name="LOG_TOTAL_FILESIZE" value="${log.config.totalfilesize}"/>
    <!-- log min count -->
    <property name="LOG_FILE_MIN" value="${log.config.min}"/>
    <!-- log max count -->
    <property name="LOG_FILE_MAX" value="${log.config.max}"/>
    <!-- pattern -->
    <property name="LOG_PATTERN_DEFAULT" value="[%d{yyyy-MM-dd HH:mm:ss}] %-5level %logger{36} - %msg%n"/>
    <property name="LOG_PATTERN_DEFAULT_ERROR" value="[%d{yyyy-MM-dd HH:mm:ss}] %-5level %logger{36} - %msg%n"/>

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

    <!-- 테스트를 위한 설정 -->
    <appender name="ERROR_CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN_DEFAULT_ERROR}</pattern>
        </encoder>
    </appender>
    <!-- file appender -->
    <appender name="INFO_DEFAULT_FILE_APPENDER"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/${LOG_FILE_NAME}.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}.log
            </fileNamePattern>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN_DEFAULT}</pattern>
        </encoder>
    </appender>

    <appender name="ERROR_DEFAULT_FILE_APPENDER" 
              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}/${LOG_FILE_NAME}-error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}-error.%d{yyyy-MM-dd}.log
            </fileNamePattern>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN_DEFAULT}</pattern>
        </encoder>
    </appender>
    
    <!-- 운영 -->
    <if condition='property("log.config.mode").equals("product")'>
        <then>
            <logger name="${LOG_PACKAGE_NAME}" additivity="false">
                <level value="INFO"/>
                <appender-ref ref="ERROR_DEFAULT_FILE_APPENDER"/>
                <appender-ref ref="INFO_DEFAULT_FILE_APPENDER"/>
            </logger>
            <logger name="org.springframework" additivity="false">
                <level value="INFO"/>
                <appender-ref ref="ERROR_DEFAULT_FILE_APPENDER"/>
            </logger>
            <root level="INFO">
                <appender-ref ref="ERROR_DEFAULT_FILE_APPENDER"/>
                <appender-ref ref="INFO_DEFAULT_FILE_APPENDER"/>
            </root>
        </then>
        <else>
            <if condition='property("log.config.mode").equals("dev")'>
                <!-- 개발 -->
                <then>
                    <logger name="${LOG_PACKAGE_NAME}" additivity="false">
                        <level value="INFO"/>
                        <appender-ref ref="CONSOLE"/>
                        <appender-ref ref="INFO_DEFAULT_FILE_APPENDER"/>
                    </logger>
                    <logger name="org.springframework" additivity="false">
                        <level value="INFO"/>
                        <appender-ref ref="CONSOLE"/>
                        <appender-ref ref="INFO_DEFAULT_FILE_APPENDER"/>
                    </logger>
                    <root level="INFO">
                        <appender-ref ref="CONSOLE"/>
                        <appender-ref ref="INFO_DEFAULT_FILE_APPENDER"/>
                    </root>
                </then>
                <!-- 로컬 local -->
                <else>
                    <logger name="${LOG_PACKAGE_NAME}" additivity="false">
                        <level value="DEBUG"/>
                        <appender-ref ref="CONSOLE"/>
                    </logger>
                    <logger name="org.springframework" additivity="false">
                        <level value="INFO"/>
                        <appender-ref ref="CONSOLE"/>
                    </logger>
                    <root level="DEBUG">
                        <appender-ref ref="CONSOLE"/>
                    </root>
                </else>
            </if>
        </else>
    </if>
        
</configuration>

profile에 따른 설정 정보 가져 오기

<springProfile name="local"></springProfile>

설정 값을 변수에 담기 

<property name="LOG_PACKAGE_NAME" value="${log.config.packagename}"/>

에러 레벨만 로그를 남기는 appender

    <appender name="ERROR_DEFAULT_FILE_APPENDER" 
              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>
        ... 
    </appender>

조건에 따른 처리 부분 

    <!-- 운영 -->
    <if condition='property("log.config.mode").equals("product")'>
        <then>
            ...
        </then>
        <else>
	        <if condition='property("log.config.mode").equals("local")'>
                <!-- 로컬 local -->
		        <then>
                    ....
		        </then>
                <!-- 개발 -->
                <else>
                    ....
                </else>
            </if>
        </else>
    </if>

예제

Controller 일반 

@Slf4j
@RestController
public class ProfileTestAPIController {

    @Value("${app.title}")
    private String appTitle;
    
    @GetMapping("/profile")
    public String test() {
        log.debug("debug : "+appTitle);
        log.info("info : "+appTitle);
        log.error("error : "+appTitle);
        return appTitle;
    }
    
}

결과

[2022-05-20 09:29:31] DEBUG e.s.s.p.ProfileTestAPIController - debug : springboot-study-local
[2022-05-20 09:29:31] INFO  e.s.s.p.ProfileTestAPIController - info : springboot-study-local
[2022-05-20 09:29:31] ERROR e.s.s.p.ProfileTestAPIController - error : springboot-study-local

참고 

PatternLayout 등 설정 참고

- https://logback.qos.ch/manual/layouts.html

 

댓글
댓글쓰기 폼
공지사항
Total
500,989
Today
70
Yesterday
310
링크
«   2022/10   »
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
글 보관함