前言
之前做的 仿网易云音乐播放器,部分网友说我写的 qDebug 有些抽象,看不懂。
那么我这次就来搞个轮子项目 - - 日志系统。
其目的,一是解决我在以后项目中的日志规范问题,
二是练习在实际项目中使用设计模式。
说实话,在之前我根本没系统学过设计模式,
导致那个 播放器项目 设计不够精巧,分层不太清晰。
而在之前写项目时,
我对我要实现的东西只有一个模糊的概念,
在代码量来到 1000+ 时,
类和类的关系就已经让我非常头疼了,
光是理清那坨意大利面条就花了我不少时间。
因此,根据我偶然获得的 启发,
我决定在以后每次写项目前先把整个项目彻底理清,
把目标定死,把模块定出来、结构图画出来。
最后完成项目文档(注,不是为了文档而文档,
而是为了让我在代码量大起来前把思路固化下来)
项目目标
一句话清晰项目目标:
实现一个基于多种设计模式的 C++ 同步与异步多日志器系统,
支持多级别日志、线程安全、多落地目标(控制台、文件、滚动文件)
以及支持扩展落地目标。
项目模块
日志等级模块
- 等级类 LogLevel
- 枚举等级
- 枚举 -> 字符串
- 等级类 LogLevel
日志消息模块
- 消息类 LogMessage
- 存储信息(时间、等级、文件路径、行号、线程ID、消息、日志器名称)
- 消息类 LogMessage
格式化模块
- 格式化类 Formatter
- 存储格式化字串
- 解析字串后得到格式化子项数组(解析+创建)
- 消息到格式化后的消息
- 格式化子项基类 FormatItem
virtual void format(std::ostream&, const LogMessage&) = 0;
- 派生类:
- 日期 DateFormatItem (使用 localtime_r, strftime)
- 消息 MessageFormatItem
- 线程 ThreadFormatItem
- 文件、行号、日志器名 等等
- 格式化类 Formatter
日志输出模块
基类 Sink
- log
- virtual ~Sink() = default;
标准输出 StdoutSink
指定文件 FileSink
大小滚动 SizeRollSink
时间滚动 TimeRollSink
工厂 SinkFactory
模板函数:区分类型、用Args传参
日志器模块
基类 Logger
- 提供不同等级的日志输出接口
- 持有 formatter 和 sinks
- 通过 log 调用不同 sink 进行日志输出
- 成员:
std::mutex _mutex; std::string _logger_name; std::atomic<LogLevel::Level> _limit_level; Formatter::ptr _formatter; std::vector<Sink::ptr> _sinks;
同步 SyncLogger
log 开始时记得加锁:
std::unique_lock<std::mutex> lock(_mutex);
异步 AsyncLogger
- 创建一个异步工作线程
- 写数据时写入缓冲区
日志器建造者模块
- 基类 Builder
- 通过建造者去建造日志器,而不是用户直接构造
- 局部 LocalLoggerBuilder
- 使用结束后失效
- 全局 GlobalLoggerBuilder
- 添加到全局单例管理类中,日志器永久有效
- 基类 Builder
异步任务处理模块
- 缓冲区类 Buffer
- 异步处理类 AsyncLooper
- 负责日志的异步处理
- 成员:
- 双缓冲区
- 停止标识 std::atomic _stop
- 互斥锁
- 两个条件变量
日志器管理模块
- 日志器管理类 LoggerManager
- 可以由用户添加日志器,并在任意位置使用
- 全局日志器管理:按名称保存日志器对象
- 提供全局默认日志器
- 单例模式实现
- 日志器管理类 LoggerManager
结构图
项目文档
一、项目简介
本项目实现了一个基于 多种设计模式 的 C++ 日志系统,支持同步与异步多日志器,提供多级别日志、线程安全机制,并支持多种日志落地方式(控制台、文件、滚动文件),同时可扩展自定义落地目标。
二、主要特性
- 同步/异步模式:支持阻塞式同步日志和高性能异步日志。
- 线程安全:使用锁 + 双缓冲区确保并发安全。
- 多级别日志:支持 Debug、Info、Warn、Error、Fatal 等。
- 多日志器支持:可同时创建多个 Logger,按名称区分。
- 多落地目标:控制台、文件、文件大小滚动、时间滚动。
- 可扩展性:用户可自定义日志 Sink。
- 单例管理器:统一管理日志器,支持全局获取和默认 Logger。
三、模块设计
基本同上文
四、结构图
同上文
五、使用示例
暂无
六、设计模式应用总结
- 工厂模式:SinkFactory 生产不同的 sink,使得用户自定义sink后使用更加方便
- 建造者模式:LoggerBuilder 构建日志器
- 单例模式:LoggerManager 全局管理器
- 外观模式:提供更简洁的外观接口(debug,info等
希望本篇文章对你有所帮助!并激发你进一步探索编程的兴趣!
本人仅是个C语言初学者,如果你有任何疑问或建议,欢迎随时留言讨论!让我们一起学习,共同进步!