异步日志系统01——日志系统框架
异步日志系统
- 日志系统框架
- 日志系统模块
- 日志系统调用过程
日志系统框架
日志系统包含:日志记录器Logger、日志格式化器Formatter、日志输出器Flush、日志级别Level
日志系统模块
日志系统主要模块有:异步日志器管理模块、日志等级模块、日志格式化模块、异步日志器模块、异步缓冲区模块、异步工作者模块、日志输出模块
-
异步日志器管理模块
Manager作为异步日志器的管理者,使用懒汉单例模式对日志器进行管理,通过GetInstance确保提供全局唯一的日志管理器实例。用户生成一个新的日志器,并将新日志器的名字加入管理器中,后续日志管理器通过日志器的名字获取该日志器(GetLogger方法);
通过管理器使用方法为:
mylog::GetLogger("asynclogger")->Info("NewStorageInfo end");
- 日志等级模块
Level规定了日志系统的日志等级,包括:FATAL、ERROR、WARN、INFO、DEBUG
调用日志器对应日志等级的函数方法,例如:
mylog::GetLogger("asynclogger")->Info("NewStorageInfo end");
其中,Info表示该行日志的等级为“INFO”。
-
日志格式化模块
Formatter将日志器的日志信息转化为统一的特定格式,会对当前日志加入时间戳、日志等级、日志信息来源等信息,并返回组织好的日志信息。 -
异步日志器模块
AsyncLogger实现了不同日志信息的组织管理,该模块包含日志器类、日志器建造者类
日志器建造者类使用了建造者模式,便于后续扩展;通过该建造者类构造一个日志器,并加入到日志管理器中;
//使用日志器建造者建造一个名为asynclogger的日志器
std::shared_ptr<mylog::LoggerBuilder> Glb(new mylog::LoggerBuilder());
Glb->BuildLoggerName("asynclogger");
Glb->BuildLoggerFlush<mylog::RollFileFlush>("./logfile/RollFile_log",1024 * 1024);
//将日志器添加到日志器管理者中,管理者是全局单例类
mylog::LoggerManager::GetInstance().AddLogger(Glb->Build());
日志器类通过日志管理者进行调用,例如:
mylog::GetLogger("asynclogger")->Info("NewStorageInfo end");
日志器类将要写入的日志信息、日志等级、时间戳、文件名、文件行、日志器名称等信息序列化解析并格式化后写入异步缓冲区进行永久化处理。
- 异步缓冲区模块
AsyncBuffer采用双缓冲区设计,分为生产者缓冲区和消费者缓冲区;
日志器处理的格式化日志内容写入生产者缓冲区,当生产者缓冲区有数据写入后,在合适的时机交换生产者缓冲区和消费者缓冲区(实际上交换了两个缓冲区的指针,并非将数据进行拷贝)
- 异步工作者模块
AsyncWorker作为一个异步线程,在日志器建造完成后开始检测生产者缓冲区是否有数据,无数据则阻塞,有数据则在合适的时机交换生产者缓冲区和消费者缓冲区,异步工作线程又称为消费者线程;
- 日志输出模块
Flush用于将消费者缓冲区的日志信息输出到对应位置(终端,文件)
日志系统调用过程
- 实例化日志器建造者并通过该建造者实例化一个日志器,将该日志器加入全局单例日志管理者中;
- 通过固定格式的宏
mylog::GetLogger("asynclogger")->Info("NewStorageInfo start");
调用日志器,先对日志信息进行格式化; - 日志器将格式化后的日志由日志器(生产者线程)写入生产者缓冲区(push),异步工作者模块(工作线程或消费者线程)在合适的时机进行生产者缓冲区和消费者缓冲区的交换并将此时的消费者缓冲区的数据通过Flush写入对应的位置。