日志系统对应用程序的重要性不言而喻。Spring Boot 为应用程序的日志记录提供了强大的支持,并提供了各种自定义选项。在本教程中,你将学习如何在 Spring Boot 应用程序中使用 Logback 和 Log4j2 实现日志记录
当你创建一个添加了任何 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/