在 Spring Boot 中使用 Logback 和 Log4j2 记录日志
日志系统对应用程序的重要性不言而喻。Spring Boot 为应用程序的日志记录提供了强大的支持,并提供了各种自定义选项。在本教程中,你将学习如何在 Spring Boot 应用程序中使用 Logback 和 Log4j2 实现日志记录
Spring Boot 中默认的的日志支持
当你创建一个添加了任何 starter 的 Spring Boot 应用程序时,它们都依赖于 spring-boot-starter
,而 spring-boot-starter
又依赖于 spring-boot-starter-logging
,这就为日志记录添加了 logback 依赖。
Spring Boot 默认日志配置已在 spring-boot-starter
中通过 CONSOLE
appender 进行了配置。你可以在 org/springframework/boot/logging/logback
包下查看打包在 spring-boot.jar
中的默认配置文件(defaults.xml
、base.xml
、console-appender.xml
、file-appender.xml
)。
因此,默认情况下,Spring Boot 配置了 Slf4j 和 Logback 来记录日志,你可以在应用程序中按如下方式记录日志:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Service
class CustomerService {
private static final Logger log = LoggerFactory.getLogger(CustomerService.class);
public Customer findById(Long id) {
log.info("Fetching customer by id: {}", id);
...
}
}
这将在你的 CONSOLE
中产生一个 INFO
级别的日志,类似于下面的内容:
2023-07-26T19:44:04.492+05:30 INFO 69881 --- [nio-8080-exec-1] c.s.demo.CustomerService : Fetching customer by id: : 1
自定义日志级别
默认情况下,Spring Boot 的 root
日志级别设置为 INFO
。你可以在 src/main/resources/application.properties
中为 root
或任何指定的包配置日志级别,如下所示:
logging.level.root=WARN
logging.level.com.sivalabs=DEBUG
logging.level.org.springframework=INFO
logging.level.org.hibernate.validator=DEBUG
使用 File Appender
Spring Boot 已经配置了 RollingFileAppender
,但默认是禁用的。只需在 application.properties
中配置 logging.file.name
或 logging.file.path
属性,即可启用 File Appender,具体如下:
# 相对于当前目录
logging.file.name=product-service.log
# 绝对路径
logging.file.name=/var/log/product-service.log
# 把日志写入到 /var/log/product-service/spring.log 文件
logging.file.path=/var/log/product-service
请注意,当你配置 logging.file.name
或 logging.file.path
属性时,将同时启用 Console
和 File
Appender。如果你想禁用 Console appender 并仅启用 File appender,或者你想对 logback 配置进行更多控制,你可以创建 src/main/resources/logback.xml
文件,并根据你的需求进行日志配置。
自定义 Logback 配置
如果通过 logging.*
属性进行的 Spring Boot 日志配置不能满足需求,那可以创建自己的 src/main/resources/logback.xml
文件,Spring Boot 将根据此配置来配置日志。
不过,Spring Boot 提供了一些 logback 扩展,可帮助你使用高级配置选项。为了使用这些扩展,需要创建名为 logback-spring.xml
而非 logback.xml
的配置文件。
logback-spring.xml
文件示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<root level="INFO">
<appender-ref ref="FILE" />
</root>
<logger name="org.springframework" level="WARN"/>
<logger name="com.sivalabs" level="DEBUG"/>
</configuration>
如果你想在配置中读取 Spring Boot properties 或根据 Spring profile 定义日志配置,Spring Boot Logback 扩展就会派上用场。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<springProperty scope="context"
name="logstashHost"
source="logstash.host"
defaultValue="localhost"/>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<springProfile name="docker">
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<property name="LOG_FILE" value="/var/logs/myapp.log"/>
<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>${logstashHost}</destination>
...
...
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
<appender-ref ref="logstash" />
</root>
</springProfile>
<springProfile name="!docker">
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</springProfile>
<logger name="com.sivalabs" level="DEBUG"/>
<logger name="org.springframework" level="INFO"/>
</configuration>
在上述配置中,我们根据 Spring profile 启用 appender。如果启用了 docker
profile,则使用 FILE
和 Logstash
appender。反之,则仅使用 CONSOLE
appender。此外,请注意我们通过定义 <springProperty .../>
来获取到 logstash.host
属性值,来指定 Logstash
主机。
使用 Log4j2 代替 Logback
如果你更喜欢使用 Log4j2 而不是 Logback,可以从 spring-boot-starter
中排除 spring-boot-starter-logging
,并在 pom.xml
中添加 spring-boot-starter-log4j2
依赖,如下所示。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<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>
</dependency>
如果使用的是 Gradle,可以按如下方式配置使用 log4j2 而不是 logback:
configurations.all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
dependencies {
implementation('org.springframework.boot:spring-boot-starter-log4j2')
...
...
}
Spring Boot 默认在 org/springframework/boot/logging/log4j2/log4j2.xml
中包含 log4j2.xml
配置文件。但如果你想提供自定义配置,则可以创建 src/main/resources/log4j2-spring.xml
文件,如下:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="LOG_PATTERN">
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %c{1}:%L - %m%n
</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.sivalabs" level="debug" additivity="false">
<AppenderRef ref="Console" />
</Logger>
<Root level="info">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
如果使用 slf4j API 创建 logger 对象,则无需修改任何代码。slf4j API 会将实际日志记录委托给 log4j2。
总结
Spring Boot 通过提供默认的配置(可自定义),使实现日志记录变得简单。在本教程中,我们学习了如何在 Spring Boot 中使用 Slf4J 和 Logback 记录日志,以及自定义日志配置。然后,我们探讨了如何使用 Log4j2 替代默认的 Logback 实现。
参考:https://www.sivalabs.in/spring-boot-logging-tutorial/