| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- #ifndef __TWINKLE_LOGGER_H__
- #define __TWINKLE_LOGGER_H__
- //////////////////////////////////////////////////////////////////////////
- // @author: Josephus
- // @date: 2016-5-3
- // @version: 1.0.0
- // @edit_history:
- // @date:2016-6-26 set option for no buffer or not.
- // @date:2016-7-2 delete erroCode stored;
- // add Trace Logger format; add GetLastError() formatting message;
- // add LOG_FUNCION() to log function enter and leave event;
- // @date:2016-7-4 improve the logger time accurating to millisecond;
- // @date:2016-7-26 change the time-formate depend on file_mode.
- // @date:2016-7-29 support for unicode characterset.
- // @date:2016-7-29 write the log buffer into the file for specified time interval.
- // @date:2016-9-2 add 'TRACE_FUNCTION' to log function with returned value(type: int, dword).
- // @date:2016-12-2 add header file: <tchar.h>
- // @date:2017-1-24 add WRITE_ERRCODE_LOG
- // @date:2017-2-9 add FileModeEnum::CustomDir_DaySplit_Mode
- //
- //////////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include <Windows.h>
- #include <fstream>
- #include <string>
- #include <tchar.h>
- #include <io.h>
- #include <direct.h>
- #include <time.h>
- #include <process.h>
- // When using Unicode Windows functions, use Unicode C-Runtime functions too.
- #ifdef UNICODE
- #ifndef _UNICODE
- #define _UNICODE
- #endif
- #endif
- #define MAX_INFOR_LEN 4096
- #define MAX_TIME_LEN 128
- #define DEFALUT_INFOR_LEN 2048
- #define MIN_INFOR_LEN 256
- //#define TIME_TO_WRITE_LOG (5 * 1000)
- #define TIME_TO_WRITE_LOG (2 * 60 * 1000)
- #define LEVEL_TRACE_WRITEABLE 0x1111
- #define LEVEL_INFOR_WRITEABLE 0x1111
- #define LEVEL_DEBUG_WRITEABLE 0x0111
- #define LEVEL_WARNING_WRITEABLE 0x0011
- #define LEVEL_ERROR_WRITEABLE 0x0001
- #define LEVEL_NONE_WRITEABLE 0x0000
- #define GET_LOGGER() (Logger::GetInstance())
- #ifdef UNICODE
- # define WRITE_INFO_LOG (Logger::GetInstance()->TraceInfor)
- # define WRITE_DEBUG_LOG (Logger::GetInstance()->TraceDebug)
- # define WRITE_WARN_LOG (Logger::GetInstance()->TraceWarning)
- # define WRITE_ERROR_LOG (Logger::GetInstance()->TraceError)
- # define WRITE_ERRCODE_LOG (Logger::GetInstance()->TraceErrWithLastCode)
- # define WRITE_INFO_PARAM (Logger::GetInstance()->TraceInfor_f)
- # define WRITE_DEBUG_PARAM (Logger::GetInstance()->TraceDebug_f)
- # define WRITE_WARN_PARAM (Logger::GetInstance()->TraceWarning_f)
- # define WRITE_ERROR_PARAM (Logger::GetInstance()->TraceError_f)
- # define WRITE_TRACE_PARAM (Logger::GetInstance()->TraceDefault_f)
- # define TLOG_TEXT2(STRING) L##STRING
- # define TSTRING2 std::string
- # define tfstream std::wfstream
- #else
- # define WRITE_INFO_LOG (Logger::GetInstance()->TraceInfor)
- # define WRITE_DEBUG_LOG (Logger::GetInstance()->TraceDebug)
- # define WRITE_WARN_LOG (Logger::GetInstance()->TraceWarning)
- # define WRITE_ERROR_LOG (Logger::GetInstance()->TraceError)
- # define WRITE_ERRCODE_LOG (Logger::GetInstance()->TraceErrWithLastCode)
- # define WRITE_INFO_PARAM (Logger::GetInstance()->TraceInfor_f)
- # define WRITE_DEBUG_PARAM (Logger::GetInstance()->TraceDebug_f)
- # define WRITE_WARN_PARAM (Logger::GetInstance()->TraceWarning_f)
- # define WRITE_ERROR_PARAM (Logger::GetInstance()->TraceError_f)
- # define WRITE_TRACE_PARAM (Logger::GetInstance()->TraceDefault_f)
- # define TLOG_TEXT2(STRING) STRING
- # define TSTRING2 std::wstring
- # define tfstream std::fstream
- #endif //UNICODE
- #define TLOG_TEXT(STRING) TLOG_TEXT2(STRING)
- #if defined(UNICODE)
- typedef std::wstring tstring;
- typedef wchar_t tchar;
- #else
- typedef std::string tstring;
- typedef char tchar;
- #endif
- const tstring DEFAULT_LOG_DIR = TLOG_TEXT("");
- const tstring DEFAULT_LOG_NAME = TLOG_TEXT("C:\\Log.txt");
- const tstring TRACE_INFOR = TLOG_TEXT("Infor: ");
- const tstring TRACE_DEBUG = TLOG_TEXT("Debug: ");
- const tstring TRACE_WARNNING = TLOG_TEXT("Warning: ");
- const tstring TRACE_ERROR = TLOG_TEXT("Error: ");
- const tstring TRACE_DEFAULT = TLOG_TEXT("Trace: ");
- enum FileModeEnum
- {
- Default_Mode,
- Single_File_Mode,
- Day_Seperated_Mode,
- MAX_Mode
- };
- enum DateTypeEnum
- {
- For_Record_Type,
- For_File_Type
- };
- enum
- {
- /*path//directory//program.exe*/
- MODE_DEFAULT,
- /*path//directory//*/
- MODE_DIRECTORY,
- /*program.exe*/
- MODE_FILENAME,
- /*program*/
- MODE_FILENAME_ONLY,
- MODE_FILENAME_WITH_PATH,
- MODE_MAX
- };
- class Logger
- {
- public:
- ~Logger(void);
- /*
- * lpszDir is reserved.
- */
- static void InitLog(FileModeEnum eMode = Day_Seperated_Mode, const tchar* lpszDir = TLOG_TEXT(""));
- static void EndLog();
- static Logger* GetInstance();
- static CRITICAL_SECTION s_cs;
- static int bInitialized;
- static void DelayLoop(unsigned long usec);
- static void SetFileWriteMode(FileModeEnum eMode = Day_Seperated_Mode, const tchar* lpszDir = TLOG_TEXT(""));
- static DWORD GetCurExeNameOrPath(tchar* outFilePath, int sizeLen, int fetchKind);
- static bool IsEnableLogg()
- {
- return (bInitialized != 0);
- }
- void TraceInfor(const tchar* strInfo);
- void TraceDebug(const tchar* strInfo);
- void TraceWarning(const tchar* strInfo);
- void TraceError(const tchar* strInfo);
- void TraceDefault(const tchar* strInfo);
- void TraceInfor_f(const tchar* fmt, ...);
- void TraceDebug_f(const tchar* fmt, ...);
- void TraceWarning_f(const tchar* fmt, ...);
- void TraceError_f(const tchar* fmt, ...);
- void TraceDefault_f(const tchar* fmt, ...);
- //Set log file name with inner static value, this function always returned true.
- bool RefleshFileName()
- {
- if(m_eFileMode != Day_Seperated_Mode)
- {
- m_fileName = m_strLogDirOrFilePath;
- }
- return true;
- }
- tstring GetFileName();
- //0x1111, 0x0111, 0x0011, 0x0001, 0x0000
- void SetWriteAbleLevel(USHORT value = LEVEL_INFOR_WRITEABLE) { m_usWriteStatus = value; }
- void DisableRecord() { m_usWriteStatus = LEVEL_NONE_WRITEABLE; }
- void SetRecordNoBuffer()
- {
- if(!m_bWriteRealTime && GetTimerEvent() != NULL)
- {
- SetEvent(hEventWrite);
- }
- m_bWriteRealTime = true;
- }
- /*
- *Account for GetLastError() with plain text.
- *@param erroCode: the error code which would be explained. if 0 function would invoke
- *GetLastError() Api inner.
- */
- int FormatLastError(tchar* szOutMsg, unsigned int sizeLen, DWORD erroCode = 0);
- void TraceErrWithLastCode(const tchar* strInfo);
- HANDLE GetTimerEvent()
- {
- if(hEventWrite && hEventWrite != INVALID_HANDLE_VALUE)
- return hEventWrite;
- return NULL;
- }
- void Start();
- __int64 Now() const;
- __int64 NowInMicro() const;
- private:
- class CAutoWriteHelper;
- friend CAutoWriteHelper;
- Logger();
- static Logger* m_pLogger;
- tstring m_fileName;
- tfstream m_logStream;
- tstring GetCustomTime(DateTypeEnum type = For_Record_Type);
- tstring GetTimeOfDay();
- void Trace(tstring strInfo);
- void Trace_format(const tchar* fmt, va_list list_arg);
- bool WriteToFile(tstring str);
- bool ClearToFile();
-
- USHORT m_usWriteStatus;
- tstring m_strBuffer;
- unsigned int m_bufCurLen;
- static FileModeEnum m_eFileMode;
- static tstring m_strLogDirOrFilePath;
-
- HANDLE hMutexForBuffer;
- HANDLE hEventWrite;
- bool m_bWriteRealTime;
- LARGE_INTEGER m_liPerfFreq;
- LARGE_INTEGER m_liPerfStart;
- private:
- /*
- http://bbs.csdn.net/topics/390648143
- */
- class CAutoWriteHelper
- {
- public:
- CAutoWriteHelper():m_pLog(NULL),m_threadHandle(NULL)
- {
- if(Logger::InitLog(), m_pLog = Logger::GetInstance())
- {
- unsigned int threadID = 0;
- m_threadHandle = (HANDLE)_beginthreadex(NULL, 0,
- Logger::CAutoWriteHelper::TimerWriteProc,
- this, 0, &threadID);
- }
- }
- ~CAutoWriteHelper()
- {
- if(Logger::m_pLogger != NULL)
- {
- if(m_pLogger->GetTimerEvent() != NULL)
- {
- SetEvent(m_pLog->hEventWrite);
- WaitForSingleObject(m_threadHandle, INFINITE);
- CloseHandle(m_threadHandle);
- m_threadHandle = NULL;
- }
- m_pLog = NULL;
- delete Logger::m_pLogger;
- Logger::m_pLogger = NULL;
- }
- }
- static unsigned int _stdcall TimerWriteProc(void* param);
- private:
- Logger* m_pLog;
- HANDLE m_threadHandle;
- void WriteToLog()
- {
- if(m_pLog)
- {
- m_pLog->ClearToFile();
- }
- }
- HANDLE GetLogTimerEvent()
- {
- if(m_pLog)
- {
- return m_pLogger->GetTimerEvent();
- }
- return NULL;
- }
- };
- static CAutoWriteHelper helper;
- };
- namespace TwinkleLib {
-
- class TraceLogger
- {
- public:
- TraceLogger(const tchar* message, const tchar* fileName, int nLine)
- :m_pszMes(message), m_pszFileN(fileName), m_nLine(nLine), m_pnRet(NULL), m_pDwRet(NULL), m_retType(-1)
- {
- if(GET_LOGGER()->IsEnableLogg())
- {
- WRITE_TRACE_PARAM(TLOG_TEXT("Enter {%s}, file: {%s}, line: {%d}."), m_pszMes, m_pszFileN, m_nLine);
- }
- }
- TraceLogger(const tchar* message, const tchar* fileName, int nLine, int* pRet)
- :m_pszMes(message), m_pszFileN(fileName), m_nLine(nLine), m_pnRet(pRet), m_pDwRet(NULL), m_retType(0)
- {
- if(GET_LOGGER()->IsEnableLogg())
- {
- WRITE_TRACE_PARAM(TLOG_TEXT("Enter {%s}, file: {%s}, line: {%d}."), m_pszMes, m_pszFileN, m_nLine);
- }
- }
- TraceLogger(const tchar* message, const tchar* fileName, int nLine, PDWORD pRet)
- :m_pszMes(message), m_pszFileN(fileName), m_nLine(nLine), m_pnRet(NULL), m_pDwRet(pRet), m_retType(1)
- {
- if(GET_LOGGER()->IsEnableLogg())
- {
- WRITE_TRACE_PARAM(TLOG_TEXT("Enter {%s}, file: {%s}, line: {%d}."), m_pszMes, m_pszFileN, m_nLine);
- }
- }
- ~TraceLogger()
- {
- if(GET_LOGGER()->IsEnableLogg())
- {
- if(m_retType == 0)
- {
- WRITE_TRACE_PARAM(TLOG_TEXT("Leave {%s}, file: {%s}, line: {%d}, return: {%d}."),
- m_pszMes, m_pszFileN, m_nLine, *m_pnRet);
- }
- else if(m_retType == 1)
- {
- WRITE_TRACE_PARAM(TLOG_TEXT("Leave {%s}, file: {%s}, line: {%d}, return: {%u}."),
- m_pszMes, m_pszFileN, m_nLine, *m_pDwRet);
- }
- else
- {
- WRITE_TRACE_PARAM(TLOG_TEXT("Leave {%s}, file: {%s}, line: {%d}."), m_pszMes, m_pszFileN, m_nLine);
- }
- }
- }
- private:
- TraceLogger (TraceLogger const &);
- TraceLogger & operator = (TraceLogger const &);
- const tchar* m_pszMes;
- const tchar* m_pszFileN;
- int m_nLine;
- int* m_pnRet;
- PDWORD m_pDwRet;
- int m_retType;
- };
- }
- const tchar *_GetFileNameForLog(const tchar *pszFilePath);
- #define LOG_FUNCTION() TwinkleLib::TraceLogger _FunctionTraceLogger(\
- TLOG_TEXT(__FUNCTION__), _GetFileNameForLog(TLOG_TEXT(__FILE__)), __LINE__)
- #define TRACE_FUNCTION(pValue) TwinkleLib::TraceLogger _FunctionTraceLogger(\
- TLOG_TEXT(__FUNCTION__), _GetFileNameForLog(TLOG_TEXT(__FILE__)), __LINE__, (pValue))
- #endif //__TWINKLE_LOGGER_H__
|