首页 » java » 正文

【未完待续】后台服务平台建设之日志

作为平台质量管理委员会的一员,在完善CI集成的过程中,参与了平台建设的方方面面的工作,其中的一项就是日志框架等的设计和建设,我之前在微博的时候就总结了一下日志的总类,以及日志对线上服务性能的影响:

Tomcat/Java服务器的日志总结

现在,我们讨论的焦点是:

1. 我们线上应该使用什么级别的日志?info还是debug?

个人认为线上使用info就足够了,但是当前的服务还未稳定,bug还挺多,如果使用info级别,很多服务出了问题将很难定位,另外本人在微博,很多线上服务也是开在debug级别,宁可牺牲一些效率,也要保存线上服务的方方面面信息,用来解决线上的问题。

另外,异常一定要记录error,并且打印异常堆栈,异常在封装后抛出的时候一定要保留根源异常和错误信息,构成异常树,因为在解决线上问题的时候,异常堆栈和异常信息都是非常重要的原因。

最后,切勿吃掉异常,如果无法处理异常,请抛出,但是在框架线程的最上层一定要catch exception/throwable,以免一个非关键异常挂掉线程,使线上服务瘫痪。

2. 我们应该用log4j默认的BlockingQueue来打日志呢?还是异步的Appender?还是使用RingBuffer来提供更高的效率?

在微博实现了异步日志框架,使用的是ConcurrentLinkedList, 业务线程保存日志到ConcurrentLinkedList,异步线程从ConcurrentLinkedList消费,并且推送到远程信息部门,如果远程信息部门系统挂掉,可以暂时存在本地磁盘。这里还有个小插曲,实现者使用了ConcurrentLinkedList的size()方法,这个方法在数据量很大的时候,是动态计算的,会占用大量的CPU时间。

RingBuffer是个更好的无锁队列,关于RingBuffer,请参考我的另外一篇日志:LMAX的Disruptor的RingBuffer学习笔记。如果使用RingBuffer,会得到更高的效率。

3. 如果我们要推送日志到不同的部门或者系统,我们是否应该引入kafka消息队列或者logstash/es等框架?

logstash能将日志格式进行转化,并且入库,通过es搜索引擎进行查找,确实很高大上。

4. 我们继续使用commong logging/log4j还是较新的slf4j/logback呢?

关于slf4j/log4j的优点请参考:浅谈Java日志框架(slf4j, logback, common logging, log4j)