SOUI4新版本的日志系统介绍
原来的日志输出宏用法有点奇怪,感觉总是不够理想。这近有点时间终于把它重整了一下。
以前的用法就不介绍了,重点介绍一下新版本的用法。
在SOUI中使用的日志系统包含两个部分:日志输出宏及日志到文件的打印模块。
日志打印模块主体是抄自一份log4z的代码,然后做了一点简单的修改来适合SOUI的接口。
日志输出宏原来的用法有点奇怪,特别是流式输出日志的样式和传统的C++看起来有点不兼容的样子。
新版本借鉴webrtc里的流式输出日志方法,让日志输出格式更简单。
要在SOUI4中使用日志,可以配置日志打印模块,也可以不配置,配置打印模块,日志可以直接输出到log文件,不配置打印模块,则默认使用OutputDebugString输出到调试窗口。
1 if (pComMgr->CreateLog4z((IObjRef**)&pLogMgr) && pLogMgr) 2 { 3 //uncomment next line to disable log mgr to output debug string. 4 pLogMgr->setLoggerDisplay(LOG4Z_MAIN_LOGGER_ID, false); 5 6 //uncomment next line to record info level log. 7 pLogMgr->setLoggerLevel(LOG4Z_MAIN_LOGGER_ID, LOG_LEVEL_INFO); 8 pLogMgr->start(); 9 } 10 11 //定义一个唯一的SApplication对象,SApplication管理整个应用程序的资源 12 SApplication* theApp = new SApplication2(pRenderFactory, hInstance); 13 14 //将日志模块交给SApp管理 15 theApp->SetLogManager(pLogMgr);
下面重点介绍日志输出宏:
SOUI4提供了一系列的日志输出宏:
//流式输出日志,当kLogTag有效时使用,否则编译失败,kLogTag可以是当前定义的宏,也可以是当前对象的成员变量。 #define SLOGD() SLOG(kLogTag,SOUI::Log::LOG_DEBUG,0) #define SLOGI() SLOG(kLogTag,SOUI::Log::LOG_INFO,0) #define SLOGW() SLOG(kLogTag,SOUI::Log::LOG_WARN,0) #define SLOGE() SLOG(kLogTag,SOUI::Log::LOG_ERROR,0) #define SLOGF() SLOG(kLogTag,SOUI::Log::LOG_FATAL,0) //流式输出日志,每条日志手动指定tag #define SLOGD2(tag) SLOG(tag,SOUI::Log::LOG_DEBUG,0) #define SLOGI2(tag) SLOG(tag,SOUI::Log::LOG_INFO,0) #define SLOGW2(tag) SLOG(tag,SOUI::Log::LOG_WARN,0) #define SLOGE2(tag) SLOG(tag,SOUI::Log::LOG_ERROR,0) #define SLOGF2(tag) SLOG(tag,SOUI::Log::LOG_FATAL,0) //格式化输出日志,当kLogTag有效时使用,否则编译失败,kLogTag可以是当前定义的宏,也可以是当前对象的成员变量。 #define SLOGFMTD(logformat, ...) SLOG_FMT(kLogTag,SOUI::Log::LOG_DEBUG,0,logformat,##__VA_ARGS__) #define SLOGFMTI(logformat, ...) SLOG_FMT(kLogTag,SOUI::Log::LOG_INFO,0,logformat,##__VA_ARGS__) #define SLOGFMTW(logformat, ...) SLOG_FMT(kLogTag,SOUI::Log::LOG_WARN,0,logformat,##__VA_ARGS__) #define SLOGFMTE(logformat, ...) SLOG_FMT(kLogTag,SOUI::Log::LOG_ERROR,0,logformat,##__VA_ARGS__) #define SLOGFMTF(logformat, ...) SLOG_FMT(kLogTag,SOUI::Log::LOG_FATAL,0,logformat,##__VA_ARGS__) //格式化输出日志,每条日志手动指定tag #define SLOGFMTD2(tag,logformat, ...) SLOG_FMT(tag,SOUI::Log::LOG_DEBUG,0,logformat,##__VA_ARGS__) #define SLOGFMTI2(tag,logformat, ...) SLOG_FMT(tag,SOUI::Log::LOG_INFO,0,logformat,##__VA_ARGS__) #define SLOGFMTW2(tag,logformat, ...) SLOG_FMT(tag,SOUI::Log::LOG_WARN,0,logformat,##__VA_ARGS__) #define SLOGFMTE2(tag,logformat, ...) SLOG_FMT(tag,SOUI::Log::LOG_ERROR,0,logformat,##__VA_ARGS__) #define SLOGFMTF2(tag,logformat, ...) SLOG_FMT(tag,SOUI::Log::LOG_FATAL,0,logformat,##__VA_ARGS__) //SOUI4内部使用的日志输出,自动将TAG定义为soui4 #define kSoui4Tag "soui4" #define SSLOGD() SLOG(kSoui4Tag,SOUI::Log::LOG_DEBUG,0) #define SSLOGI() SLOG(kSoui4Tag,SOUI::Log::LOG_INFO,0) #define SSLOGW() SLOG(kSoui4Tag,SOUI::Log::LOG_WARN,0) #define SSLOGE() SLOG(kSoui4Tag,SOUI::Log::LOG_ERROR,0) #define SSLOGF() SLOG(kSoui4Tag,SOUI::Log::LOG_FATAL,0) #define SSLOGFMTD(logformat, ...) SLOG_FMT(kSoui4Tag,SOUI::Log::LOG_DEBUG,0,logformat,##__VA_ARGS__) #define SSLOGFMTI(logformat, ...) SLOG_FMT(kSoui4Tag,SOUI::Log::LOG_INFO,0,logformat,##__VA_ARGS__) #define SSLOGFMTW(logformat, ...) SLOG_FMT(kSoui4Tag,SOUI::Log::LOG_WARN,0,logformat,##__VA_ARGS__) #define SSLOGFMTE(logformat, ...) SLOG_FMT(kSoui4Tag,SOUI::Log::LOG_ERROR,0,logformat,##__VA_ARGS__) #define SSLOGFMTF(logformat, ...) SLOG_FMT(kSoui4Tag,SOUI::Log::LOG_FATAL,0,logformat,##__VA_ARGS__)
SLOGx及SLOGx2提供流式输出日志方法,区别在于SLOGx要求当前代码中有一个kLogTag宏或者可访问变量。
例如在一个模块的cpp文件开始使用#define kLogTag “XXX”,配合SLOGx使用,自动在log中生成tag为XXX的日志。
以demo.cpp为例
#define kLogTag "demo" SLOGFMTE(L"log output using unicode format,str=%s, tick=%u", L"中文", GetTickCount()); SLOGFMTE("log output using ansi format,str=%s, tick=%u", "test", GetTickCount()); SLOGI()<<"test=" << 200;
如果希望使用不同的tag,则可以使用SLOGx2系列宏
1 SLOGI2(“tag1”)<<"test=" << 200; 2 SLOGI2(“tag2”)<<"test=" << 200; 3 SLOGI2(“tag3”)<<"test=" << 200;
除了流式输出日志,另一种常用的日志输出方式是格式化输出,SOUI4提供了SLOGFMTx和SLOGFMTx2两组宏。
SLOGFMTx和SLOGFMTx2都是格式化输出日志,区别和SLOGx与SLOGx2的区别类似。
#define kLogTag "demo" SLOGFMTE2("newtag",L"log output using unicode format,str=%s, tick=%u", L"中文", GetTickCount()); SLOGFMTE("log output using ansi format,str=%s, tick=%u", "test", GetTickCount());
注意,格式化输出宏中会根据format参数,自动选择以宽字符还是Ansi字符串来格式化输出。如果format是宽字符,则后续的%s对应的字符串也必须是宽字符串。
SSLOGx系列宏是SOUI4内部使用的宏,和前面几组宏唯一的区别在于自动将tag固定为"soui4"。
用户也可以参考这组宏的形式固定一个业务代码中使用的tag。
启程软件 2022-09-23