日志库
类似于log4net,log4j这样的日志库功能早已经十分强大,所以类似如果format,如果输出到一个指定的device之类的问题,早就不需要广大程序员思索。所以本章讨论不会涉及这些内容。
多进程服务器日志
多进程的情况下,如果日志是采用写文件的方式,一般推荐每个进程单独写一个文件(即使log模块可以解决文件句柄竞争问题,也会存在性能损耗)。另一种方式,就是干脆不写文件,直接通过类似于syslog,把日志提交给一个专业的收集者去处理。单独写文件的最大好处是,进程可以长时间hold住文件写句柄,而不需要每次去执行文件打开操作。经过测试,这一步骤消耗的时间是大大长于实际文件写的过程的。
写入终端比较
上文已经提到,一般可以写两种终端(syslog或文件)
syslog的好处是,可以同步调用(相当于发送了一个局域网socket包),无竞争(上文提到的),日志合并(多个进程的日志可以输出到一个地方,方便查看),高效(服务器进程可以日志比较简单,syslog可以完成format等抵效工作)
写文件的好处,架设简单(KISS,无任何依赖和配置,容易被理解),可以按需分类文件夹和文件名,利于管理(比如我们可以把消费的日志,升级的日志都专门分出来,查看起来很方便),格式化过程可编程(不同的进程可以更方便的定制,肯定比syslog配置方便的多)
如果是一个效率至上的服务器(大型mmo,日志量巨大),推荐用syslog类似的异步收集方式。而对于像我们这种比较休闲的手游,日志效率平摊下来几乎没有影响。所以,虽然写文件只有一个易于分档的好处,我们还是选择了这种方式。
二次封装
虽然是以log4net作为底层支持,但一般我们还是会进行以此二次封装。
异步开关
我们需要封装一个异步开关,打开异步开关后,日志就不会阻塞主线程(比如写文件,放主线程写是很危险的)。实现方式很简单,就是委托一个线程在后台慢慢写呗。
日志合并/统计
部分重复日志(循环报错等),一直输出,会导致cpu无谓的消耗,所以我们需要杜绝这样的错误,通过隔离层来封装这些也是十分合适的做法。
适配
有时候,可能有几种日志库需要协同工作。比如我们的部分日志需要通过Thrift走,那么二次封装可以把这些细节通过适配的方式隐藏起来。