首页 > 代码库 > 简单的日志系统
简单的日志系统
參考glog写了现有的Logging系统。
直接有
enum LoggingEnum{
LOG_INFO,
LOG_DBBUG,
LOG_ERROR,
LOG_WARNNING,
LOG_END
};
几种等级的日志,实时刷到console上,异步延迟写到日志上,建立队列缓存日志,时间一到一起刷到file,好了,看下Logging实现:
class Active; struct Buffer; enum LoggingEnum{ LOG_INFO, LOG_DBBUG, LOG_ERROR, LOG_WARNNING, LOG_END }; enum GLogColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW }; class Logging { public: Logging(); ~Logging(); void WriteWithFunLine(LoggingEnum eLoggingEnum, char* fun, int line, char* msg, ...); void WriteBuffer(Buffer*& pBuffer); private: INT32 CreateLogFile(LoggingEnum aLoggingEnum); void Write(LoggingEnum eLoggingEnum, char* msg, int msgLen); private: FILE* m_File[LOG_END]; Active* m_pActive; typedef boost::posix_time::ptime PTIME; boost::atomic<BOOLEAN> m_IfCanFlush[LOG_END]; PTIME m_PrelushTime[LOG_END]; std::queue<Buffer*> m_BufferQueue[LOG_END]; };
Logging g_Logging; string LOGPreStr[LOG_END] = {"LOG_INFO", "LOG_DBBUG", "LOG_ERROR", "LOG_WARNNING"}; #ifdef _WINDOWS // Returns the character attribute for the given color. WORD GetColorAttribute(GLogColor color) { switch (color) { case COLOR_RED: return FOREGROUND_RED; case COLOR_GREEN: return FOREGROUND_GREEN; case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; default: return 0; } } #else // Returns the ANSI color code for the given color. const char* GetAnsiColorCode(GLogColor color) { switch (color) { case COLOR_RED: return "1"; case COLOR_GREEN: return "2"; case COLOR_YELLOW: return "3"; case COLOR_DEFAULT: return ""; }; return NULL; // stop warning about return type. } #endif // OS_WINDOWS GLogColor GLogColorVec[LOG_END] = {COLOR_GREEN, COLOR_DEFAULT, COLOR_RED, COLOR_YELLOW}; Logging::Logging(){ PTIME nowTime = boost::posix_time::microsec_clock::local_time(); INT32 n32Res = eNormal; for (INT32 i = LOG_INFO; i < LOG_END; ++i){ m_File[i] = NULL; m_IfCanFlush[i] = FALSE; m_PrelushTime[i] = nowTime; n32Res = CreateLogFile((LoggingEnum)i); if (n32Res != eNormal){ printf("Createfile(i) failed", i); } } m_pActive = Active::CreateActive(std::bind(&Logging::WriteBuffer, this, std::placeholders::_1)); } void Logging::Write(LoggingEnum eLoggingEnum, char* msg, int msgLen){ Buffer* pBuffer = m_pActive->GetBuffer(); pBuffer->m_LogLevel = eLoggingEnum; char* curData = http://www.mamicode.com/pBuffer->m_pMsg;>
当中用到的Active就是简单的生产者消费者模型:struct Buffer { Buffer():m_LogLevel(0), m_Len(1024), m_pMsg(new char[m_Len]){} ~Buffer(){ if (NULL != m_pMsg) delete []m_pMsg; } Buffer(int size):m_LogLevel(0), m_Len(size) , m_pMsg(new char[m_Len]){ } int m_LogLevel; int m_Len; char* m_pMsg; }; typedef std::function<void(Buffer*&)> Callback; class Active { private: Active(const Active&); Active& operator=(const Active&); Active(); void doDone(){m_IfDone = true;} void Run(); void setCallBack(Callback aCallBack); bool IfEmpty(); int Consume(Buffer*& apBuffer); std::queue<Buffer*> m_Queue; boost::thread m_Thread; volatile bool m_IfDone; Callback m_Callback; boost::mutex m_Mutex; boost::mutex m_ObjectMutex; CSSObejctPool<Buffer> m_pBufferPool; boost::condition_variable m_ConditionVar; public: ~Active(); Buffer* GetBuffer(); void ReleaseBuffer(Buffer*& pBuffer); void Send(Buffer* apBuffer); void Stop(); static Active* CreateActive(Callback aCallBack); };Active::Active(): m_IfDone(false){} Active::~Active() { Stop(); } void Active::Send( Buffer* apBuffer ){ if (NULL != apBuffer){ boost::mutex::scoped_lock lock(m_Mutex); bool bNeedSig = m_Queue.empty(); m_Queue.push(apBuffer); if (bNeedSig){ m_ConditionVar.notify_one(); } } } void Active::Run() { Buffer* pBuffer = NULL; while (!m_IfDone && 0 == Consume(pBuffer)){ m_Callback(pBuffer); if (NULL != pBuffer){ boost::mutex::scoped_lock lock(m_ObjectMutex); m_pBufferPool.ReleaseObejct(pBuffer); } } } Active* Active::CreateActive(Callback aCallBack){ Active* aPtr = new Active(); aPtr->m_Thread = boost::thread(&Active::Run, aPtr); aPtr->m_Callback = aCallBack; return aPtr; } void Active::setCallBack(Callback aCallBack){ m_Callback = aCallBack; } Buffer* Active::GetBuffer(){ boost::mutex::scoped_lock lock(m_ObjectMutex); return m_pBufferPool.AcquireObject(); } bool Active::IfEmpty(){ return m_Queue.empty(); } int Active::Consume(Buffer*& apBuffer){ boost::mutex::scoped_lock lock(m_Mutex); while (m_Queue.empty()){ if (m_IfDone){ return 1; } m_ConditionVar.wait(lock); } if (m_IfDone){ return 1; } apBuffer = m_Queue.front(); m_Queue.pop(); return 0; } void Active::Stop(){ m_IfDone = true; m_ConditionVar.notify_one(); } void Active::ReleaseBuffer(Buffer*& pBuffer){ if (NULL != pBuffer){ boost::mutex::scoped_lock lock(m_ObjectMutex); m_pBufferPool.ReleaseObejct(pBuffer); pBuffer = NULL; } }
ok!仅仅有4个文件,仅仅要有boost库就能够编译使用了。用到的objectpool是之前博客介绍过的内存池。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。