log4z icon indicating copy to clipboard operation
log4z copied to clipboard

当日志队列满了之后再输出的日志会被丢弃

Open slandx opened this issue 8 years ago • 7 comments

测试场景: 3个线程,每个线程输出10000条数据,使用LOGFMTD输出。并且关闭console输出,只写文件。 测试环境: win10 64bit, i5, 8G 测试结果: 原本应该在日志文件里有30000条记录,结果只有2万多条(每次结果不一样)。 原因分析: 定位了一下,发现是prePushLog函数里会判断_logs队列的大小,如果超过LOG4Z_LOG_QUEUE_LIMIT_SIZE就会返回false,这条日志就被丢弃了。 解决方案: 把LOG4Z_LOG_QUEUE_LIMIT_SIZE这个值设置大一点,就能输出全部30000条。不过,到底设置多大才算够大,在实际使用过程中不好确定,只能是尽量设置的大一点,保证日志不丢失吧。

slandx avatar Jan 13 '17 03:01 slandx

你不怕爆内存 就设置2亿. 队列性能是百万级别/每秒的, 线程竞争虽然会掉一定的性能, 但是 核心瓶颈和问题还是 写硬盘速度跟不上塞进来的. 这个得从硬件和需求上找解决方案, log4z能做的是 如果写速度跟不上 爆内存还是爆日志 选一个.

zsummer avatar Jan 13 '17 03:01 zsummer

另外 正常项目日志输出每秒行数峰值很少超过千行级别的, 1万的队列实际上可处理的日志每秒是10万以上级别的, 我这边测试是20万. 而实际业务中超过每秒1万的情况一般只有一个 死循环.. 这种情况下除了第一次的日志是有意义的 后面拥堵到日志队列的都是垃圾数据. 如果爆内存 很可能所有日志丢失. 所以 极端情况下丢日志的做法是相对好的选择.

zsummer avatar Jan 13 '17 03:01 zsummer

@zsummer 多谢回复,的确如你所说,在我实际使用中,正常逻辑下log4z没出现丢日志的情况。我也是在测试各个日志库的性能的时候发现的这个现象。循环里只输log,什么都不干,属于极端情况。其它日志库比如glog虽然不会丢,但会把执行时间拉长。

slandx avatar Jan 13 '17 08:01 slandx

拉长执行时间倒也是一个不错的方法 我可以考虑再加个宏定义来切换丢日志或者短暂sleep

zsummer avatar Jan 13 '17 08:01 zsummer

目前的解决方案采用了拉长写入间隔的方式替换掉了原先丢弃日志的方式. 效果很好.

zsummer avatar Aug 26 '17 06:08 zsummer

@zsummer 效果非常好!!对比了一下,3线程,每线程10万行日志,比glog快了一个数量级。

slandx avatar Aug 29 '17 07:08 slandx

目前单线程比多线程还快. 单线程我这里测试简单字符串能稳定跑220万/second . 复杂类型也有80万. linux下折半 简单字符串100万 复杂类型log 48万. 本来打算测试下glog和log4cpp做下对比的 一下子忙起来了. .. 没顾上

zsummer avatar Aug 29 '17 08:08 zsummer