1、概览 {#1概览}
日志是系统中的一个重要组件。Spring Boot 支持 Logback 和 Log4j2 日志框架,并且提供了一些扩展,可用于高级配置。
在本教程中,我将带你学习如何在 Spring Boot 中使用 Logback 和 Log4j2 的扩展进行高级的日志配置。
2、Logback 扩展 {#2logback-扩展}
Spring Boot 默认使用 Logback 进行日志记录。在本节中,我们将了解 Logback 的一些扩展,以进行高级配置。
注意 :Spring Boot 建议使用 logback-spring.xml
作为 Logback 的配置文件名称,而不是默认的 logback.xml
。因为 logback.xml
配置文件会被 Logback 默认加载,它会比 Spring 更早地加载进系统,所以我们不能在标准的 logback.xml
中使用扩展,
2.1、Maven 依赖 {#21maven-依赖}
要使用 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、基本日志 {#22基本日志}
首先,在 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 设置 {#23profile-设置}
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 {#24读取-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 扩展 {#3log4j2-扩展}
Log4j2 扩展与 Logback 扩展类似。我们不能在标准的 log4j2.xml
配置文件中使用扩展,因为它会被 Log4j2 提前加载。
Spring Boot 推荐的方法是将 Log4j2 配置存储在名为 log4j2-spring.xml
的单独文件中。如果存在其他 Log4j2 配置,Spring Boot 将在加载该配置之前加载它。
3.1、Maven 依赖 {#31maven-依赖}
要使用 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 设置 {#32profile-设置}
与 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 查询 {#33environment-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 {#34log4j2-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、总结 {#4总结}
Spring Boot 提供广泛的日志支持。在本教程中,我们学习了如何在 Spring Boot 中使用 Logback 和 Log4j2 的扩展进行高级的日志配置。
参考:https://www.baeldung.com/spring-boot-logback-log4j2