#ifndef LOGGER__H_ #define LOGGER__H_ #ifdef _WIN32 #pragma once //#pragma warning(disable:4710) #pragma warning(disable:4996) #include #include #include #else #ifndef SINGLE_THREADED_MODEL #include #endif #include #endif // _WIN32 class HLoggerExtension { public: HLoggerExtension() {} virtual ~HLoggerExtension() {} protected: virtual void OnWrite(const char * pszText, unsigned nLength) = 0; friend class HLogger; }; /////////////////////////////////////// class HLogger { public: enum { MD_MAX_STRING = 1024, // max one-line log length MD_MAX_PATH = 1024, // max path name length MD_MAX_DATE = 16, // max date string length MIN_LIMIT_SIZE = 4096 }; enum Options { dayWrite = 0x0001, // add day : default timeWrite = 0x0002, // add time : default autoNewLine = 0x0004, // ... onlyLevel = 0x0008, consoleWrite = 0x0010 }; HLogger(); virtual ~HLogger(); bool Create(unsigned nLevel, bool bContinue, const char * szPathName = NULL, bool bIsBinary = false); // nLevel : max write level // bContinue : true is contiue writing to exist log file. // szPathName : NULL ==> log name is date. ex) 20030201.log // szPathName : Directory ==> log name is date. ex) Create("log/") = log/20030201.log // szPathName : full path name or file name ==> equal. void Release(); // for log file close. inline int GetLevel(); inline void SetLevel(unsigned nLevel); inline int GetOption(); inline void SetOption(int flagOption); inline void SetFileSplitSize(off_t nFileSize); inline off_t GetFileSplitSize(); inline off_t GetFileLimitSize(); inline void SetFileLimitSize(off_t nFileSize); inline void SetExtension(HLoggerExtension * pExtension); // auto delete instance void Write(int nLevel, const char * pszLog); void Dump(int nLevel, const char * pszLog, size_t nSize, bool bWithHex); void Format(int nLevel, const char * fmt, ...); void Trace(const char * szSrcFileName, const unsigned nSrcLine, int nLevel, const char *fmt, ...); protected: inline char * GetLogStringBuffer(); inline void SetLogStringBuffer(const char * pszLog); bool OpenFile(unsigned nLevel, const char * szPathName); void CloseFile(); void GetDateTime(char *szDate, char *szTime); void WriteLog(const bool bIsTrace); virtual inline void OnWrite(const char * pszText, unsigned nLength); #ifndef SINGLE_THREADED_MODEL inline void Lock(); inline void Unlock(); #endif public: // Two pair fuctions for source file name and line // Must be called pair. void SetSrcInfoWithLock(const char * szSrcFileName, const unsigned nSrcLine); void TraceWithUnlock(int nLevel); friend void __Logger_Format(int nLevel, const char *fmt, ...); friend void __Logger_SetSrcInfoWithLock(const char * szSrcFileName, const unsigned nSrcLine); friend void __Logger_TraceWithUnlock(int nLevel, const char *fmt, ...); public: int m_nLogLength; private: char * m_szWriteString; char * m_szLogString; char * m_szTmpString; int m_fhLog; int m_nLevel; int m_flagOption; bool m_bIsContinue; bool m_bIsBinary; off_t m_nFileSplitSize; // bytes off_t m_nFileLimitSize; // bytes char m_szPathName[MD_MAX_PATH]; char m_szLogFileName[MD_MAX_PATH]; unsigned m_nLogFileNameExt; bool m_bIsFileNameChange; char m_szPrevDate[MD_MAX_DATE]; char m_szSrcFileName[MD_MAX_PATH]; unsigned m_nSrcLine; int m_nWriteLength; #ifdef _WIN32 struct _timeb m_tTimeb; #else struct timeb m_tTimeb; #endif char m_szMiliSec[8]; char m_szTracePathName[MD_MAX_PATH]; int m_nTracePathLength; #ifndef SINGLE_THREADED_MODEL #ifdef _WIN32 CRITICAL_SECTION m_csInstance; #else pthread_mutex_t m_mutex; #endif // _WIN32 #endif // SINGLE_THREADED_MODEL HLoggerExtension * m_pExtension; }; inline int HLogger::GetLevel() { return m_nLevel; } inline void HLogger::SetLevel(unsigned nLevel) { m_nLevel = nLevel; } inline int HLogger::GetOption() { return m_flagOption; } inline void HLogger::SetOption(int flagOption) { m_flagOption = flagOption; } inline void HLogger::SetFileSplitSize(off_t nFileSize) { m_nFileSplitSize = nFileSize; } inline off_t HLogger::GetFileSplitSize() { return m_nFileSplitSize; } inline off_t HLogger::GetFileLimitSize() { return m_nFileLimitSize; } inline void HLogger::SetFileLimitSize(off_t nFileSize) { if (nFileSize < MIN_LIMIT_SIZE) m_nFileLimitSize = MIN_LIMIT_SIZE; else m_nFileLimitSize = nFileSize; } inline char * HLogger::GetLogStringBuffer() { return m_szLogString; } inline void HLogger::SetLogStringBuffer(const char * pszLog) { m_szLogString = (char *)pszLog; } inline void HLogger::OnWrite(const char * pszText, unsigned nLength) { write(m_fhLog, pszText, nLength); } inline void HLogger::SetExtension(HLoggerExtension * pExtension) { if (m_pExtension) delete m_pExtension; m_pExtension = pExtension; } #ifndef SINGLE_THREADED_MODEL inline void HLogger::Lock() { #ifdef _WIN32 EnterCriticalSection(&m_csInstance); #else pthread_mutex_lock(&m_mutex); #endif } inline void HLogger::Unlock() { #ifdef _WIN32 LeaveCriticalSection(&m_csInstance); #else pthread_mutex_unlock(&m_mutex); #endif } #endif // SINGLE_THREADED_MODEL /////////////////////////////////////// extern HLogger * g_pLogFile__Logger; extern inline int __Logger_GetLevel() { if (g_pLogFile__Logger == NULL) return 0; return g_pLogFile__Logger->GetLevel(); } extern inline void __Logger_SetLevel(unsigned nLevel) { if (g_pLogFile__Logger == NULL) return; g_pLogFile__Logger->SetLevel(nLevel); } extern inline int __Logger_GetOption() { if (g_pLogFile__Logger == NULL) return 0; return g_pLogFile__Logger->GetOption(); } extern inline void __Logger_SetOption(int flagOption) { if (g_pLogFile__Logger == NULL) return; g_pLogFile__Logger->SetOption(flagOption); } extern inline void __Logger_SetExtension(HLoggerExtension * pExtension) { if (g_pLogFile__Logger == NULL) return; g_pLogFile__Logger->SetExtension(pExtension); } extern inline void __Logger_Write(int nLevel, const char * pszLog) { if (g_pLogFile__Logger == NULL) return; g_pLogFile__Logger->Write(nLevel, pszLog); } extern inline void __Logger_Dump(int nLevel, const char * pszLog, size_t nSize, bool bWithHex) { if (g_pLogFile__Logger == NULL) return; g_pLogFile__Logger->Dump(nLevel, pszLog, nSize, bWithHex); } extern inline void __Logger_Format(int nLevel, const char * fmt, ...) { if (g_pLogFile__Logger == NULL) return; if (nLevel > g_pLogFile__Logger->GetLevel() || ((g_pLogFile__Logger->GetOption() & HLogger::onlyLevel) == HLogger::onlyLevel && g_pLogFile__Logger->GetLevel() != nLevel)) return; va_list vaList; va_start(vaList, fmt); #ifndef SINGLE_THREADED_MODEL g_pLogFile__Logger->Lock(); #endif #ifdef _WIN32 g_pLogFile__Logger->m_nLogLength = _vsnprintf(g_pLogFile__Logger->GetLogStringBuffer(), HLogger::MD_MAX_STRING - 1, fmt, vaList); #else g_pLogFile__Logger->m_nLogLength = vsnprintf(g_pLogFile__Logger->GetLogStringBuffer(), HLogger::MD_MAX_STRING - 1, fmt, vaList); #endif if (g_pLogFile__Logger->m_nLogLength < 0 || g_pLogFile__Logger->m_nLogLength >= HLogger::MD_MAX_STRING) { g_pLogFile__Logger->m_nLogLength = HLogger::MD_MAX_STRING; g_pLogFile__Logger->GetLogStringBuffer()[HLogger::MD_MAX_STRING - 1] = '\0'; } va_end(vaList); g_pLogFile__Logger->WriteLog(false); #ifndef SINGLE_THREADED_MODEL g_pLogFile__Logger->Unlock(); #endif } extern inline void __Logger_SetSrcInfoWithLock(const char * szSrcFileName, const unsigned nSrcLine) { if (g_pLogFile__Logger == NULL) return; g_pLogFile__Logger->SetSrcInfoWithLock(szSrcFileName, nSrcLine); } extern inline void __Logger_TraceWithUnlock(int nLevel, const char *fmt, ...) { if (g_pLogFile__Logger == NULL) return; if (nLevel > g_pLogFile__Logger->GetLevel() || ((g_pLogFile__Logger->GetLevel() & HLogger::onlyLevel) == HLogger::onlyLevel && g_pLogFile__Logger->GetLevel() != nLevel)) { #ifndef SINGLE_THREADED_MODEL g_pLogFile__Logger->Unlock(); #endif return; } va_list vaList; va_start(vaList, fmt); #ifdef _WIN32 g_pLogFile__Logger->m_nLogLength = _vsnprintf(g_pLogFile__Logger->GetLogStringBuffer(), HLogger::MD_MAX_STRING - 1, fmt, vaList); #else g_pLogFile__Logger->m_nLogLength = vsnprintf(g_pLogFile__Logger->GetLogStringBuffer(), HLogger::MD_MAX_STRING - 1, fmt, vaList); #endif if (g_pLogFile__Logger->m_nLogLength < 0 || g_pLogFile__Logger->m_nLogLength >= HLogger::MD_MAX_STRING) { g_pLogFile__Logger->m_nLogLength = HLogger::MD_MAX_STRING; g_pLogFile__Logger->GetLogStringBuffer()[HLogger::MD_MAX_STRING - 1] = '\0'; } va_end(vaList); g_pLogFile__Logger->TraceWithUnlock(nLevel); } #define HLOG_OPEN(LEVEL, CONTINUE, FILENAME) { if (g_pLogFile__Logger == NULL) { g_pLogFile__Logger = new HLogger; if (g_pLogFile__Logger->Create(LEVEL, CONTINUE, FILENAME) == false) g_pLogFile__Logger = NULL; } } #define HLOG_CLOSE() { if (g_pLogFile__Logger) { delete g_pLogFile__Logger; g_pLogFile__Logger = NULL; } } #define HLOG_GETLEVEL __Logger_GetLevel #define HLOG_SETLEVEL __Logger_SetLevel #define HLOG_GETOPTION __Logger_GetOption #define HLOG_SETOPTION __Logger_SetOption #define HLOG_SETEXTENSION __Logger_SetExtension #define HLOG __Logger_Write #define HLOGD __Logger_Dump #define HLOGF __Logger_Format #define PSTRACE __Logger_SetSrcInfoWithLock(__FILE__, __LINE__),__Logger_TraceWithUnlock #endif // LOGGER__H_