使用日志facade slf4j
在代码中不直接使用具体日志LIB库API,例如log4j,logback等,使用日志facade 库slf4j。使用facade的好处是,与日志实现解耦,可以方便切换日志实现。
log4j日志性能
log4j rootLogger对象锁由于比较粗的控制粒度,导致高并发日志输出频繁的时候,性能下降很厉害。log4j2在性能上有了很大的提升。推荐使用log4j2 的异步appender。
日志级别
log4j2 日志级别有OFF,FATAL,ERROR,WARN,INFO,DEBUG,ALL。建议只使用 DEBUG、INFO、WARN、ERROR这四个级别,这些日志级别也是slf4j使用的级别。
典型的级别有:
- DEBUG——最详细,但是只有在开发或者调试时适用
- INFO——最常用的级别
- WARN——发生不在预期之内的一些状态,但是可接受
- ERROR——有错误发生
在不同环境会采用不同的日志级别。一般,相比较第三方库里输出的日志,我们更关注自己应用程序的日志记录。
- 开发/测试环境:应用 DEBUG 第三方库 WARN
- 生产环境:应用 INFO 第三方库 WARN
log4j2配置monitorInterval,在运行时修改配置,可以直接生效日志配置。在生产环境,偶尔在需要的时候,会开启debug级别,获取更多的日志信息来分析问题。
使用slf4j parameterized logging
当日志语句禁用的情况下, 使用parameterized logging 参数化日志, 可以提升性能。
例如:
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
不管debug级别日志是否启用,日志文本都会进行类型转化和文本拼接的操作。
通常我们可以通过增加判断,来避免不必要的文本拼接操作。
if(logger.isDebugEnabled()) {
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}
使用这种方法,不论是否debug 开启,增加 了 检查 日志是否启用的判断一次是 isDebugEnabled 一次是debug方法里面。
slf4j提供了 parameterized logging机制,只有要必要的情况下,才会对日志本本进行组装。
logger.debug("Entry number: {} is {}", i, entry[i]);
记录,切记过多过少
日志信息,可以帮助定位问题,也可以利用日志信息,分析用户行为,用于统计信息。
日志过多,会占用太大的磁盘空间,难以维护。
比起日志过少,日志过多倒并不是什么大问题。一般,日志都是会手机到日志服务器去做集中式存储,便于后期分析和统计需要。
日志过少时,因为缺少信息,分析bug和故障的时候就捉襟见肘了。
尽量在日志中,包含足够的信息。例如 操作的数据、业务数据等信息,便于快速的诊断问题。
记录性能信息
记录执行时间可以用来帮助定位性能问题。一般只需要记录那些可能比较耗时的地方:
- 慢服务调用
- 慢servie层方法
- 慢执行SQL语句