知識庫 / Spring / Spring Boot RSS 訂閱

Spring Boot 登錄

Logging,Spring Boot
HongKong
5
01:45 PM · Dec 06 ,2025

1. 概述

在本教程中,我們將探索 Spring Boot 中可用的主要日誌選項。

有關 Logback 的更詳細信息,請參閲《Logback 指南》,而 Log4j2 的介紹則在《Log4j2 – Appenders、佈局和過濾器》中。

2. 初始設置

首先,讓我們創建一個 Spring Boot 模塊。推薦的方法是使用 Spring Initializr,正如我們在 Spring Boot 教程中所介紹的。

現在,讓我們創建一個唯一的類文件,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...";
    }
}

在加載 Web 應用程序後,只需訪問 http://localhost:8080/,即可觸發這些日誌行。

3. 無配置日誌

Spring Boot 是一個非常實用的框架。它允許我們忘記大部分的配置設置,其中許多配置設置是它帶有偏見的自動調整。

在日誌方面,唯一的強制依賴是 Apache Commons Logging

我們只需要在使用 Spring 4.x 時導入它 (Spring Boot 1.x),因為在 Spring 5 中,它由 Spring Framework 的 spring-jcl 模塊提供 (Spring Boot 2.x)。

如果使用 Spring Boot Starter,我們完全不必擔心導入 spring-jcl (而我們幾乎總是這樣做的)。這是因為每個 Starter,比如我們的 spring-boot-starter-web,都依賴於 spring-boot-starter-logging,它已經替我們導入了 spring-jcl

3.1. 默認 Logback 日誌記錄

使用啓動器時,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. 日誌級別 (Log Levels)

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,因為它是在請求級別中最低的級別。

3.3. 默認日誌文件

默認情況下,Spring Boot 將消息記錄到控制枱。但是,它也允許將日誌寫入文件,同時保留控制枱輸出。我們可以使用 logging.file.namelogging.file.path 屬性來實現這一點。當同時設置這兩個屬性時,logging.file.name 將具有優先權,logging.file.path 將被忽略。

以下是在 application.properties 文件中的示例配置:

logging.file.name=logs/app.log
logging.file.path=logs

logging.file.name 屬性指定了完整的路徑,包括目錄和文件名。如果指定的該文件不存在,Spring Boot 將會自動創建它。此外,文件路徑可以是絕對路徑或相對路徑。

此外,logging.file.path 屬性指定了用於存儲日誌文件的目錄。如果僅設置此屬性,Spring Boot 將自動為日誌文件生成默認文件名。 類似於logging.file.name 屬性,文件路徑可以是絕對路徑或相對路徑。

重要的是,在 Spring Boot 版本 2.3 之前,等效的屬性名為 logging.pathlogging.name

<h2><strong>4. Logback 配置日誌</strong></h2>
<p>即使默認配置也很有用(例如,在POC或快速實驗中以零時間開始),但它很可能不足以滿足我們的日常需求。</p>
<p>讓我們看看<strong>如何包含一個Logback配置</strong>,使用不同的顏色和日誌模式,併為<em>控制枱</em>和<em>文件</em>輸出指定不同的規範,以及具有合理的<em>滾動策略</em>,以避免生成巨大的日誌文件。</p>
<p>首先,我們應該找到一種解決方案,允許我們單獨處理日誌設置,而不是污染<em>application.properties</em>,該文件通常用於許多其他應用程序設置。</p>
<p><strong>當類路徑中的文件具有以下名稱時,Spring Boot 將自動加載</strong>它,覆蓋默認配置:</p>
<ul>
 <li><em>logback-spring.xml</em></li>
 <li><em>logback.xml</em></li>
 <li><em>logback-spring.groovy</em></li>
 <li><em>logback.groovy</em></li>
</ul>
<p><strong>Spring 建議儘可能使用<em>-spring</em>變體</strong>,如文檔<a href="https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html#boot-features-custom-log-configuration">中所述</a>。</p>
<p>讓我們編寫一個簡單的<em>logback-spring.xml</em>:</p>
<?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>
    <version>3.5.7</version>
</dependency>

我們需要將其轉換為一個精簡版本,並且(僅一次)添加我們的替代庫,通過一個啓動器在這裏實現:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>3.5.7</version>
    <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>
    <version>3.5.7</version>
</dependency>

此時,我們需要將以下文件放置在 classpath 中:

  • 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

我們可以直接使用 Log4j2,無需通過 SLF4J。

