Linux 多线程服务端编程读书笔记 (五)

Linux 多线程服务端编程笔记(五)

第五章 高效的多线程日志

1、 两种日志
  1. 交易日志
  2. 诊断日志
2、 关键进程记录的日志

日志通常需要记录:

  1. 收到的每条内部消息的 ID、关键字段、长度、hash 值等。
  2. 收到的每条外部消息的全文。
  3. 发送消息的全文,每条消息都有全局唯一的id
  4. 关键内部状态的变更

另外:

  1. 每条日志都有时间戳
  2. 一个日志库大致分为:前端 - 生成日志;后端 - 把日志写到目的地。异步日志
3、日志库应该提供的功能
  1. 日志消息级别:TRACE、DEBUG、INFO、WARN、ERROR、FAEAL
  2. 日志消息可能有多个目的地,如文件,socket,SMTP。对于分布式系统服务进程而言,目的地只有本地文件
  3. 日志消息可以配置
  4. 可以设置运行时过哭泣
4、 日志消息的几个要点
  1. 尽量每条 日志占一行,方便分析
  2. 时间戳精确到微妙,gettimieofday()
  3. 使用GMT时区
  4. 打印线程id
  5. 打印日记级别
  6. 打印原文件名和行号
5、多线程异步日志
  1. 线程安全的多线程日志的解决思路

    • 用一个全局锁保护IO,或者每个线程单独写一个日志文件。性能堪忧,前者造成所有线程抢占一个锁,后者会让业务线程阻塞在写磁盘操作上
    • 每个进程只写一个日志文件,用一个背景线程负责收集日志消息,并写入日志文件,其他业务线程只需往这个日志线程中发送日志消息,称为“异步日志”
  2. 我们需要一个“队列”将日志前端的数据传送到后端(日志线程)

  3. muduo日志库采用的是双缓冲技术

    基本思路是准备两块 buffer:A 和 B,前端负责往 buffer A 填写数据,后端负责将 buffer B 的数据写入文件。buffer A 写满就交换 A 和 B。如此往复。

  4. 日志消息堆积

    • 前端陷入死循环,拼命发送日志消息,超过后端的处理能力

    • 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());
          }
      
5、日志的其他方案
  1. 使用队列前后端中传递消息,每一个消息都是一个std::string,这种消息都要分配内存,并由后端线程释放
  2. muduo现在的异步日志实现用了一个全局锁。尽馆临界区很少,但是如果线程数目较多,锁的争用也可能影响性能
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值