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로 사전 설정되어 있습니다. 즉, TRACEDEBUG 메시지가 표시되지 않습니다.

구성을 변경하지 않고 활성화하기 위해 명령 줄에 –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>

응용 프로그램을 실행하면 다음과 같은 결과가 나타납니다.

 

보시다시피, 이제 TRACEDEBUG 메시지를 기록 하고 전체 콘솔 패턴은 이전과 텍스트 및 색채가 모두 다릅니다.

또한 현재 경로 아래에 생성 된 / 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 프로젝트 내에서 주요 로깅 프레임 워크와 인터페이스하는 주요 방법을 보았습니다.

또한 각 솔루션의 주요 장점과 함정을 살펴 보았습니다.

항상 그렇듯이 전체 소스 코드는 GitHub에서 사용할 수 있습니다 .