為了實現這一點,我們只需使用原生類:

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
// [...]
Logger logger = LogManager.getLogger(LoggingController.class);

我們不需要對標準的 Log4j2 Spring Boot 配置進行任何其他修改。

現在我們可以利用 Log4j2 的全新功能,而無需被舊的 SLF4J 接口所困擾。但我們也因此與該實現方案綁定,在切換到其他日誌框架時,我們需要重寫我們的代碼。

7. 使用 Lombok 進行日誌記錄

在我們之前看到的示例中,我們需要聲明一個日誌記錄器實例,來自我們的日誌記錄框架。

這部分樣板代碼可能會令人厭煩。我們可以使用 Lombok 引入的各種註解來避免它。

首先,我們需要在構建腳本中添加 Lombok 依賴才能使用它:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.42</version>
    <scope>provided</scope>
</dependency>

7.1. @Slf4j@CommonsLog</h3

SLF4J 和 Apache Commons Logging API 允許我們無需影響代碼的情況下,靈活地更改日誌框架。

並且我們可以 使用 Lombok 的 @Slf4j@CommonsLog 註解 將正確的日誌器實例添加到我們的類中:org.slf4j.Logger 用於 SLF4J,org.apache.commons.logging.Log 用於 Apache Commons Logging。

要查看這些註解在行動中的效果,讓我們創建一個類似於 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...";
    }
}

請注意,我們對片段進行了輕微調整,使用 log 作為我們的logger實例。這是因為添加 @Slf4j 註解會自動添加名為 log 的字段。

通過 零配置日誌,應用程序將使用底層日誌實現 Logback 進行日誌記錄。同樣,Log4j2 實現也用於與 Log4j2-Configuration Logging 配合使用進行日誌記錄。

當我們用 @CommonsLog 替換 @Slf4j 註解時,我們也能獲得相同的行為。

7.2. @Log4j2

我們可以使用註解 @Log4j2 直接使用 Log4j2。因此,我們修改了 LombokLoggingController,使用 @Log4j2 代替 @Slf4j@CommonsLog

@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 還提供其他註解,以幫助我們保持代碼的整潔和有序。有關更多信息,請參閲《Lombok 項目介紹》,我們還提供關於使用 Eclipse 和 IntelliJ 設置 Lombok 的教程。

8. 謹防使用 Java Util Logging

Spring Boot 也支持 JDK 日誌,通過 logging.properties 配置文件的支持。

儘管如此,在某些情況下,不建議使用它。如 文檔所述:

Java Util Logging 存在已知的問題,會導致在“可執行 jar”中運行時出現問題。因此,如果可能,我們建議避免在“可執行 jar”中運行時。

此外,在 Spring 4 中手動排除 commons-logging 在 pom.xml 中,以避免日誌庫之間的潛在衝突,也是一個好習慣。Spring 5 則自動處理,因此在使用 Spring Boot 2 時,我們無需進行任何操作。

9. Windows 上的 JANSI

雖然基於 Unix 的操作系統,如 Linux 和 Mac OS X,默認支持 ANSI 顏色代碼,但在 Windows 命令行中,一切都將是單色的。

Windows 可以通過名為 JANSI 的庫獲取 ANSI 顏色。

我們應該注意潛在的類加載問題。

必須導入並明確在配置中激活它,如下所示:

Logback:

<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 JAR 包添加到我們的應用程序中,並將屬性 log4j.skipJansi 設置為 false。這允許 Log4j 使用 Jansi 添加 ANSI 轉義碼,以便在向控制枱寫入時使用。

注意:在 Log4j 2.10 之前,Jansi 默認啓用。由於 Jansi 需要本機代碼,因此 Jansi 只能被單個類加載器加載。對於 Web 應用程序,這意味着 Jansi JAR 包必須位於 Web 容器的類路徑中。為了避免 Web 應用程序出現問題,Log4j 不再在 Log4j 2.10 及更高版本中嘗試在沒有 Log4j 顯式配置的情況下加載 Jansi。

此外,還值得注意的是:

  • 佈局 文檔頁面包含有用的 Log4j2 JANSI 信息,在 highlight{pattern}{style} 部分。
  • 雖然 JANSI 可以着色輸出,但 Spring Boot 的 Banner(原生或通過 banner.txt 文件自定義)將保持單色。

10. 結論

我們已經瞭解瞭如何在 Spring Boot 項目中與主要日誌框架進行交互的主要方法。

我們還探討了每種解決方案的主要優勢和潛在問題。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.