Spring Boot 中 Logback 和 Log4j2 的扩展
1、概览
日志是系统中的一个重要组件。Spring Boot 支持 Logback 和 Log4j2 日志框架,并且提供了一些扩展,可用于高级配置。
在本教程中,我将带你学习如何在 Spring Boot 中使用 Logback 和 Log4j2 的扩展进行高级的日志配置。
2、Logback 扩展
Spring Boot 默认使用 Logback 进行日志记录。在本节中,我们将了解 Logback 的一些扩展,以进行高级配置。
注意:Spring Boot 建议使用 logback-spring.xml
作为 Logback 的配置文件名称,而不是默认的 logback.xml
。因为 logback.xml
配置文件会被 Logback 默认加载,它会比 Spring 更早地加载进系统,所以我们不能在标准的 logback.xml
中使用扩展,
2.1、Maven 依赖
要使用 Logback,我们需要在 pom.xml
中添加 logback-classic
依赖项。
spring-boot-starter-web 依赖已经包含了它,所以不需要额外导入 logback-classic
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.2、基本日志
首先,在 Spring Boot main 类中输出一些示例日志:
@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、Profile 设置
Spring profile 提供了一种根据激活的 profile 调整应用配置的机制。
例如,我们可以为 “development” 和 “production” 等不同环境定义不同的 Logback 配置文件。如果我们只想使用一个 Logback 配置文件,那么可以在 logback-spring.xml
中使用 springProfile
元素。
使用 springProfile
元素,我们可以根据激活的 profile 选择性地包含或排除某些配置。通过 name
属性来指定当前节点下的配置在哪个 profile 被激活时生效。
默认情况下,Spring Boot 只把日志输出到控制台。现在,假设我们想在 “production” profile 下把日志输出到文件,而在 “development” profile 下输出到控制台。使用 springProfile
元素可以轻松实现。
创建 logback-spring.xml
文件:
<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
来设置激活的 profile。
现在,如果我们在 development
profile 下运行 Spring Boot 应用程序,控制台中将显示以下日志输出:
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
name
属性还支持表达式,用于描述更复杂的 profile
逻辑。例如,我们希望在 “staging” profile 或 “production” profile 任意被激活时包含一些配置,那么可以使用 |
表达式:
<springProfile name="production | staging">
<!-- configuration -->
</springProfile>
上述配置在 “production” profile 或 “production” profile 处于激活状态时启用。
2.4、读取 Environment Properties
有时,我们需要在日志配置中访问 application.properties
中的属性值。在这种情况下,我们使用 Logback 配置中的 springProperty
元素。
SpringProperty
元素与 Logback 标准的 property
元素类似。不过,它具有一个 source
属性,该属性值来自 application properties。如果环境中没有设置该属性,它将从 defaultValue
属性中获取默认值。此外,我们需要为 name
属性设置一个值,以便在配置中的其他元素中引用该属性。
最后,我们可以设置 scope
属性值为 context
。scope 为 context
的属性是 context 的一部分,可以在所有日志事件中使用。
假设我们想使用 application name 作为日志文件名。首先,我们在 application.properties
文件中定义 application name:
spring.application.name=logback-extension
然后,我们在 logback-spring.xml
中公开 application name:
<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>
<!-- configuration -->
</appender>
</springProfile>
在上述配置中,我们将 springProperty
元素的 source
属性设置为 spring.application.name
属性。此外,我们还使用 ${application.name}
来引用该属性。
下一节,我们将讨论 Spring Boot 应用中 Log4j2 的扩展。
3、Log4j2 扩展
Log4j2 扩展与 Logback 扩展类似。我们不能在标准的 log4j2.xml
配置文件中使用扩展,因为它会被 Log4j2 提前加载。
Spring Boot 推荐的方法是将 Log4j2 配置存储在名为 log4j2-spring.xml
的单独文件中。如果存在其他 Log4j2 配置,Spring Boot 将在加载该配置之前加载它。
3.1、Maven 依赖
要使用 Log4j2 库而不是默认的 Logback,我们需要将 Logback 从 starter 依赖中排除:
<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>
此外,我们还需要在 pom.xml 文件中添加 spring-boot-starter-log4j2 和 log4j-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
库,以便在 Log4j2 设置中支持 Spring Boot profile。如果没有这个依赖,我们将看到以下 ERROR 信息:
2023-01-21 15:56:12,473 main ERROR Error processing element SpringProfile ([Loggers: null]): CLASS_NOT_FOUND
3.2、Profile 设置
与 Logback 类似,我们可以使用 SpringProfile
元素来为不同的 Profile 定义配置。
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
Profile 运行应用,你就只能看到 com.baeldung.extensions
包中 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、Environment Properties 查询
Log4j2 Lookup 提供了一种在配置文件中,读取应用配置值的方式。
我们可以使用 Log4j2 的 Lookup 功能从 application.properties
文件中获取值,并在 Log4j2 配置中使用它们。此外,我们还可以使用激活和默认 Profile 的值。为了实现这一点,在 Log4j2 配置中,我们可以使用以 spring
为前缀的 Lookup。
让我们在 application.properties
文件中设置 spring.application.name=log4j2-extension
。然后,我们从 Spring Environment 中读取 spring.application.name
的值:
<Console name="Console-Extensions" target="SYSTEM_OUT">
<PatternLayout
pattern="%d %p %c{1.} [%t] ${spring:spring.application.name} %m%n" />
</Console>
在上述配置中,我们使用 spring
前缀查找设置了 spring.application.name
。运行后,应用将在控制台输出以下日志信息:
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 System Properties
Log4j2 提供了多个 System Properties,可用于配置各个方面。我们可以将这些配置添加到 log4j2.system.properties
文件中。
例如,添加 log4j2.debug=true
属性。此时 log4j2 会将所有内部日志也打印到控制台:
TRACE StatusLogger Log4jLoggerFactory.getContext() found anchor class java.util.logging.Logger
我们也可以在 application.properties
文件中添加这些 System Properties,但是 log4j2.system.properties
文件中定义的属性优先级高于 application.properties
文件。
4、总结
Spring Boot 提供广泛的日志支持。在本教程中,我们学习了如何在 Spring Boot 中使用 Logback 和 Log4j2 的扩展进行高级的日志配置。
参考:https://www.baeldung.com/spring-boot-logback-log4j2