深入理解Spring Boot日志系统架构

本文基于Spring Boot 2.0版本,全面解析其日志系统的设计原理与实践应用。

Spring Boot日志体系概览

Spring Boot框架内部采用commons-logging作为日志记录接口,但允许开发者灵活替换底层实现。框架默认为三种主流日志框架提供开箱即用的支持:Java
Util Logging、Log4J2以及Logback。

以下是与日志相关的核心配置参数说明:

# 日志配置文件路径,例如使用Logback时可指定:classpath:logback.xml
logging.config=
# 异常信息转换格式
logging.exception-conversion-word=%wEx
# 日志文件名称(可指定绝对路径或相对路径)
logging.file=
# 归档日志文件的最大保留数量(仅默认Logback配置生效)
logging.file.max-history=0
# 单个日志文件的最大容量(仅默认Logback配置生效)
logging.file.max-size=10MB
# 包路径日志级别映射,例如:logging.level.org.springframework=DEBUG
logging.level.*=
# 日志文件存储目录
logging.path=
# 控制台输出格式(仅默认Logback配置生效)
logging.pattern.console=
# 日志时间戳格式(仅默认Logback配置生效)
logging.pattern.dateformat=yyyy-MM-dd HH:mm:ss.SSS
# 文件输出格式(仅默认Logback配置生效)
logging.pattern.file=
# 日志级别显示格式(仅默认Logback配置生效)
logging.pattern.level=%5p
# 是否注册日志系统关闭钩子
logging.register-shutdown-hook=false

若未进行任何配置,应用默认仅将INFO及以上级别的日志输出至控制台,不会生成日志文件。

当项目中引入任何Starter依赖时,Spring Boot会自动选用Logback作为默认日志实现,并内置了对多种日志门面的桥接支持,包括Java
Util Logging、Commons Logging、Log4J以及SLF4J。这意味着无论开发者使用哪种日志门面API,Logback都能无缝承接。

如下图所示,从spring-boot-starter-web的依赖关系中可见Logback及其桥接器的完整组成:

日志配置实践演示

application.properties配置文件中添加以下设置:

# 设置全局日志级别为DEBUG
logging.level.root=DEBUG
# 指定日志文件输出路径
logging.file=d:/logs/javastack.log
# 针对特定框架调整日志级别
logging.level.org.springframework=INFO
logging.level.sun=WARN

在应用启动类中添加多日志门面测试代码:

// 使用Commons Logging
private static final org.apache.commons.logging.Log logger1 =
        org.apache.commons.logging.LogFactory.getLog(SpringBootBestPracticeApplication.class);

// 使用SLF4J
private static final org.slf4j.Logger logger2 =
        org.slf4j.LoggerFactory.getLogger(SpringBootBestPracticeApplication.class);

// 使用Java Util Logging
private static final java.util.logging.Logger logger3 =
        java.util.logging.Logger.getLogger("SpringBootBestPracticeApplication");

@Bean
public CommandLineRunner loggerLineRunner() {
    return (args) -> {
        logger1.error("Commons Logging - 错误级别消息");
        logger1.info("Commons Logging - 信息级别消息");
        logger2.info("SLF4J - 信息级别消息");
        logger3.info("Java Util Logging - 信息级别消息");
        logger1.debug("Commons Logging - 调试级别消息");
    };
}

执行后控制台输出结果:

2018-05-24 17:16:21.645 ERROR 3132 --- [main] c.j.s.SpringBootBestPracticeApplication : Commons Logging - 错误级别消息
2018-05-24 17:16:21.645 INFO 3132 --- [main] c.j.s.SpringBootBestPracticeApplication : Commons Logging - 信息级别消息
2018-05-24 17:16:21.645 INFO 3132 --- [main] c.j.s.SpringBootBestPracticeApplication : SLF4J - 信息级别消息
2018-05-24 17:16:21.645 INFO 3132 --- [main] c.j.s.SpringBootBestPracticeApplication : Java Util Logging - 信息级别消息
2018-05-24 17:16:21.645 DEBUG 3132 --- [main] c.j.s.SpringBootBestPracticeApplication : Commons Logging - 调试级别消息

测试表明,三种不同的日志门面API均能与Logback完美协作,日志内容也正确写入指定文件。

高级日志配置策略

Spring Boot提供的简单配置方式适用于基础场景,但对于按日期滚动归档、自定义归档策略等复杂需求,则需要通过外部日志配置文件实现。框架能自动检测类路径下的特定配置文件并初始化对应的日志系统。

各日志框架对应的配置文件命名规则如下:

日志框架 支持的配置文件
Logback logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
Log4j2 log4j2-spring.xml, log4j2.xml
JDK (Java Util Logging) logging.properties

开发者只需在classpath下创建对应格式的配置文件,或通过logging.config属性指定配置文件路径即可。

由于Logback是默认实现,推荐在资源目录下创建logback-spring.xml文件进行自定义配置。使用-spring后缀的命名方式(如
logback-spring.xml)是Spring Boot推荐的做法,确保框架能完全控制日志初始化过程,并能读取application.properties中的配置参数。

通过以上介绍,相信你对Spring Boot的日志机制有了全面认识。具体配置文件的编写方式与传统项目一致,此处不再赘述。