服务器编程中,日志系统需要满足几个条件
.高效,日志系统不应占用太多资源
.简洁,为了一个简单的日志功能引入大量第三方代码未必值得
.线程安全,服务器中各个线程都能同时写出日志
.轮替,服务器不出故障是不重启的,半年一年的日志放到一个文件会导致文件过大
.及时保存,程序故障导致异常退出,此时需要通过日志诊断问题,不缓冲的日志系统更易用
著名的日志库有log4xxx系列,提供了非常灵活的功能,当然随之而来的代价就是庞大的库。在大多数服务器应用中,所需的功能不多,我偏向于选择一个支持按时间轮替的简洁的日志库。
为了同时做到线程安全和支持轮替,大多数日志系统都使用锁。写出日志时,首先获取锁,如果需要轮替,则进行轮替操作,否则写到现有文件,最后释放锁。
google开源的leveldb的日志系统中,同时做到了“线程安全”和轮替,但是没有用锁,这引发了我的兴趣。
仔细阅读发现它的运作原理是
.每个log操作,都会生成相关的字符串,最终调用write,写出到日志系统的文件描述符fd。
.进行rotate操作时,重新命名旧文件,保持旧文件的打开状态,然后打开新文件,将fd设置为新文件。
.接下来sleep 200ms,然后把close旧文件
那么轮替过程中,fd的值为fd_old或者fd_new,只要fd的读写是原子的,不会读取到非fd_old和fd_new的其他值即可(fd是int,这点可以做到)。write操作就没有问题
如果由于系统繁忙,