【同步/异步 日志系统】--- 介绍
Welcome to 9ilk's Code World
(๑•́ ₃ •̀๑) 个人主页: 9ilk
(๑•́ ₃ •̀๑) 文章专栏: 项目
本篇博客主要对基于多设计模式下的同步&&异步日志系统这个项目的基本介绍,包括技术栈,日志系统的必要性,以及基本的实现思想。
为什么做这个项目
在进行服务器程序调试的时候涉及到多线程,多进程等, 出现bug难以定位 , 此时就可以借助日志系统打印帮助定位。之前我简单封装的宏日志打印工具只是单纯使用单线程来执行日志语句的输出,简单的输出到控制台上,这样才能执行后面的业务逻辑,这样的效率无疑是低下的,同时日志输出方向比较死板以及格式不易扩展。
#define INF 0
#define DBG 1
#define ERR 2
#define LOG_LEVEL DBG
#define LOG(level,format,...) do{\if(level < LOG_LEVEL) break;\ time_t t = time(NULL);\struct tm* ltm = localtime(&t);\char temp[32] = {0};\strftime(temp,32,"%H:%M:%S",ltm);\fprintf(stdout,"[%s %s:%d] " format "\n",temp,__FILE__,__LINE__,##__VA_ARGS__);\
}while(0)
#define INF_LOG(format,...) LOG(INF,format,##__VA_ARGS__)
#define DBG_LOG(format,...) LOG(DBG,format,##__VA_ARGS__)
#define ERR_LOG(format,...) LOG(ERR,format,##__VA_ARGS__)
在学习和使用了优秀的日志系统,比如spdlog,zlog等日志系统 , 打算做这个高性能的日志系统组件项目, 应用到日志打印工作中,该日志系统亮点是,异步日志的缓冲区主要使用了异步双缓冲区的思想,外界将任务数据添加到输入缓冲区中,异步线程对处理缓冲区中的数据进行处理,若处理缓冲区中没有数据了则交换缓冲区。同时该项目支持创建不同类型的日志器,以及支持不同的日志落地方向,更能让用户自己扩展等。
日志系统实现思想
日志系统的技术主要包括三种类型 :
- 利用
printf
、std::cout
等输出函数将日志信息打印到控制台。 - 对于大型商业化项目,为了方便排查问题,我们一般会将日志输出到文件或者是数据库系统方便查询和分析日志,主要分为同步日志和异步日志方式。
1. 同步写日志(直接写磁盘)
同步日志是指当输出日志时,必须等待日志输出语句执行完毕后,才能执行后面的业务逻辑,日志输出语句与程序的业务逻辑语句将在同一个线程运行,每次调用一次打印日志API
就对应一次系统调用write
写日志文件。
会存在的问题是在高并发场景下,随着日志数量不断增加,同步日志系统容易产生系统瓶颈:
- 一方面,大量的日志打印陷入等量的
write
系统调用,有一定的系统开销。 - 另一方面,使得打印日志的进程附带了大量同步的磁盘IO,影响程序性能。
2. 异步写日志(需要设计缓冲区和异步线程)
异步日志指的是在进行日志输出时,日志输出语句和业务逻辑语句并不在一个线程中运行,而是有专门的线程在进行日志输出。对于业务线程,它只需要将日志放到一个内存缓冲区中,不需要等待即可继续执行后续的业务逻辑,相当于是缓冲区日志的生产者,而日志落地操作交给专门的日志线程去完成,相当于是缓冲区日志的消费者,这其实是一个典型的是生产者-消费者模型。
此时即使日志没有真正的落地也不影响程序的主业务, 大大提高程序的性能:
- 主线程调用日志打印接口成为非阻塞操作。
- 同步的磁盘IO从主线程中剥离出来交给单独的线程完成。
项目日志系统支持功能
- 支持多级别的日志消息(只输出高于某级别的日志)
- 支持同步日志和异步日志(同步:将日志写入到文件、数据库由我自己这个业务线程干;异步:日志放到内容,由其他工作线程进行实际输出)
- 支持可靠写入日志到控制台、文件以及滚动文件中。
- 支持多线程程序并发写到日志。
- 支持扩展不同的日志落地目标地。(日志输出可以落地到标准输出,文件,切换文件,也可以同时进行,还支持扩展,比如写入到数据库,或发送给日志发送服务器)
项目技术栈
开发环境:
- Ubuntu 22.04
- vscode / vim
- g++ / gdb
- MakeFile
关键技术:
- 类层次设计(继承和多态的应用)
- C++11(多线程、auto、智能指针、右值引用等)
- 双缓冲区
- 生产消费模型
- 多线程
- 设计模式(单例、工厂、代理、建造者等)