日志记录注意事项
Java体系日志框架
Logback、Log4j、Log4j2、commons-logging、JDK自带的java.util.logging等;(Logback和Log4j使用最广泛,同一人开发的,其中Logback是Log4j的改进版)
如果程序启动时出现 SLF4J 的错误提示,那很可能是配置出现了问题,可以使用 Maven 的 dependency:tree 命令梳理依赖关系。
SLF4J(Simple Logging Facade For Java)
//日志的统一管理,SLF4J实现了三种功能 1. 提供了统一的日志门面API,实现了中立的日志记录API; 2. 桥接功能,用来把各种日志框架的API桥接到SLF4JAPI。因此,程序中使用了各种日志API记录日志,最终都可以桥接到SLF4J门面API; 3. 适配功能,可以实现SLFJ4JAPI标准实现的,因此不需要绑定模块做转换; //注意:我们可以使用log4j-over-slf4j来实现Log4j桥接到SLF4J,也可以使用slf4j-log4j12实现SLF4J适配到Log4j,但它不能同时使用它们,否则就会产生死循环。jcl和jul也是同样道理。
注意错误配置导致日志重复记录
1. logger 配置继承关系导致日志重复记录
2. 错误配置 LevelFilter 造成日志重复记录。
注意使用异步日志改善性能遇到的问题
//使用 Logback 提供的 AsyncAppender 即可实现异步的日志记录 //AsyncAppende 类似装饰模式,也就是在不改变类原有基本功能的情况下为其增添新功能 //需要注意的问题 1. 记录异步日志撑爆内存; 2. 记录异步日志出现日志丢失; 3. 记录异步日志出现阻塞。 //原因 1. queueSize 设置得特别大,就可能会导致 OOM。 2. queueSize 设置得比较小(默认值就非常小),且 discardingThreshold 设置为大于 0 的值(或者为默认值),队列剩余容量少于 discardingThreshold 的配置就会丢弃 <=INFO 的日志。 -- 一是,因为 discardingThreshold 的存在,设置 queueSize 时容易踩坑。 -- 二是,discardingThreshold 参数容易有歧义,它不是百分比,而是日志条数。 3. neverBlock 默认为 false,意味着总可能会出现阻塞。 //解决:queueSize、discardingThreshold 和 neverBlock按需设置和取舍 1. 如果考虑绝对性能为先,那就设置 neverBlock 为 true,永不阻塞。 2. 如果考虑绝对不丢数据为先,那就设置 discardingThreshold 为 0,即使是 <=INFO 的级别日志也不会丢,但最好把 queueSize 设置大一点,毕竟默认的 queueSize 显然太小,太容易阻塞。 3. 如果希望兼顾两者,可以丢弃不重要的日志,把 queueSize 设置大一点,再设置一个合理的 discardingThreshold。
原文链接:https://time.geekbang.org/column/article/220307