1. 概述

日志是任何软件应用的重要组成部分,它帮助排查问题和调试。此外,日志还可用于监控目的。Spring Boot 支持主流日志框架,如 LogbackLog4j2Spring Boot 为 Logback 和 Log4j2 提供了几个扩展,可用于高级配置

本教程将深入探讨 Spring Boot 应用中的 Logback 和 Log4j2 扩展功能。

2. Logback 扩展

Spring Boot 默认使用 Logback 库处理日志。本节将介绍几个有助于高级配置的 Logback 扩展。

⚠️ 注意Spring Boot 推荐使用 logback-spring.xml 而非默认的 logback.xml标准 logback.xml 无法使用扩展功能,因为该配置文件加载过早

2.1. Maven 依赖

使用 Logback 需要在 pom.xml 中添加 logback-classic 依赖。但该依赖已包含在 Spring Boot Starter 依赖中。

因此只需添加 spring-boot-starter-web 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2.2. 基础日志

首先在主类中添加日志示例:

@SpringBootApplication
public class SpringBootLogbackExtensionsApplication {

    private static final Logger logger = LoggerFactory.getLogger(SpringBootLogbackExtensionsApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(SpringBootLogbackExtensionsApplication.class, args);

        logger.debug("Debug log message");
        logger.info("Info log message");
        logger.error("Error log message");
        logger.warn("Warn log message");
        logger.trace("Trace log message");
    }
}

2.3. 环境特定配置

Spring profiles 提供基于激活环境调整应用配置的机制。

例如可为不同环境(如 developmentproduction)定义独立配置。若想使用单一配置文件,可在 logback-spring.xml 中使用 springProfile 元素

通过 springProfile 元素,可根据激活的 Spring profiles 选择性包含/排除配置段。使用 name 属性指定生效的环境

默认 Spring Boot 仅输出到控制台。假设生产环境输出到文件,开发环境输出到控制台:

<springProfile name="development">
    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
        </layout>
    </appender>
    <root level="info">
        <appender-ref ref="Console" />
    </root>
</springProfile>

<springProfile name="production">
    <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{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
    </appender>
    <root level="info">
        <appender-ref ref="RollingFile" />
    </root>
</springProfile>

通过 JVM 参数 -Dspring.profiles.active=development-Dspring.profiles.active=production 激活环境。

当使用 development 环境运行时,控制台输出如下:

10:31:13.766 [main] INFO  c.b.e.SpringBootLogbackExtensionsApplication - Info log message
10:31:13.766 [main] ERROR c.b.e.SpringBootLogbackExtensionsApplication - Error log message
10:31:13.766 [main] WARN  c.b.e.SpringBootLogbackExtensionsApplication - Warn log message

若需同时支持 stagingproduction 环境,可使用 profile 表达式:

<springProfile name="production | staging">
    <!-- 配置内容 -->
</springProfile>

productionstaging 任一环境激活时生效。

2.4. 环境属性

有时需要在日志配置中访问 application.properties 的值,此时可使用 springProperty 元素

springProperty 类似 Logback 的标准 property 元素,但属性值来自环境而非直接指定。

springPropertysource 属性指定应用属性名,若未设置则使用 defaultValue 属性的默认值。name 属性用于在配置中引用该属性。

可通过 scope 属性设置作用域,context 作用域的属性在所有日志事件中可用。

假设使用应用名称作为日志文件名。首先在 application.properties 中定义:

spring.application.name=logback-extension

然后在 logback-spring.xml 中暴露该属性:

<property name="LOGS" value="./logs" />
<springProperty scope="context" name="application.name" source="spring.application.name" />
<springProfile name="production">
    <appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOGS}/${application.name}.log</file>
        <!-- 其他配置 -->
    </appender>
</springProfile>

上述配置通过 ${application.name} 引用属性值。

3. Log4j2 扩展

Log4j2 扩展与 Logback 扩展类似。标准 log4j2.xml 无法使用扩展,因其加载过早

Spring Boot 推荐将配置保存在 log4j2-spring.xml 文件中,该文件会优先加载。

3.1. Maven 依赖

要使用 Log4j2 替代默认 Logback,需从 starter 依赖中排除 Logback

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

并添加 spring-boot-starter-log4j2log4j-spring-boot 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-spring-boot</artifactId>
</dependency>

踩坑警告:缺少 log4j-spring-boot 会导致以下错误:

2023-01-21 15:56:12,473 main ERROR Error processing element SpringProfile ([Loggers: null]): CLASS_NOT_FOUND

3.2. 环境特定配置

虽然多数情况下使用独立配置文件可行,但有时需要单一配置文件支持多环境。此时可使用 SpringProfile 元素添加环境支持

示例 log4j2-spring.xml

<SpringProfile name="development">
    <Logger name="com.baeldung.extensions" level="debug"></Logger>
</SpringProfile>

<SpringProfile name="production">
    <Logger name="com.baeldung.extensions" level="error"></Logger>
</SpringProfile>

使用 production 环境运行时,仅输出 ERROR 级别日志:

2023-01-22T11:19:52,885 ERROR [main] c.b.e.SpringBootLog4j2ExtensionsApplication: Error log message
2023-01-22T11:19:52,885 FATAL [main] c.b.e.SpringBootLog4j2ExtensionsApplication: Fatal log message

注意SpringProfile 段可出现在 configuration 元素内的任何位置。

3.3. 环境属性查找

Log4j2 Lookups 提供为日志配置提供值的方式。

可通过 spring- 前缀查找访问 application.properties 的值,包括激活的默认环境配置

application.properties 中设置:

spring.application.name=log4j2-extension

log4j2-spring.xml 中读取:

<Console name="Console-Extensions" target="SYSTEM_OUT">
    <PatternLayout
        pattern="%d %p %c{1.} [%t] ${spring:spring.application.name} %m%n" />
</Console>

运行后控制台输出:

2023-01-22 16:17:30,301 ERROR c.b.e.SpringBootLog4j2ExtensionsApplication [main] log4j2-extension Error log message
2023-01-22 16:17:30,301 FATAL c.b.e.SpringBootLog4j2ExtensionsApplication [main] log4j2-extension Fatal log message

3.4. Log4j2 系统属性

Log4j2 提供多个系统属性用于配置。这些属性可添加到 log4j2.system.properties 文件中。

例如添加 log4j2.debug=true 属性,可将内部日志输出到控制台:

TRACE StatusLogger Log4jLoggerFactory.getContext() found anchor class java.util.logging.Logger

系统属性也可在 application.properties 中设置,但 log4j2.system.properties 中的属性优先级更高。

4. 总结

Spring Boot 提供强大的日志支持。本教程探讨了 Spring Boot 中的 Logback 和 Log4j2 扩展功能。

完整源码可在 GitHub 获取:


原始标题:Spring Boot Logback and Log4j2 Extensions