使用C++实现日志(2)
1.3 日志系统的分析
日志系统大体分为前端(frontend) 和后端(backend) 两部分:
- 前端:供应用程序使用的接口(API),负责生成日志消息(log message);
- 后端:负责将日志消息写入目的地(destination)。
前后端通过回调函数接口连接,示例如下:
void output(const char* message, int len);
// 或
void output(const std::string &message);
其中message
为完整日志消息,包含级别、时间戳、源文件位置、线程 ID 等字段及具体内容。
1. 识别问题空间中的对象
- 时间戳对象;
- 日志流对象;
- 日志对象;
- 文件写对象;
- 日志文件对象。
2. 确定对象中的方法
(1)时间戳对象中的方法
now()
:获得当前时间(时刻);toString()
、toFromattedString
:获取可打印字符串。
(2)日志流对象中的方法
- 构造日志流;
- 添加正文信息;
- 获得完整的日志字段信息字符串。
(3)日志对象中的方法
- 设置日志等级;
- 设置打印回调函数(默认打印到终端);
- 设置刷新回调函数;
- 获得日志流对象;
- 一个日志对象对应一条完整日志信息,析构函数负责将日志写入终端或文件。
(4)文件写对象中的方法
- 封装 OS 提供的文件操作:创建 / 打开文件、写文件、关闭文件等。
(5)日志文件对象中的方法
- 构建日志文件名称;
- 构建新的回滚文件;
- 将日志信息写入文件缓冲区;
- 刷新函数:将文件缓冲区数据写入文件。
3. 确定对象中的属性(数据结构)
(1)时间戳对象中的属性
- 使用
std::int64_t
存储微秒。
(2)日志流对象中的属性
- 日志信息级别;
- 标题字段;
- 正文信息。
(3)日志对象中的属性
- 包含日志流对象;
- 日志级别;
- 回调函数的定义。
(4)文件写对象中的属性
FILE *fp_
:文件指针;- 文件缓冲区;
- 累计写文件的字节个数。
(5)日志文件对象中的属性
- 写文件对象;
- 写互斥器;
- 日志文件名;
- 回滚大小;
- 写文件的间隔时间;
- 写文件的次数。
1.4 时序图
写入终端时序图:
写入文件时序图: