SpringBoot对日志的配置和加载进行了封装,让我们可以很方便地使用一些日志框架,只需要定义对应日志框架的配置文件,比如LogBack、Log4j、Log4j2等,代码内部便可以直接使用。
比如我们在resources目录下定义了一个logback.xml文件,文件内容是logback相关的配置,然后就可以直接在代码在使用Logger记录日志啦。
# LoggingSystem内部结构
从图中也可以发现目前SpringBoot支持4种类型的日志,分别是JDK内置的Log(JavaLoggingSystem)、Log4j(Log4JLoggingSystem)、Log4j2(Log4J2LoggingSystem)以及Logback(LogbackLoggingSystem)。
LoggingSystem是个抽象类,内部有这几个方法:
beforeInitialize方法:日志系统初始化之前需要处理的事情。抽象方法,不同的日志架构进行不同的处理
initialize方法:初始化日志系统。默认不进行任何处理,需子类进行初始化工作
cleanUp方法:日志系统的清除工作。默认不进行任何处理,需子类进行清除工作
getShutdownHandler方法:返回一个Runnable用于当jvm退出的时候处理日志系统关闭后需要进行的操作,默认返回null,也就是什么都不做
setLogLevel方法:抽象方法,用于设置对应logger的级别
AbstractLoggingSystem抽象类继承LoggingSystem抽象类,进行了一些扩展,重点在于initialize方法:
实现了beforeInitialize方法,但是内部不做任何处理
复写了initialize方法,具体过程如下
# LoggingSystem的初始化
LoggingApplicationListener是ApplicationListener接口的实现类,会被springboot使用工厂加载机制加载:
spring-boot-starter模块内部会引用spring-boot-starter-logging模块,这个starter-logging模块内部会引入logback相关的依赖。这一依赖会导致LoggingSystem的静态方法get获取LoggingSystem的时候会得到LogbackLoggingSystem。
因此默认情况下,springboot程序基本都是使用logback作为默认的日志。
# 一些例子
前提都是以LogbackLoggingSystem作为日志系统。
# 项目里没有任何日志的配置
由于没有任何配置,进行initialize的时候日志配置文件为null,最后只能调用loadDefaults方法进行加载,LogbackLoggingSystem的loadDefaults方法,由于logFile为null,所以最终只构造了一个ConsoleAppender。
所以项目没有任何日志配置的情况下,控制台依旧能打印出项目的启动信息。
# 项目里没有任何logback的配置,只有yaml中配置了logging.file和logging.path
logging.file和logging.path的配置在LogFile这个日志文件类中生效。
比如yaml配置如下(只定义了logging.file):
logging: file: /tmp/temp.log
这个配置导致了调用initialize方法的时候logFile存在,这样不止有ConsoleAppender,还有一个FileAppender,这个FileAppender对应的文件就是LogFile文件,也就是 /tmp/temp.log日志文件。
比如yaml配置如下(只定义了logging.path):
这个时候FileAppender对应的file是/tmp/spring.log文件。
所以我们如果配置了logging.path和logging.file,那么生效的只有logging.file配置。
# resources下有logback.xml配置(相当于就是classpath下存在logback.xml文件)
之前分析过,LogbackLoggingSystem中的getStandardConfigLocations方法返回以下文件:
logback-test.groovy或者logback-test-spring.groovy
logback-test.xml或者logback-test-spring.xml
logback.groovy或者logback-spring.groovy
logback.xml或者logback-spring.xml
在resources目录下定义logback-spring.xml文件,内容如下:
这时logging.file配置失效,这是因为没有调用loadDefaults方法(loadDefaults方法内部会把LogFile构造成FileAppender),而是调用了loadConfiguration方法,该方法会根据logback.xml文件中的配置去构造Appender。
# resources下有my-logback.xml配置
由于LogbackLoggingSystem中没有对my-logback.xml路径的解析,所有不会被识别,但是可以在yaml中配置logging.config配置:
这样配置就能识别my-logback.xml文件。
# 其它
最新版的SpringBoot内部提供了一个NoOpLoggingSystem,这个日志系统内部什么都不做,构造过程如下:
所以程序启动的时候加上 -Dorg.springframework.boot.logging.LoggingSystem=none就可以构造NoOpLoggingSystem这个日志系统。
来源:http://fangjian0423.github.io/2017/08/23/springboot-logging-system
往期推荐
?
- 携程开源的配置管理中心Apollo,为什么这门屌?
- 我把SpringBoot项目从18.18M瘦身到0.18M,部署起来真省事!
- 面经分享:网友问我,怎样才能在谷歌匹兹堡办公室里写代码?
点击