理清四个容易搞混的日志框架Commons Logging、Log4j、SLF4J、Logback。
其实如上分成两类,像Commons Logging、SLF4J是门面日志框架,并不是日志解决方案,它们可以通过配置文件挂载不同的日志系统(Log4j、Logback),它是服务这些日志系统的。
Log4j 目前已经停止更新,Apache 推荐升级版 Log4j2
现在基本不用Commons Logging,都是用它的改进版SLF4J,全称简单日志门面(Simple Logging Facade for Java)。
像这些门面日志框架的作用就是方便切换,比如项目以前用SLF4J挂载Log4j(也就是依赖Log4j)记录日志,现在要切换成Logback,只需要将 Log4j 替换成 Logback 就行,不用修改项目中的代码。
阿里巴巴规范手册也就提过这事
【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架 SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理 方式统一。
再来看使用方法,第一步当然依赖SLF4J,第二选择日志系统Log4j、Logback,任选一个就行,然后依赖相关。
这些都比较简单,而且 Springboot 已经对SLF4J做了支持,所以我们不用管依赖,只需确定使用哪个日志系统,以及日志系统配置文件的编写。
SLF4J如何挂载日志系统的配置文件呢?
日志系统配置文件包含日志输出的格式、路径、控制台输出格式、文件大小、保存时长..
要么指定配置文件的路径,要么按名字默认加载。
指定路径,一般日志系统配置文件要么放在 resources 下,要么根目录,像如下配置
logging:
config: classpath:log4j2.xml #resoureces
config: logback.xml #根目录
但其实不配置也行,只要日志系统命名符合SLF4J要求,它也能自动加载。
只要这些配置文件在 resources 目录下,SLF4J接受以下命名:
- logback-spring.xml、logback.xml
- log4j-spring.xml、log4j.xml
- log4j2-spring.xml、log4j2.xml
其他格式的日志配置文件也一样,像.properties、.groovy,关键在于命名。Springboot 官方推荐用 logback-spring.xml。
所以,指定路径的方式在于可以随便命名,如果没这需求,推荐后者。
再来看日志配置文件,其实这才是重点,Log4j和Logback两配置文件参数差不多,就上面提到的输出的格式、路径、控制台输出格式、文件大小、保存时长…这里我拿Logback举例。
首先是日志输出格式,分成两种,控制台输出格式和日志文件输出格式,其实这两种可以用一种风格。但控制台我们可以设置更多个性化日志,比如给日志加颜色。但日志文件中就必须要朴素点,因为它没法识别颜色之类属性,硬加上会乱码。
所以,如果想简单化,直接全部用一种朴素输出格式就行,也可以分成两种,因为有些个性化设置确实方便定位问题。
<!--控制台输出格式-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%yellow(%date{HH:mm:ss.SSS}) [%highlight(%thread)] %-5level %c.%M\(%F:%L\) %n%msg%n</pattern>
</encoder>
</appender>
每一项解释很累,直接运行看效果就懂了,无非是时间、线程名、日志级别、定位、日志内容,还加了点颜色。
接着日志文件输出格式
<!--定义日志文件的存储路径,要绝对路径-->
<property name="logdir" value="/Users/guozh/logs/test"/>
<!--日志文件输出-->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>
${logdir}/%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<!-- 保存天数 -->
<maxHistory>30</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- 日志文件的最大大小 -->
<maxFileSize>130MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
<pattern>%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} %n%msg%n</pattern>
</Pattern>
</layout>
</appender>
最后再引入
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE" />
</root>
后面代码中类上使用注解@Slf4j,就能在类中使用日志。
log.info("说点啥");
还有个事,日志文件的储存路径可以是变量,之前分享过多环境配置日志文件路径,logback.xml 中读取 application.yml 属性值。
本文由老郭种树原创,转载请注明:https://guozh.net/the-difference-between-commons-logging-log4jslf4j-logback/