1. 项目介绍
本项⽬主要实现⼀个⽇志系统, 其主要⽀持以下功能:
• ⽀持多级别⽇志消息
• ⽀持同步⽇志和异步⽇志
• ⽀持可靠写⼊⽇志到控制台、⽂件以及滚动⽂件中
• ⽀持多线程程序并发写⽇志
• ⽀持扩展不同的⽇志落地⽬标地
2. 开发环境
• CentOS 7
• vscode/vim
• g++/gdb
• Makefile
3. 核⼼技术
• 类层次设计(继承和多态的应⽤)
• C++11(多线程、auto、智能指针、右值引⽤等)
• 双缓冲区
• ⽣产消费模型
• 多线程
• 设计模式(单例、⼯⼚、代理、模板等)
4. 环境搭建
本项⽬不依赖其他任何第三⽅库, 只需要安装好CentOS/Ubuntu + vscode/vim环境即可开发。
5. ⽇志系统介绍
5.1 为什么需要⽇志系统
• ⽣产环境的产品为了保证其稳定性及安全性是不允许开发⼈员附加调试器去排查问题, 可以借助⽇志系统来打印⼀些⽇志帮助开发⼈员解决问题
• 上线客⼾端的产品出现bug⽆法复现并解决, 可以借助⽇志系统打印⽇志并上传到服务端帮助开发⼈员进⾏分析
• 对于⼀些⾼频操作(如定时器、⼼跳包)在少量调试次数下可能⽆法触发我们想要的⾏为,通过断点的暂停⽅式,我们不得不重复操作⼏⼗次、上百次甚⾄更多,导致排查问题效率是⾮常低下,可以借助打印⽇志的⽅式查问题
• 在分布式、多线程/多进程代码中, 出现bug⽐较难以定位, 可以借助⽇志系统打印log帮助定位bug
• 帮助⾸次接触项⽬代码的新开发⼈员理解代码的运⾏流程
5.2 ⽇志系统技术实现
⽇志系统的技术实现主要包括三种类型:
• 利⽤printf、std::cout等输出函数将⽇志信息打印到控制台
• 对于⼤型商业化项⽬, 为了⽅便排查问题,我们⼀般会将⽇志输出到⽂件或者是数据库系统⽅便查询和分析⽇志, 主要分为同步⽇志和异步⽇志⽅式
◦ 同步写⽇志
◦ 异步写⽇志
5.2.1 同步写⽇志
同步⽇志是指当输出⽇志时,必须等待⽇志输出语句执⾏完毕后,才能执⾏后⾯的业务逻辑语句,⽇志输出语句与程序的业务逻辑语句将在同⼀个线程运⾏。每次调⽤⼀次打印⽇志API就对应⼀次系统调⽤write写⽇志⽂件。
在⾼并发场景下,随着⽇志数量不断增加,同步⽇志系统容易产⽣系统瓶颈:
• ⼀⽅⾯,⼤量的⽇志打印陷⼊等量的write系统调⽤,有⼀定系统开销.
• 另⼀⽅⾯,使得打印⽇志的进程附带了⼤量同步的磁盘IO,影响程序性能
5.2.2 异步写⽇志
异步⽇志是指在进⾏⽇志输出时,⽇志输出语句与业务逻辑语句并不是在同⼀个线程中运⾏,⽽是有
专⻔的线程⽤于进⾏⽇志输出操作。业务线程只需要将⽇志放到⼀个内存缓冲区中不⽤等待即可继续执⾏后续业务逻辑(作为⽇志的⽣产者),⽽⽇志的落地操作交给单独的⽇志线程去完成(作为⽇志的消费者), 这是⼀个典型的⽣产-消费模型。
这样做的好处是即使⽇志没有真的地完成输出也不会影响程序的主业务,可以提⾼程序的性能:
• 主线程调⽤⽇志打印接⼝成为⾮阻塞操作
• 同步的磁盘IO从主线程中剥离出来交给单独的线程完成