日志通常需要记录:
收到的每条内部消息的 ID、关键字段、长度、hash 值等。收到的每条外部消息的全文。发送消息的全文,每条消息都有全局唯一的id关键内部状态的变更另外:
每条日志都有时间戳一个日志库大致分为:前端 - 生成日志;后端 - 把日志写到目的地。异步日志线程安全的多线程日志的解决思路
用一个全局锁保护IO,或者每个线程单独写一个日志文件。性能堪忧,前者造成所有线程抢占一个锁,后者会让业务线程阻塞在写磁盘操作上每个进程只写一个日志文件,用一个背景线程负责收集日志消息,并写入日志文件,其他业务线程只需往这个日志线程中发送日志消息,称为“异步日志”我们需要一个“队列”将日志前端的数据传送到后端(日志线程)
muduo日志库采用的是双缓冲技术
基本思路是准备两块 buffer:A 和 B,前端负责往 buffer A 填写数据,后端负责将 buffer B 的数据写入文件。buffer A 写满就交换 A 和 B。如此往复。
日志消息堆积
前端陷入死循环,拼命发送日志消息,超过后端的处理能力
muduo日志处理日志堆积的方法:直接丢到多余的buffer以腾出内存
if (buffersToWrite.size() > 25) { char buf[256]; snprintf(buf, sizeof buf, "Dropped log messages at %s, %zd larger buffers\n", Timestamp::now().toFormattedString().c_str(), buffersToWrite.size()-2); fputs(buf, stderr); output.append(buf, static_cast<int>(strlen(buf))); buffersToWrite.erase(buffersToWrite.begin()+2, buffersToWrite.end()); }