Spring Boot 中的日志记录

更新于 2025-12-30

Andrea Ligios 2018-07-04

1. 概述

在本篇简短教程中,我们将探索 Spring Boot 中可用的主要日志记录选项。

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 Boot 2.x)中,它由 Spring Framework 的 spring-jcl 模块提供。

如果你使用了 Spring Boot Starter(几乎总是如此),就完全不必担心手动引入 spring-jcl。因为每个 Starter(例如 spring-boot-starter-web)都依赖于 spring-boot-starter-logging,而后者已经自动包含了 spring-jcl

3.1. 默认使用 Logback 日志

当你使用 Spring Boot Starter 时,默认使用 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、DEBUG 和 INFO,则最终生效的是 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 会自动生成默认文件名(如 spring.log)。

注意:在 Spring Boot 2.3 之前,对应的属性名为 logging.pathlogging.file

4. 使用 Logback 配置日志

尽管默认配置对快速原型开发(POC)很有帮助,但在实际项目中通常不够用。

下面我们展示如何使用自定义的 Logback 配置:

  • 自定义颜色和日志格式
  • 分别配置控制台和文件输出
  • 设置合理的滚动策略,避免日志文件过大

为避免污染 application.properties(通常用于其他应用配置),建议将日志配置单独管理。

只要在 classpath 中存在以下任一文件名,Spring Boot 会自动加载它以覆盖默认配置:

  • logback-spring.xml
  • logback.xml
  • logback-spring.groovy
  • logback.groovy

建议:尽可能使用 -spring 后缀的文件(如 logback-spring.xml),因为它支持 Spring Boot 特有的功能(如 profile 条件配置)。

下面是一个简单的 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">
            <!-- 每天滚动,并且当文件达到 10MB 时也滚动 -->
            <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>
    
    <!-- 所有日志默认记录 INFO 级别 -->
    <root level="info">
        <appender-ref ref="RollingFile" />
        <appender-ref ref="Console" />
    </root>

    <!-- com.baeldung 包下记录 TRACE 级别 -->
    <logger name="com.baeldung" level="trace" additivity="false">
        <appender-ref ref="RollingFile" />
        <appender-ref ref="Console" />
    </logger>

</configuration>

运行应用后,你会看到:

  • TRACE 和 DEBUG 消息现在可见
  • 控制台输出格式和颜色与默认不同
  • 日志同时写入 ./logs/ 目录下的文件,并按滚动策略归档

5. 使用 Log4j2 配置日志

虽然 Spring Boot 核心基于 Apache Commons Logging,且默认使用 Logback,但它也内置了对其他日志框架的桥接支持,便于切换。

要使用 Log4j2(或其他非 Logback 框架),需先从依赖中排除 Logback。

例如,对于每个 Starter(如 spring-boot-starter-web):

<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-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>
                <!-- 启动时、每天、以及文件达到 10MB 时滚动 -->
                <OnStartupTriggeringPolicy />
                <SizeBasedTriggeringPolicy size="10 MB" />
                <TimeBasedTriggeringPolicy />
            </Policies>
        </RollingFile>
    </Appenders>

    <Loggers>
        <!-- 所有日志默认记录 INFO 级别 -->
        <Root level="info">
            <AppenderRef ref="Console" />
            <AppenderRef ref="RollingFile" />
        </Root>

        <!-- com.baeldung 包下记录 TRACE 级别 -->
        <Logger name="com.baeldung" level="trace"></Logger>
    </Loggers>

</Configuration>

运行后,你会发现输出风格与 Logback 明显不同,证明已成功切换到 Log4j2。

补充:Log4j2 还支持 YAML 或 JSON 格式的配置文件。

6. 不通过 SLF4J 直接使用 Log4j2

你也可以绕过 SLF4J,直接使用 Log4j2 的原生 API:

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

无需额外配置,即可使用 Log4j2 的全部新特性。但缺点是代码与 Log4j2 强耦合,未来切换日志框架时需重写日志代码。

7. 使用 Lombok 简化日志

前面的例子中,我们需要手动声明 Logger 实例,这属于样板代码。Lombok 可以帮我们消除它。

首先添加 Lombok 依赖:

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

7.1. @Slf4j@CommonsLog

SLF4J 和 Apache Commons Logging 提供了日志框架解耦的能力。Lombok 的 @Slf4j@CommonsLog 注解可自动注入对应的 Logger 实例。

示例(使用 @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。
使用 @CommonsLog 效果类似,只是 Logger 类型为 org.apache.commons.logging.Log

7.2. @Log4j2

若想直接使用 Log4j2 原生 API,可使用 @Log4j2 注解:

@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...";
    }
}   

8. 警惕 Java Util Logging

Spring Boot 也支持 JDK 自带的 java.util.logging(JUL),通过 logging.properties 配置。

但官方文档指出:

在“可执行 JAR”中运行时,Java Util Logging 存在已知的类加载问题。强烈建议尽可能避免在可执行 JAR 中使用它

此外,在 Spring 4 中,建议在 pom.xml 中手动排除 commons-logging 以避免日志库冲突。Spring 5(即 Spring Boot 2+)已自动处理此问题,无需额外操作。

9. Windows 下的 JANSI 支持

Linux 和 macOS 默认支持 ANSI 颜色代码,但 Windows 控制台默认是黑白的。

可通过 JANSI 库启用彩色日志:

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 配置

Log4j2 默认在 Windows 上不启用 ANSI。需:

  1. 添加 JANSI 依赖
  2. 设置系统属性 log4j.skipJansi=false

注意:Log4j 2.10 之前 JANSI 默认启用;此后因 JANSI 依赖本地代码,可能引发类加载问题(尤其在 Web 应用中),故改为需显式启用。

另外:

  • Log4j2 的 highlight{pattern}{style} 语法支持 JANSI 样式
  • 即便启用了 JANSI,Spring Boot 的 Banner(无论是默认还是通过 banner.txt 自定义)仍为单色

10. 结论

我们探讨了在 Spring Boot 项目中集成主流日志框架的主要方式,并分析了每种方案的优缺点与注意事项。