系列文章目录
1.项目介绍
2.相关技术补充
3.日志系统框架
4.代码设计
5.功能测试
6.性能测试
文章目录
目录
前言
为什么需要日志系统
- 生产环境的产品喂了保证其稳定性以及安全性是不允许开发人员附加调试器去排查问题,可以借助日志系统来打印一些日志,帮助开发人员解决问题
- 上线客户端的产品出现bug无法复现并解决,可以借助日志系统打印日志并上传到服务器端帮助开发人员进行分析
- 对于一些高频操作(定时器、心跳包),在少量的调试次数下可能无法触发我们想要的行为,通过断点暂停的方式,我们不得不重复操作几十次或更多,导致排查问题效率非常底下,可以借助打印日志的方式查问题
- 在分布式、多线程/多进程代码中,出现bug比较难以定位,可以借助日志系统打印log帮助定位Bug
- 帮助首次接触代码的人员理解代码的运行流程
一、项目介绍
本项目主要实现一个日志系统,其主要支持以下功能:
- 支持多级别日志消息
- 支持同步和异步日志
- 支持可靠写入日志到控制台、文件以及滚动文件中
- 支持多线程程序并发写日志
- 支持扩展不同的日志落地目标地
二、开发环境
- centos7
- vscode/vim
- g++/gdb
- Makefile
三、核心技术
- 类层次设计(继承和多态的应用)
- C++11的特性(多线程、auto、智能指针、右值引用等)
- 双缓冲区
- 生产消费模型
- 多线程
- 设计模式(单例、工厂、代理、模板等)
四、日志系统介绍
日志系统的技术实现
- 利用printf,std::cout等输出函数将日志信息打印到控制台
- 对于大型商业化项目,为了方便排查问题,一般将日志输出到文件或者数据库系统方便查询和分析日志,主要分为同步日志和异步日志
同步日志
同步日志是指输出日志时,必须等待日志输出语句执行完毕后,才能执行后面的业务逻辑语句。日志输出语句与业务逻辑语句在一个线程中运行,每调用一次打印日志API就对应一次系统调用write写日志文件
在高并发场景下,随着日志数量不断增加,同步日志系统容易产生瓶颈:
一方面,大量的日志陷入等量的write系统调用,有一定的系统开销
一方面,使得打印日志的进程附带了大量同步磁盘IO,影响了程序性能
异步日志
异步日志是指在进行日志输出时,日志输出语句与业务逻辑语句不在一个线程中运行,而是有专门的线程用于进行日志输出操作。业务线程只需要将日志放在一个内存缓冲区,不用等待即可执行后续业务逻辑(作为日志的生产者),而日志的落地操作单独交给日志线程去完成(作为日志的消费者),这是一个典型的生产者-消费者模型。
这样的好处是即使日志没有完成输出,也不会影响程序的主业务,可以提高程序的性能:
主线程调用日志打印接口成为非阻塞操作
同步的磁盘IO从主线程中剥离出来交给单独的线程完成。
总结
本节主要介绍了日志系统的概要,详情请见后续文章。