这是我参与「第四届青训营 」笔记创作活动的的第10天
本文主要是介绍实现的需求和重要设计部分,后文会介绍具体实现
服务端日志
关键线程记录:
- 收到的每条内部消息的id(还可包括关键字段、长度、hash等)
- 收到的外部消息的全文(?)
- 发出的每条消息的全文,消息要具有全局唯一的id
- 关键内部状态的变更等
每条日志都是需要有时间戳的,这样才能追踪事件的来龙去脉
1. 功能需求
日志功能多级别,
INFO,TRACE,DEBUG,AWRN,ERROR,FATAL(必须)日志消息有多个目的地等
日志的输出级别在运行时候可调试是有必要的,一个可执行文件可以输出不同级别的日志文件供生产测试的使用
本地文件作为日志的 目的地, 日志文件的滚动是必须的,能够简化日志的 归档实现。比如说 文件大小:文件填满了1G, 那么就换下一个文件。时间: 每天0点创建新的日志。
典型日志文件的名称格式:
进程名(通常是argv[0)的basename,文件创建时间,机器名称,进程ID,统一后缀 .log程序崩溃,最后几个日志丢失?
- 定期将缓冲区内容flush到磁盘
- 日志消息带有
cookie,为函数的地址,通过core dump文件可进行查找日志的消息格式默认是不变的:
日期,时间,微秒,线程,级别,正文,源文件,行号
2.性能需求
- 写很多的日志每没有性能损失
- 不能阻塞正常的执行流程
- 多线程程序中不造成争用
多线程异步日志
多线程程序的每个进程最好是只写一个日志文件:用一个北京线程负责日志消息的收集,并且写入日志文件。其他的业务线程只管往这个 日志线程发送日志消息。
为什么需要异步日志?
多线程程序中如果网络IO线程或者业务线程直接往磁盘写数据,写操作可能会阻塞好几秒。这就可能导致了请求方超时,或者说耽误了发送心跳消息。正常业务处理 尽量避免磁盘IO,线程是复用的,阻塞代表影响多个客户的连接。
木铎采用的是 双缓冲机制, 准备两个bufferA,B。前端往一个buffer中填数据,后端将另一个buffer中的数据写入到文件中,如果前端写的buffer满了就交换两个buffer。这样会将多条日志消息拼成大的buffer传送到后端
\