获取
- 通过一个COM接口的方式获取到一个管理器对象
1 2 3 4 5 |
SOUI_COM_C BOOL SOUI_COM_API SOUI::LOG4Z::SCreateInstance(IObjRef **ppLogMgr) { *ppLogMgr = new LogerManager; return TRUE; } |
ThreadHelper
- 是一个抽象类,接口run是抽象的
start
- 作为抽象基类,实现了start
- 主要功能是创建了一个线程(是跨平台的实现),
1 2 3 4 5 6 7 8 9 10 11 |
// windows #if defined (WIN32) || defined(_WIN64) unsigned long long ret = _beginthreadex(NULL, 0, threadProc, (void *) this, 0, NULL); if (ret == -1 || ret == 0) { std::cout << "log4z: create log4z thread error! \r\n" <<std::endl; return false; } _hThreadID = ret; #endif |
1 2 3 4 5 6 7 8 |
// 非Windows实现 int ret = pthread_create(&_phtreadID, NULL, threadProc, (void*)this); if (ret != 0) { std::cout <<"log4z: create log4z thread error! \r\n" << std::endl; return false; } |
- 然后创建了一个Helper,调用了run
1 2 3 4 5 6 |
unsigned int WINAPI threadProc(LPVOID lpParam) { ThreadHelper * p = (ThreadHelper *) lpParam; p->run(); return 0; } |
- run里面开始往列表里放数据
wait
- 等待run里面创建的线程内核对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
bool ThreadHelper::wait() { #if defined (WIN32) || defined(_WIN64) if (WaitForSingleObject((HANDLE)_hThreadID, INFINITE) != WAIT_OBJECT_0) { return false; } #else if (pthread_join(_phtreadID, NULL) != 0) { return false; } #endif return true; } |
TObjRefImpl
- 是一个COM接口类
ILog4zManager
- 继承自IObjRef,是一个抽象类
TObjRefImpl<ILog4zManager>
- 是ILog4zManager的一个偏特化
LogerManager
- 继承了ThreadHelper
- 继承了TObjRefImpl的偏特化
TObjRefImpl<ILog4zManager>
使用
- 创建具象化对象
- 调用start
1 2 3 4 5 6 7 8 9 |
if(pComMgr->CreateLog4z((IObjRef**)&pLogMgr) && pLogMgr) { //uncomment next line to disable log mgr to output debug string. //pLogMgr->setLoggerDisplay(LOG4Z_MAIN_LOGGER_ID,false); //uncomment next line to record info level log. //pLogMgr->setLoggerLevel(LOG4Z_MAIN_LOGGER_ID,ILog4zManager::LOG_LEVEL_INFO); pLogMgr->start(); } |
- 结束的时候调用stop
1 2 3 4 |
if(pLogMgr) { pLogMgr->stop(); } |
- 其他地方使用
1 2 3 4 |
ILog4zManager * SApplication::GetLogManager() { return m_logManager; } |
1 |
#define GETLOGMGR() SOUI::SApplication::getSingletonPtr()?SOUI::SApplication::getSingleton().GetLogManager():NULL |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
//! base micro. #define SOUI_LOG_STREAM(id_or_name, filter, level, log)\ do{\ SOUI::ILog4zManager * pLogMgr = GETLOGMGR(); \ char *logBuf= (char*)malloc(SOUI::LOG4Z_LOG_BUF_SIZE);\ SOUI::Log4zStream ss(logBuf, SOUI::LOG4Z_LOG_BUF_SIZE);\ ss << log;\ if (pLogMgr && pLogMgr->prePushLog(id_or_name,level)) \ {\ const void *pAddr = _ReturnAddress(); \ pLogMgr->pushLog(id_or_name, level, filter, logBuf, __FILE__, __LINE__, __FUNCTION__, pAddr);\ }else if(level>=OUTLOG_LEVEL)\ {\ ss<<" "<<__FUNCTION__<<" "<<__FILE__<<":"<<__LINE__<<"\n";\ OutputDebugStringA(logBuf);\ }\ free(logBuf);\ } while (0) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//! fast micro #define LOG_TRACE(id_or_name, filter, log) SOUI_LOG_STREAM(id_or_name, filter, SOUI::ILog4zManager::LOG_LEVEL_TRACE, log) #define LOG_DEBUG(id_or_name, filter, log) SOUI_LOG_STREAM(id_or_name, filter, SOUI::ILog4zManager::LOG_LEVEL_DEBUG, log) #define LOG_INFO(id_or_name, filter, log) SOUI_LOG_STREAM(id_or_name, filter, SOUI::ILog4zManager::LOG_LEVEL_INFO, log) #define LOG_WARN(id_or_name, filter, log) SOUI_LOG_STREAM(id_or_name, filter, SOUI::ILog4zManager::LOG_LEVEL_WARN, log) #define LOG_ERROR(id_or_name, filter, log) SOUI_LOG_STREAM(id_or_name, filter, SOUI::ILog4zManager::LOG_LEVEL_ERROR, log) #define LOG_ALARM(id_or_name, filter, log) SOUI_LOG_STREAM(id_or_name, filter, SOUI::ILog4zManager::LOG_LEVEL_ALARM, log) #define LOG_FATAL(id_or_name, filter, log) SOUI_LOG_STREAM(id_or_name, filter, SOUI::ILog4zManager::LOG_LEVEL_FATAL, log) //! super micro. #define LOGT(filter, log ) LOG_TRACE(SOUI::LOG4Z_MAIN_LOGGER_ID,filter, log ) #define LOGD(filter, log ) LOG_DEBUG(SOUI::LOG4Z_MAIN_LOGGER_ID, filter,log ) #define LOGI(filter, log ) LOG_INFO(SOUI::LOG4Z_MAIN_LOGGER_ID,filter, log ) #define LOGW(filter, log ) LOG_WARN(SOUI::LOG4Z_MAIN_LOGGER_ID, filter,log ) #define LOGE(filter, log ) LOG_ERROR(SOUI::LOG4Z_MAIN_LOGGER_ID,filter, log ) #define LOGA(filter, log ) LOG_ALARM(SOUI::LOG4Z_MAIN_LOGGER_ID,filter, log ) #define LOGF(filter, log ) LOG_FATAL(SOUI::LOG4Z_MAIN_LOGGER_ID,filter, log ) |
设计思路
- 在一开始创建了一个线程,线程里面在不断检测存放log数据的list里面是否有数据,有数据就拿出来并处理
- 外部在使用的时候,由于在一个比较早的时机将LogManager创建好了,通过宏来在需要的地方添加日志,实质是将输入放到对应的list里面
- 这样,线程检测到有数据来了,就去处理
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ 包管理器:各平台安装卸载相关记述09/17
- ♥ Windows 核心编程 _ 进程五06/30
- ♥ Spdlog记述:四09/16
- ♥ Windows IOCP07/22
- ♥ C++20_第一篇06/30
- ♥ Dump分析:堆内存泄露03/29