1. 개요
이 짧은 자습서에서는 Spring Boot에서 사용할 수있는 주요 로깅 옵션을 살펴 보겠습니다.
Logback에 대한 자세한 정보는 A Guide to Logback 에서 확인할 수 있으며 Log4j2는 Intro to Log4j2 – Appenders, Layouts and Filters 에 소개되어 있습니다.
2. 초기 설정
먼저 Spring Boot 모듈을 만들어 보겠습니다. 권장하는 방법은 Spring Initializr 를 사용하는 것인데, 이는 Spring Boot Tutorial 에서 다룹니다 .
이제 유일한 클래스 파일 인 LoggingController를 만들어 보겠습니다 .
@RestController
public class LoggingController {
Logger logger = LoggerFactory.getLogger(LoggingController.class);
@RequestMapping("/")
public String index() {
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");
return "Howdy! Check out the Logs to see the output...";
}
}
웹 애플리케이션을로드하면 http : // localhost : 8080 /을 방문하여 로깅 행을 트리거 할 수 있습니다 .
3. 제로 구성 로깅
Spring Boot는 매우 유용한 프레임 워크입니다. 이를 통해 대부분의 구성 설정을 잊어 버릴 수 있으며 대부분은 자동 조정됩니다.
로깅의 경우 유일한 필수 의존성은 Apache Commons Logging입니다.
Spring 5 ( Spring Boot 2.x ) 에서 Spring Framework의 spring-jcl 모듈에서 제공하므로 Spring 4.x ( Spring Boot 1.x )를 사용할 때만 가져 오면 됩니다.
Spring Boot Starter (거의 항상 그렇습니다) 를 사용하는 경우 spring-jcl 을 가져 오는 것에 대해 전혀 걱정할 필요가 없습니다 . 모든 스타터, 우리처럼 때문이다 스프링 부팅 스타터 웹 에 따라 달라 스프링 부팅 스타터 로깅, 이미 끌어 스프링 JCL 우리를 위해.
3.1. 기본 로그 백 로깅
스타터를 사용할 때 Logback은 기본적으로 로깅에 사용됩니다.
Spring Boot는 패턴과 ANSI 색상으로 미리 구성하여 표준 출력을 더 읽기 쉽게 만듭니다.
이제 애플리케이션을 실행하고 http : // localhost : 8080 / 페이지를 방문 하여 콘솔에서 어떤 일이 발생하는지 살펴 보겠습니다 .
보시다시피 Logger의 기본 로깅 수준은 INFO로 사전 설정되어 있습니다. 즉, TRACE 및 DEBUG 메시지가 표시되지 않습니다.
구성을 변경하지 않고 활성화하기 위해 명령 줄에 –debug 또는 –trace 인수를 전달할 수 있습니다 .
java -jar target/spring-boot-logging-0.0.1-SNAPSHOT.jar --trace
3.2. 로그 수준
또한 Spring Boot는 환경 변수를 통해보다 세분화 된 로그 수준 설정에 대한 액세스를 제공합니다. 이를 달성 할 수있는 몇 가지 방법이 있습니다.
먼저 VM 옵션에서 로깅 수준을 설정할 수 있습니다.
-Dlogging.level.org.springframework=TRACE
-Dlogging.level.com.baeldung=TRACE
또는 Maven을 사용 하는 경우 명령 줄을 통해 로그 설정을 정의 할 수 있습니다 .
mvn spring-boot:run
-Dspring-boot.run.arguments=--logging.level.org.springframework=TRACE,--logging.level.com.baeldung=TRACE
Gradle로 작업 할 때 명령 줄을 통해 로그 설정을 전달할 수 있습니다. 이렇게 하려면 bootRun 작업을 설정 해야 합니다 .
완료되면 애플리케이션을 실행합니다.
./gradlew bootRun -Pargs=--logging.level.org.springframework=TRACE,--logging.level.com.baeldung=TRACE
상세도를 영구적으로 변경하려면 여기에 설명 된대로 application.properties 파일 에서 변경할 수 있습니다 .
logging.level.root=WARN
logging.level.com.baeldung=TRACE
마지막으로 로깅 프레임 워크 구성 파일을 사용하여 로깅 수준을 영구적으로 변경할 수 있습니다.
Spring Boot Starter는 기본적으로 Logback을 사용한다고 언급했습니다. 두 개의 개별 패키지에 대한 수준을 설정하는 Logback 구성 파일의 일부를 정의하는 방법을 살펴 보겠습니다.
<logger name="org.springframework" level="INFO" />
<logger name="com.baeldung" level="INFO" />
기억 패키지의 로그 수준이 여러 번 정의 된 경우 위에서 언급 한 여러 가지 옵션을 사용하여,하지만 다른 로그 수준, 가장 낮은 수준이 사용됩니다.
따라서 Logback, Spring Boot 및 환경 변수를 동시에 사용하여 로깅 수준을 설정 하면 요청 된 수준 중 가장 낮은 수준이므로 로그 수준은 TRACE 가됩니다.
4. 로그 백 구성 로깅
기본 구성이 유용하더라도 (예 : POC 또는 빠른 실험 중에 제로 시간에 시작하기 위해) 일상적인 요구 사항에 충분하지 않을 가능성이 큽니다.
콘솔 및 파일 출력에 대한 별도의 사양 , 대용량 로그 파일 생성을 방지하기 위해 적절한 롤링 정책 을 사용하여 다른 색상 및 로깅 패턴을 사용 하여 Logback 구성을 포함하는 방법을 살펴 보겠습니다 .
먼저 다른 많은 애플리케이션 설정에 일반적으로 사용되는 application.properties 를 오염시키는 대신 로깅 설정 만 처리 할 수있는 솔루션을 찾아야합니다 .
클래스 경로의 파일에 다음 이름 중 하나가 있으면 Spring Boot는 기본 구성을 통해 파일 을 자동으로로드 합니다.
- logback-spring.xml
- logback.xml
- logback-spring.groovy
- logback.groovy
Spring 은 여기에 설명 된대로 가능할 때마다 일반 버전 보다 -spring 변형 을 사용할 것을 권장 합니다 .
간단한 logback-spring.xml을 작성해 보겠습니다 .
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOGS" value="./logs" />
<appender name="Console"
class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
</Pattern>
</layout>
</appender>
<appender name="RollingFile"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS}/spring-boot-logger.log</file>
<encoder
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
</encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily and when the file reaches 10 MegaBytes -->
<fileNamePattern>${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- LOG everything at INFO level -->
<root level="info">
<appender-ref ref="RollingFile" />
<appender-ref ref="Console" />
</root>
<!-- LOG "com.baeldung*" at TRACE level -->
<logger name="com.baeldung" level="trace" additivity="false">
<appender-ref ref="RollingFile" />
<appender-ref ref="Console" />
</logger>
</configuration>
응용 프로그램을 실행하면 다음과 같은 결과가 나타납니다.
보시다시피, 이제 TRACE 및 DEBUG 메시지를 기록 하고 전체 콘솔 패턴은 이전과 텍스트 및 색채가 모두 다릅니다.
또한 현재 경로 아래에 생성 된 / logs 폴더 의 파일에 로그온 하여 롤링 정책을 통해 보관합니다.
5. Log4j2 구성 로깅
Apache Commons Logging이 핵심이고 Logback이 제공되는 참조 구현이지만 다른 로깅 라이브러리로의 모든 라우팅이 이미 포함되어있어 쉽게 전환 할 수 있습니다.
하지만 Logback 이외의 로깅 라이브러리를 사용하려면 의존성에서 제외해야합니다.
다음과 같은 모든 스타터에 대해 (이 예제에서는 유일한 것이지만 많은 것을 가질 수 있습니다) :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
우리는 그것을 스키니 버전으로 바꾸고, (한 번만) 스타터 자체를 통해 대체 라이브러리를 추가해야합니다.
<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>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
이 시점에서 다음 중 하나라는 이름의 파일을 클래스 경로에 배치해야합니다.
- log4j2-spring.xml
- log4j2.xml
추가 수정없이 Log4j2 (SLF4J를 통해)를 통해 인쇄합니다.
간단한 log4j2-spring.xml을 작성해 보겠습니다 .
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable" />
</Console>
<RollingFile name="RollingFile"
fileName="./logs/spring-boot-logger-log4j2.log"
filePattern="./logs/$${date:yyyy-MM}/spring-boot-logger-log4j2-%d{-dd-MMMM-yyyy}-%i.log.gz">
<PatternLayout>
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
</PatternLayout>
<Policies>
<!-- rollover on startup, daily and when the file reaches
10 MegaBytes -->
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy
size="10 MB" />
<TimeBasedTriggeringPolicy />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<!-- LOG everything at INFO level -->
<Root level="info">
<AppenderRef ref="Console" />
<AppenderRef ref="RollingFile" />
</Root>
<!-- LOG "com.baeldung*" at TRACE level -->
<Logger name="com.baeldung" level="trace"></Logger>
</Loggers>
</Configuration>
응용 프로그램을 실행하면 다음과 같은 결과가 나타납니다.
보시다시피 출력은 Logback의 출력과 상당히 다릅니다. 이는 현재 Log4j2를 완전히 사용하고 있다는 증거입니다.
XML 구성 외에도 Log4j2를 사용하면 여기 에 설명 된 YAML 또는 JSON 구성도 사용할 수 있습니다 .
6. SLF4J없는 Log4j2
SLF4J를 통과하지 않고 기본적으로 Log4j2를 사용할 수도 있습니다.
이를 위해 우리는 단순히 네이티브 클래스를 사용합니다.
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
// [...]
Logger logger = LogManager.getLogger(LoggingController.class);
표준 Log4j2 Spring Boot 구성에 대해 다른 수정을 수행 할 필요가 없습니다.
이제 이전 SLF4J 인터페이스에 얽매이지 않고 Log4j2의 새로운 기능을 활용할 수 있습니다. 그러나 우리는 또한이 구현에 묶여 있으며 다른 로깅 프레임 워크로 전환 할 때 코드를 다시 작성해야합니다.
7. Lombok으로 로깅
지금까지 본 예제 에서 로깅 프레임 워크에서 로거 인스턴스를 선언해야했습니다 .
이 상용구 코드는 성 가실 수 있습니다. Lombok에서 도입 한 다양한 어노테이션을 사용하여이를 피할 수 있습니다.
먼저 빌드 스크립트에 Lombok 의존성을 추가해야합니다.
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
7.1. @ Slf4j 및 @CommonsLog
SLF4J 및 Apache Commons 로깅 API를 사용하면 코드에 영향을주지 않고 로깅 프레임 워크를 유연하게 변경할 수 있습니다.
그리고 Lombok의 @ Slf4j 및 @CommonsLog 어노테이션 을 사용하여 올바른 로거 인스턴스를 클래스에 추가 할 수 있습니다. SLF4J의 경우 org.slf4j.Logger , Apache Commons 로깅의 경우 org.apache.commons.logging.Log 입니다.
이러한 어노테이션이 작동하는 것을보기 위해 LoggingController 와 유사 하지만 로거 인스턴스가없는 클래스를 만들어 보겠습니다 . LombokLoggingController 로 이름을 지정하고 @ Slf4j로 어노테이션을 추가합니다 .
@RestController
@Slf4j
public class LombokLoggingController {
@RequestMapping("/lombok")
public String index() {
log.trace("A TRACE Message");
log.debug("A DEBUG Message");
log.info("An INFO Message");
log.warn("A WARN Message");
log.error("An ERROR Message");
return "Howdy! Check out the Logs to see the output...";
}
}
로그 를 로거 인스턴스로 사용하여 스 니펫을 약간 조정했습니다 . @ Slf4j 어노테이션을 추가하면 log 라는 필드가 자동으로 추가 되기 때문 입니다.
함께 제로 구성 로깅 , 응용 프로그램이 기본 로깅 구현 Logback를 사용 로깅. 마찬가지로 Log4j2 구현은 Log4j2- 구성 로깅을 사용한 로깅에 사용됩니다.
@ Slf4j 어노테이션을 @CommonsLog 로 바꾸면 동일한 동작이 발생 합니다.
7.2. 뿡 빵뀨
@ Log4j2 어노테이션 을 사용하여 Log4j2를 직접 사용할 수 있습니다. 따라서 @ Slf4j 또는 @CommonsLog 대신 @ Log4j2 를 사용 하도록 LombokLoggingController 를 간단히 변경합니다 .
@RestController
@Log4j2
public class LombokLoggingController {
@RequestMapping("/lombok")
public String index() {
log.trace("A TRACE Message");
log.debug("A DEBUG Message");
log.info("An INFO Message");
log.warn("A WARN Message");
log.error("An ERROR Message");
return "Howdy! Check out the Logs to see the output...";
}
}
로깅 외에도 코드를 깔끔하고 깔끔하게 유지하는 데 도움이되는 Lombok의 다른 어노테이션이 있습니다. 이에 대한 자세한 정보는 Introduction to Project Lombok 에서 확인할 수 있으며 , Setting Up Lombok With Eclipse 및 IntelliJ 에 대한 자습서도 있습니다 .
8. Java Util 로깅주의
Spring Boot는 logging.properties 구성 파일을 통해 JDK 로깅도 지원 합니다.
하지만 사용하는 것이 좋지 않은 경우가 있습니다. 에서 문서 :
'실행 가능한 jar'에서 실행할 때 문제를 일으키는 Java Util Logging에 알려진 클래스 로딩 문제가 있습니다. 가능하면 '실행 가능한 jar'에서 실행할 때 피하는 것이 좋습니다.
로깅 라이브러리 간의 잠재적 인 충돌을 피하기 위해 Spring 4를 사용하여 pom.xml에서 commons-logging 을 수동으로 제외하는 것도 좋은 방법 입니다. 대신 Spring 5가 자동으로 처리하므로 Spring Boot 2를 사용할 때 아무것도 할 필요가 없습니다.
9. Windows의 JANSI
Linux 및 Mac OS X와 같은 Unix 기반 운영 체제는 기본적으로 ANSI 색상 코드를 지원하지만 Windows 콘솔에서는 모든 것이 슬프게도 단색입니다.
Windows는 JANSI라는 라이브러리를 통해 ANSI 색상을 얻을 수 있습니다.
하지만 가능한 클래스 로딩 단점에주의를 기울여야합니다.
다음과 같이 구성에서 가져 와서 명시 적으로 활성화해야합니다.
로그 백 :
<configuration debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<withJansi>true</withJansi>
<encoder>
<pattern>[%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n</pattern>
</encoder>
</appender>
<!-- more stuff -->
</configuration>
Log4j2 :
ANSI 이스케이프 시퀀스는 기본적으로 많은 플랫폼에서 지원되지만 Windows에서는 기본적으로 지원되지 않습니다. ANSI 지원을 활성화하기 위해, 우리의 응용 프로그램 및 설정 속성에 Jansi 항아리를 추가 log4j.skipJansi 에 거짓 . 이를 통해 Log4j는 Jansi를 사용하여 콘솔에 쓸 때 ANSI 이스케이프 코드를 추가 할 수 있습니다.
참고 : Log4j 2.10 이전에는 Jansi가 기본적으로 활성화되었습니다. Jansi에 네이티브 코드가 필요하다는 사실은 Jansi가 단일 클래스 로더에 의해서만로드 될 수 있음을 의미합니다 . 웹 애플리케이션의 경우 이는 Jansi jar가 웹 컨테이너의 클래스 경로에 있어야 함을 의미 합니다. 웹 응용 프로그램에 문제가 발생하지 않도록 Log4j는 더 이상 Log4j 2.10부터 명시적인 구성없이 Jansi를 자동으로로드하려고 시도하지 않습니다.
또한 주목할 가치가 있습니다.
- 레이아웃 문서 페이지가 유용 Log4j2 JANSI의 정보가 포함되어 하이라이트 {패턴} {스타일} 절을 참조하십시오.
- JANSI는 출력에 색상을 지정할 수 있지만 Spring Boot의 배너 (기본 또는 banner.txt 파일을 통해 사용자 지정 )는 단색으로 유지됩니다.
10. 결론
우리는 Spring Boot 프로젝트 내에서 주요 로깅 프레임 워크와 인터페이스하는 주요 방법을 보았습니다.
또한 각 솔루션의 주요 장점과 함정을 살펴 보았습니다.