网络日志的实现(1)|青训营笔记

112 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的的第10天

本文主要是介绍实现的需求和重要设计部分,后文会介绍具体实现

服务端日志

关键线程记录:

  • 收到的每条内部消息的id(还可包括关键字段、长度、hash等)
  • 收到的外部消息的全文(?)
  • 发出的每条消息的全文,消息要具有全局唯一的id
  • 关键内部状态的变更等

每条日志都是需要有时间戳的,这样才能追踪事件的来龙去脉

1. 功能需求

  • 日志功能多级别,INFO,TRACE,DEBUG,AWRN,ERROR,FATAL必须

  • 日志消息有多个目的地等

  1. 日志的输出级别在运行时候可调试是有必要的,一个可执行文件可以输出不同级别的日志文件供生产测试的使用

  2. 本地文件作为日志的 目的地, 日志文件的滚动是必须的,能够简化日志的 归档实现。比如说 文件大小:文件填满了1G, 那么就换下一个文件。时间: 每天0点创建新的日志。

  3. 典型日志文件的名称格式:

    进程名(通常是argv[0)的basename, 文件创建时间机器名称进程ID统一后缀 .log

  4. 程序崩溃,最后几个日志丢失?

    • 定期将缓冲区内容flush到磁盘
    • 日志消息带有cookie,为函数的地址,通过core dump文件可进行查找
  5. 日志的消息格式默认是不变的:

    日期,时间,微秒,线程,级别,正文,源文件,行号

2.性能需求

  • 写很多的日志每没有性能损失
  • 不能阻塞正常的执行流程
  • 多线程程序中不造成争用

多线程异步日志

多线程程序的每个进程最好是只写一个日志文件:用一个北京线程负责日志消息的收集,并且写入日志文件。其他的业务线程只管往这个 日志线程发送日志消息。

为什么需要异步日志?

多线程程序中如果网络IO线程或者业务线程直接往磁盘写数据,写操作可能会阻塞好几秒。这就可能导致了请求方超时,或者说耽误了发送心跳消息。正常业务处理 尽量避免磁盘IO,线程是复用的,阻塞代表影响多个客户的连接

木铎采用的是 双缓冲机制, 准备两个bufferA,B。前端往一个buffer中填数据,后端将另一个buffer中的数据写入到文件中,如果前端写的buffer满了就交换两个buffer。这样会将多条日志消息拼成大的buffer传送到后端

\