日志功能是一个不可或缺的应用基础功能,客户端、服务端都会日常使用,其中服务端的日志功能相对更加需要,在日常维护工作中,当服务端出现问题时,很多时候需要日志功能来配合寻找出现问题的原因。日志功能虽然非常基础、非常常见几乎各公司都会提供基础类来支持该功能实现,本人也看过一些日志基础类,作为基础构件,我觉得还是有必要说说我自己对日志基础类的一些设计关键点,一来可以为初入门的开发者提供参考思路,二来也可以为需要进行日志类优化的同行们,提供参考。
一、日志类功能
1. 输出日志,作为日志类的核心基本功能当然是不可或缺的。
2. 服务端一般是多线程环境,于是我们希望日志类能尽量的降低日志类在使用时线程间碰撞的机率,提高输出效率,从而提高服务性能。
3. 日志输出一般除了输出到控制台窗口外,还会进行写文件持久化类的解决方案,以备事后查看,写磁盘相对执行其他计算机指令而言是个较为耗时的操作,我们希望该方面日志类能尽量提高性能效率。
4. 根据实际情况需要能较为灵活的控制日志输出量。
二、应对设计
1. 日志输出采用两类,其一,输出至控制台窗口,可以使得维护人员实时从控制台窗口看到输出日志。其二,采用写log日志文件形式,进行持久化操作,可以保存一段时间,以备事后查看。
2. 上述第二,第三,都是侧重于提升日志输出效率,降低消耗,在设计时一并考虑。不论是输出至控制台窗口和写log日志文件,调用次数越频繁,那么线程间的碰撞几率越大,性能消耗也就越大,特别是写文件时,性能消耗更为突出。其实可以采用系统对各外设调用的解决方案,既增加缓存的方式来降低真实输出的次数,从而提升性能效率。如,我们可以增加输出字符缓冲区,每次外部调用输出时,日志类,并不真正调用输出,而是将输出字符缓存至缓存区,等待超时,或者是缓冲区满来真正输出日志。通过一次批量输出来减少真实输出次数达到提升性能效率目的。
3. 灵活控制日志输出量,是本人在某公司看到的日志类,其实现思路是,将输出日志等级化,并设定当前输出等级,在维护需要时动态调整这个当前输出等级来达到日志量输出控制,该方法较为灵活,好处是确实能很好的控制日质量,坏处是日志接口添加了等级参数,在调用时就强制需要提供该参数。
三、其他
1. 为了提升日志类的处理性能效率,在设计时,添加了输出缓存,降低了真实输出次数调用来达到性能优化目的。该解决方案需要比较准确的把握日志真实输出时机,否则可能非但达不到目的反而还导致日志输出异常,得不偿失。个人建议日志类附带独立线程进行专门的日志处理,这么做增强日志类的独立性,写入接口不停地将数据写入缓存,由独立线程来决定何时需要真正地输出日志,形成闭环,大大提高使用独立性。当然需要付出一个线程的代价,个人认为还是值得的。
2. 为了避免日志文件过大,造成传输时间过长,不利于维护的弊端,我们可以设计在写入输出日志时,进行日志文件大小的检测,如果文件过大,那么将日志写入新的日志文件。
3. 同样的,为了避免日志文件过多,造成磁盘空间不够的问题,我们也可以定时进行检测日志文件的过期删除工作。本人在实际维护工作中,也曾遇到由于日志文件过多,造成磁盘空间不足,服务异常的问题。可以和上述单个日志文件大小检测一起合并,在独立线程中进行检测处理
本篇是个人对于日志类设计的一点粗浅观点,仅立足于实现日志功能出发,并未考虑日志收集,和日志上传等其他方面,如果各位读者对于日志的其他方面也有兴趣,本文虽未提及但也欢迎发起讨论。通用平台也同样涉及到日志收集问题,该方面以后可能会有专门的篇章来讲述设计及其实现细节,有感兴趣的读者可以关注本人博客。