Springboot Logging 적용 - logback
Springboot에서의 Logging
Springboot에서는 Logging 설정을 자동적으로 지원
slf4j 로깅 Facade를 통해 logback을 기본적으로 지원하고 있음
slf4j란?
Simple Logging Facade for Java (SLF4J) LINK
SLF4J는 다양한 로깅 프레임워크(java.util.logging / logback / log4j 등)에 대한 간단한 Facade* 또는 추상화 역할을 하여 사용자가 설정(deployment)하는 경우 원하는 로깅 프레임워크를 플러그인할 수 있도록 함
로깅 API를 분리하면 애플리케이션과 특정 로깅 프레임워크간의 관계가 느슨해지고, 이를 통해 기존 또는 다른 코드와 쉽게 통합하거나 이미 다른 로깅을 사용한 프로젝트에 코드를 제공할 수 있음
Facade 패턴
- 어떤 서브시스템의 일련의 인터페이스에 대해 통합된 인터페이스를 제공
- Facade에서 고수준 인터페이스를 정의하기 때문에 서브 시스템을 더 쉽게 사용할 수 있음
기본 logging 해보기
// BoardApplication
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BoardApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(BoardApplication.class);
// WepApplication 사용 안함 설정 - NONE
application.setWebApplicationType(WebApplicationType.NONE);
application.run(args);
}
}
// AppRunner
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
// ApplicationRunner - 애플리케이션 실행 후 추가로 실행하고 싶은 것 구현할 때 사용
public class AppRunner implements ApplicationRunner {
// Logger 생성 - LoggerFactory.getLogger(클래스명)
// lombok을 이용한다면, 클래스 위에 @Slf4j 애너테이션을 다는 것으로 대체할 수 있음
// - @Slf4j 사용시 log라는 필드가 생겨서, log.info("") 이런 식으로 사용
private Logger logger = LoggerFactory.getLogger(AppRunner.class);
@Override
public void run(ApplicationArguments args) {
/* logging - 레벨별로 설정 가능
logger.trace("A TRACE Message");
logger.debug("A DEBUG Message");
logger.info("An INFO Message");
logger.warn("A WARN Message");
logger.error("An ERROR Message");
*/
logger.info("=======================");
logger.info("Jamie's Spring Boot App");
logger.info("=======================");
}
}
결과 - Application 실행시, 로깅한 내용 확인됨
Logging 설정하기 - application.properties
# 콘솔 창에 출력되는 로깅 메세지를 색으로 구분해서 출력
spring.output.ansi.enabled=always
# 로그 메세지가 저장되는 디렉터리 (절대경로/상대경로 모두 가능)
# 이렇게 설정하면, logs/spring.log로 LOG_FILE이 잡히고, LOG_PATH로는
logging.file.path=logs
# 로그 레벨 - logging.level.{패키지 경로}를 통해 설정
logging.level.com.github.jamie9504.board=DEBUG
Logging Extentions(확장)
Springboot에서는 기본적으로 logback 모듈을 제공, logback 모듈의 설정 정보를 logback-spring.xml 파일로 따로 관리할 수 있음
Logback 확장이 가능한 이유
Web Application 시작하면 classpath 내에서 환경 파일(logback.xml)을 검색해서 logback을 초기화시킴
=> Spring 구동 전의 시점
Springboot의 경우 logback-spring.xml을 사용해 Spring이 logback을 구동할 수 있도록 지원해줌
=> profile이나 application.properties에 설정된 properties들을 읽어올 수 있음
application.properties
logging.level info를 전체에 적용
profile 설정을 다중으로 할 수 있게 설정 적용 - 추후 application.properties를 환경별로 분리한다면 다양하게 적용할 수 있도록
# 콘솔 창에 출력되는 로깅 메세지를 색으로 구분해서 출력
spring.output.ansi.enabled=always
# 로그 메세지가 저장되는 디렉터리 (절대경로/상대경로 모두 가능)
logging.file.path=logs
# 로그 레벨 - logging.level.{패키지 경로}를 통해 설정
logging.level.root=DEBUG
# profile 설정
spring.profiles.include=file-logging,console-logging
logback-spring.xml
다중 profile을 위해 console-logging, file-logging 분리
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds">
<property name="LOG_PATH" value="${LOG_PATH}"/>
<property name="LOG_FILE_NAME" value="spring"/>
<property name="ERR_LOG_FILE_NAME" value="error"/>
<property name="LOG_PATTERN"
value="%-5level %d{yy-MM-dd HH:mm:ss}[%thread] [%logger{0}:%line] - %msg%n"/>
<property name="LOG_CONSOLE_PATTERN"
value="%black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable"/>
<springProfile name="console-logging">
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_CONSOLE_PATTERN}</pattern>
</encoder>
</appender>
</springProfile>
<springProfile name="file-logging">
<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>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</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>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${ERR_LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>60</maxHistory>
</rollingPolicy>
</appender>
</springProfile>
<root>
<springProfile name="console-logging">
<appender-ref ref="CONSOLE"/>
</springProfile>
<springProfile name="file-logging">
<appender-ref ref="FILE"/>
</springProfile>
<springProfile name="remote-logging">
<appender-ref ref="REMOTE_LOG_SERVER"/>
</springProfile>
</root>
</configuration>
적용 결과
logback이 아닌 다른 로깅 모듈로 바꾸고 싶다면?
의존성 파일(build.gradle / pom.xml)에서 logback을 제거한 후, 다른 로깅 모듈 의존성을 추가
Gradle
// 제외
configurations {
all {
compile.exclude module: 'spring-boot-starter-logging'
}
}
// 추가 - 예. log4j2
dependencies {
compile 'org.springframework.boot:spring-boot-starter-log4j2'
}
Maven
<dependency>
<!-- 제거 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
<!-- 추가 - 예: log4j2 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
참고하면 좋을 글
https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-logging - 공식 문서
https://meetup.toast.com/posts/149 - Springboot + logback 설명이 상세히 잘 나와있음
https://www.baeldung.com/spring-boot-logging - Springboot logging 설명이 나와있음(영어)
- application.properties 관련 설정 공식 문서