前言
本篇文章主要涉及以下知识点:
- 常用的日志框架(日志门面以及日志实现)
- slf4j+log4j2的使用
- log4j2的傻瓜通用配置
一些问题的修改与更新
将日志自动保存到不同的日志文件(19-10-03更新)
· 自己在做项目的时候遇到了一个问题:重新运行项目,如何把日志保存到不同的log文件?
· 我之前写的那个模板有一个重大的问题:每次运行程序,只要日志文件没超过maxSize,log都只会记录到这个文件。但是调试的时候,这种操作令人十分不爽,因此,在查询了官网之后,给模板进行了修改。
修改如下:
· 因为在普通的字符串里无法使用pattern的语法,因此使用fileName="$${date:MM-dd-HH-ss}"
作为保存的日志名称,这样每次运行程序,日志必然会保存在不同的文件下。
· 实际上,我们完全可以构造两个FileAppender,这样就可以根据我们的需要来使用不同的日志文件记录方式了:本文的模板已更新,不喜可删。
什么是slf4j和log4j2
· 目前开源的日志框架有很多,如logback,log4j等,这面临了一个问题:当使用不同的日志框架或者这些日志框架面临了重大更新的时候,如果其实现函数有所改变,那么旧版本的框架就会崩溃,这很不利于项目的维护和新框架的推广。因此才诞生了例如slf4j这样的日志门面。
· 日志门面,顾名思义就是日志框架对外的表现形式,理论上只要日志框架实现了日志门面的接口,不管其怎么更新,开发者都不需要对项目的依赖,或者项目的代码做出过多的改变。目前还在坚持更新且性能良好的日志门面非slf4j莫属,因此强烈建议使用slf4j作为我们书写日志的接口。
· 日志框架方面,logback是log4j的升级版,这两个框架与slf4j是一个开发者开发出来的,因此其整合十分之稳定。但是log4j2作为apache最新推出的日志框架,在异步记录日志的方面性能比logback要更加的优异,因此本着要用就用最好的的原则 ,使用lo4gj2作为日志记录的框架。
注:log4j2只是假借了log4j之名而已,log4j的真正升级版是logback。
依赖
· 日志的环境依赖总共有4部分,分别是slf4j接口部分,log4j2的日志框架实现部分,log4j2异步日志插件部分以及slf4j与log4j2的桥接部分。
包名 | 作用 |
---|---|
slf4j-api | 目前的版本1.7就可。slf4j的接口包,我们对日志进行的所有操作都用的是这个包的API |
log4j-core | 版本必须在2.1以上,是log4j2的核心包 |
log4j-api | 版本与核心包一致,log4j2的接口包,用来直接调用log4j2框架的,必须导入,不然无法与slf4j对接 |
log4j-web | 版本与核心包一致,用于web项目的log4j2,阻止web项目出现警告 |
com.lmax.disruptor | 版本随意,开启log4j2的异步日志记录的功能 |
log4j-slf4j-impl | 版本与核心包一致,用于slf4j与log4j对接,即用slf4j的接口实现操作日志 |
这里给出一份Maven完整依赖:
1 | <properties> |
配置
· 看多很多的博客,都没有官网的配置全面,因此给出官网传送门:log4j2官网详细配置说明
· 本博客给出一种粘贴复制即可用的配置,并给出一些个人认为比较重要的说明。
配置文件
· 基本上所有的配置都写在了Properties里,因此,只需要改Properties就可以用了(建议自定义Logger,不建议修改Appenders)。
Apperders里定义了两种日志记录的格式:1. 在控制台输出name=“Console”,2. 在文件输出name=“File”。使用RollingRandomAccessFileAppender是因为其性能最好,且支持日志自动归档。
1 |
|
配置的简单说明:
RollingRandomAccessFile标签
RollingRandomAccessFile的三个属性的含义:
- name:这个Appender的引用名
- fileName:日志文件的路径及名称(文件夹或文件不存在就自动创建)
- filePattern:日志归档后的文件的保存路径和名称(如果加了.zip就自动压缩)
RollingRandomAccessFile必须配置的两个字标签:
- TriggerPolicy:文件翻转触发机制。翻转的意思就是旧文件保存(归档),另起新文件进行记录。
- 在上述配置文件中,其触发机制是SizeBasedTriggeringPolicy,即:当文件大小超过一定阈值后,进行自动保存
- RolloverStrategy:文件翻转策略。
- 在上述配置文件中,其策略是默认策略,当归档的文件数量达到一定数值后,就自动删除旧文件(如果不配置,则默认为7)
- TriggerPolicy:文件翻转触发机制。翻转的意思就是旧文件保存(归档),另起新文件进行记录。
- 测试代码如下:
1 | import org.slf4j.Logger; |
- 测试结果如下
设置了保存的文件最大为1KB,最大保存文件数量为10,保存500条日志。每篇日志能保存9条语句。
- untitled.log输出如下:
1 | 2019-08-28 19:16:52,248 ERROR AsyncLogger [main] Log4j2Test.testLog(Log4j2Test.java:11) 491 |
· 可见,如果不设置翻转的机制,要么会在一个日志文件内记录所有的数据,要么仅会保存7条归档的日志。一般情况下,希望能把所有的归档日志文件都保存下来,因此RolloverStragety的值要设置的大一点。
Logger的配置
· Logger分为同步和异步,只有一个RootLogger。异步的实现就是我们之前引入的那个com.lmax.disruptor包,当我们启用异步日志记录的时候,就会新建一个Disruptor对象,具体的日志记录流程建议参考这位大佬的文章:Log4j2中的同步日志与异步日志。
Logger中属性的含义:
- name:在代码getLogger的名字,root没有此属性。
- level:日志的打印级别为”OFF>FATAL>ERROR>WARN>INFO>DEBUG>TRACE“。logger在记录日志的时候,只会记录level界别及以上的日志内容(OFF永远不会打印)。如设置了ERROR,只会打印FATAL和ERROR。
- includeLoacation:日志打印的时候是否会输出位置(打印位置会降低性能)。
- additivity:root没有,配置此属性值为true来避免重复打印(如果为false,root会重复打印一次相同级别的日志),至于为什么会重复打印,还是建议大家看一下官方文档,这里不赘述了。
Logger的子标签
1.< AppenderRef ref=”xxx” > 表示这个logger将用到何种Appender,ref内写Appender的name属性值。
PatternLayout解释
· 本配置文件默认的layoutPattern为:%date %p %c{1.} [%thread] %location %message %exception%n
· 官网有特别特别详细的说明文档,我这个都是对着官网写出来的,特别好理解,强烈建议大家对看文档。传送门:log4j2的LayoutPattern;本博客就只介绍一下上面的这行配置。
格式 | 说明 |
---|---|
%date | 输出日期和时间:yyyy-MM-dd HH:mm:ss,SSS(年-月-日 时:分:秒,毫秒) |
%p | 输出日志的打印级别 |
%c{1.} | 输出该日志所处的缩略类路径 |
%[thread] | 打印执行该日志记录的线程名 |
%location | 打印日志语句在项目代码中的位置 |
%message | 日志内容 |
%exception | 如果出现了异常,则打印异常 |
%n | 类似于/n,是换行符 |
总结
· 日志记录一直是一个很尴尬的点,感觉不难,但一直理解不是很深刻,其实我们最常用的就是把日志输出到控制台或者输出到文件,私以为只要把这两个方面搞明白了就行。以后做项目,尽量就用slf4j+log4j2来记录日志啦。
交流
请联系邮箱:chenxingyu@bupt.edu.cn