Logger 和 NoticeCenter 是 ZLToolKit 的两个关键工具组件:一个解决"看得见"(日志),一个解决"解得了耦"(消息广播)。本文深入分析两者的实现,揭示 C++ 观察者模式的优雅实践。1. Logger 日志系统1.1 架构总览LogContextCapture (流式日志 运算符) → LogContext (上下文:文件/行/级别/时间) → Logger (单例分发器) → LogChannel (通道基类) ├─ ConsoleChannel (控制台输出) ├─ FileChannel (文件输出) └─ SysLogChannel (syslog 输出) → LogWriter (写入器) ├─ AsyncLogWriter (异步写入) └─ SyncLogWriter (同步写入)1.2 日志级别typedefenum{LTrace=0,LDebug,LInfo,LWarn,LError}LogLevel;1.3 流式日志宏// 用法DebugL"connect to "ip":"port;InfoL"stream started";WarnL"timeout, retrying";ErrorL"socket error: "strerror(errno);宏定义:#defineDebugLLogContextCapture(Logger::Instance(),\LogContext(LDebug,__FILE__,__FUNCTION__,__LINE__))#defineInfoLLogContextCapture(Logger::Instance(),\LogContext(LInfo,__FILE__,__FUNCTION__,__LINE__))#defineWarnLLogContextCapture(Logger::Instance(),\LogContext(LWarn,__FILE__,__FUNCTION__,__LINE__))#defineErrorLLogContextCapture(Logger::Instance(),\LogContext(LError,__FILE__,__FUNCTION__,__LINE__))#defineTraceLLogContextCapture(Logger::Instance(),\LogContext(LTrace,__FILE__,__FUNCTION__,__LINE__))1.4 LogContextCapture — 流式捕获classLogContextCapture{public:LogContextCapture(Loggerlogger,LogContextctx):_logger(logger),_ctx(std::move(ctx)){}~LogContextCapture(){// 析构时将累积的内容写入日志_ctx._content=_oss.str();_logger.add(_ctx);}// 运算符重载templatetypenameTLogContextCaptureoperator(constTdata){_ossdata;return*this;}private:Logger_logger;LogContext _ctx;stringstream _oss;};精妙之处:利用临时对象的析构时机——DebugL "xxx"产生临时LogContextCapture,语句结束时析构自动 flush。1.5 LogContext — 日志上下文structLogContext{LogLevel _level;string _file;string _function;int_line;string _content;uint64_t_time;LogContext(LogLevel level,constchar*file,constchar*function,intline):_level(level),_file(file),_function(function),_line(line
ZLToolKit 源码分析(九):Logger 日志系统与 NoticeCenter 消息广播
Logger 和 NoticeCenter 是 ZLToolKit 的两个关键工具组件:一个解决"看得见"(日志),一个解决"解得了耦"(消息广播)。本文深入分析两者的实现,揭示 C++ 观察者模式的优雅实践。1. Logger 日志系统1.1 架构总览LogContextCapture (流式日志 运算符) → LogContext (上下文:文件/行/级别/时间) → Logger (单例分发器) → LogChannel (通道基类) ├─ ConsoleChannel (控制台输出) ├─ FileChannel (文件输出) └─ SysLogChannel (syslog 输出) → LogWriter (写入器) ├─ AsyncLogWriter (异步写入) └─ SyncLogWriter (同步写入)1.2 日志级别typedefenum{LTrace=0,LDebug,LInfo,LWarn,LError}LogLevel;1.3 流式日志宏// 用法DebugL"connect to "ip":"port;InfoL"stream started";WarnL"timeout, retrying";ErrorL"socket error: "strerror(errno);宏定义:#defineDebugLLogContextCapture(Logger::Instance(),\LogContext(LDebug,__FILE__,__FUNCTION__,__LINE__))#defineInfoLLogContextCapture(Logger::Instance(),\LogContext(LInfo,__FILE__,__FUNCTION__,__LINE__))#defineWarnLLogContextCapture(Logger::Instance(),\LogContext(LWarn,__FILE__,__FUNCTION__,__LINE__))#defineErrorLLogContextCapture(Logger::Instance(),\LogContext(LError,__FILE__,__FUNCTION__,__LINE__))#defineTraceLLogContextCapture(Logger::Instance(),\LogContext(LTrace,__FILE__,__FUNCTION__,__LINE__))1.4 LogContextCapture — 流式捕获classLogContextCapture{public:LogContextCapture(Loggerlogger,LogContextctx):_logger(logger),_ctx(std::move(ctx)){}~LogContextCapture(){// 析构时将累积的内容写入日志_ctx._content=_oss.str();_logger.add(_ctx);}// 运算符重载templatetypenameTLogContextCaptureoperator(constTdata){_ossdata;return*this;}private:Logger_logger;LogContext _ctx;stringstream _oss;};精妙之处:利用临时对象的析构时机——DebugL "xxx"产生临时LogContextCapture,语句结束时析构自动 flush。1.5 LogContext — 日志上下文structLogContext{LogLevel _level;string _file;string _function;int_line;string _content;uint64_t_time;LogContext(LogLevel level,constchar*file,constchar*function,intline):_level(level),_file(file),_function(function),_line(line