学习Java时间也不短了,最近忽然发现(顿悟)我好想没怎么学习使用过“日志”这个东西啊。。。之前学校的教学中简单的使用了log4j,但是配置文件也是老师给的,自己也没有细究其内容,就浑浑噩噩的过去了。现在想想确实不该,这不是一个好的现象。既然发现缺漏,那就花点时间将其慢慢弥补。
正文
SpringBoot基于Spring,Spring使用Apache的JCL(Jkarta Commons Logging)作为Spring框架内部的日志框架,其仅仅是一个日志接口,在实际应用中需要为该接口来指定相应的日志实现。SpringBoot默认的日志实现是JUL(Java Util Logging),是JDK自带的日志包。
此外SpringBoot外部当然也支持SLF4j(Simple Logging Facade for java)日志接口、Log4j日志实现、Logback日志实现这类很流行的日志框架。而且spring-boot-starter-logging采用了SLF4j+logback的形式,SpringBoot也能自动适配很多其他流行日志框架并简化配置。
统一将上面这些日志实现统称为日志框架。
Java应用中,日志一般分为以下5个级别:
- ERROR错误信息
- WARN警告信息
- INFO一般信息
- DEBUG调试信息
- TRACE跟踪信息
SLF4j
SLF4j是一个存取日志的标准接口,一张图展示SLF4j对多种日志框架极好的兼容性:
使用的时候,日志记录方法的调用,不应该直接调用日志的实现类,而是调用日志抽象层里的方法。
每一个日志的实现框架都有自己的配置文件。使用SLF4j以后,配置文件依然是日志实现框架自己本身的配置文件。
一个思考
现在有一个a项目使用SLF4j+logback日志框架,但是a项目依赖了Spring、Hibernate、Mybatis等等框架,这些依赖的框架内部使用的不是SLF4j+logback日志框架:
a系统(SLF4j+logback):Spring(commons-logging)、Hibernate(jboss-logging)。。。
能否统一日志记录,使a系统及其依赖项目框架都使用SLF4j进行输出?
在SLF4j官方文档中已经给出了解决方案,这个方案就是:Replace!
这个解决方案大概以下三步:
- 将系统中其他的日志框架先排除出去,但是被排除日志框架的项目很可能会在运行时报错!
- 为了避免第一步的问题,SLF4j提供了一系列的中间包用来替换原有的日志框架。
- 最后导入我们需要的SLF4j实现即可。
总结
SpringBoot应用都依赖于spring-boot-starter,spring-boot-starter又依赖spring-boot-autoconfigure(自动配置)、snakeyaml(yaml文件解析)、spring-boot-starter-logging,其中spring-boot-starter-logging依赖关系如下:
- SpringBoot底层使用SLF4j+logback进行日志记录。
- SpringBoot也把其他的日志都替换成了SLF4j。一系列的替换包项目,内部的包名和被替换的包保持一致,但是内部都是调用的SLF4j的方法实现的。
- 如果我们要引入其他的框架,一定要把这个框架的默认日志依赖exclusion掉,移除之后SpringBoot就可以自动适配。事实上SpringBoot本身也是这么干的。
配置和使用
在运行SpringBoot应用时,我们没有进行日志配置,但是依然有日志输出,说明SpringBoot有默认设置:
1 | //通过记录工厂获取记录器 |
从输出结果可以看出,SpringBoot默认配置的日志级别是:info,如果希望所有级别的日志,需要在配置文件中加入:
1 | #logging.level.被设置的包路径=级别 |
如果希望不仅仅是在控制台输出日志,而是希望可以以文件的形式保存日志信息,可以进行如下配置:
1 | #logging.file=springboot.log 不指定路径,springboot.log文件就会保存在项目下 |
但是上述配置方式在springboot2.0之后有所变化:
1 | #logging.file改为logging.file.name=E:/springboot.log |
上述方法两条配置如果一起使用,只有logging.file.name起效。(老版本配置一样)还可以配置日志的格式:
1 | #日志输出格式: |
上述配置都是在application.properties中进行的,只能进行部分配置。如果想要进行更加详细完备的日志配置,需要添加xml日志配置文件。在springboot包中的logging包中有对logback进行默认配置的xml文件,如果想要定义自己的日志配置文件,直接在类路径下创建每个日志框架自己的配置文件即可,SpringBoot就不使用默认配置了。自定义日志配置文件的文件名必须使用官方文档中说的这些:
并且SpringBoot官方建议使用带有spring的文件名,如果使用logback.xml,配置文件就会被日志框架直接识别(相当于绕过了SpringBoot)。
反之,如果使用logback-spring.xml,日志框架就不直接加载日志的配置项,而是由SpringBoot来解析日志配置,而且可以使用SpringBoot的springProfile功能:
1 | <!--可以指定某段配置,只在某个环境下生效(该功能只能SpringBoot解析时才能生效,如果直接日志框架识别则会报错)--> |
日志框架的切换
以SLF4j替换为LOG4j为例,先看官方文档:
看明白了这个,切换这件事就变得简单了,简单粗暴直接排除原先的spring-boot-starter-logging依赖,引入spring-boot-starter-log4j2依赖:
1 | <dependency> |
SpringBoot会自动适配log4j,并且也有其对应的默认配置。如果需要log4j的自定义配置文件,按照前文logback自定义配置文件的方式创建对应的xml文件即可。
关于每个日志框架的配置文件中还有哪些可配置项,后续学习中再去日志框架对应的官方文档或者大佬的博文中了解。