C++文件型日志类(WIN32) v0.2

C++文件型日志类 v0.2版发布 附带一个范例程序 有做24小时值守程序或者后台作业程序可以用一用

下载点见我的资源 有需要的朋友可以去下载 不要分

 

http://download.csdn.net/source/751774

 

代码如下

  1. /*
  2. Destination: 文件型日志封装类 v0.2
  3. Author: llbird
  4. Email: wushaojian@21cn.com
  5. Blog: http://blog.csdn.net/wujian53 
  6. Update: 2008-6-10
  7. */
  8. #ifndef _CX_LOG_H_
  9. #define _CX_LOG_H_
  10. #if defined(_MSC_VER)
  11.     #pragma warning(disable: 4530)
  12. #endif
  13. #include <stdio.h>
  14. #include <time.h>
  15. #include <assert.h>
  16. #include <list>
  17. #include <iterator>
  18. #include <stdexcept>
  19. #include <exception>
  20. #if defined(_MSC_VER) || defined(__INTEL_COMPILER)  
  21.     #include <comdef.h>
  22. #endif
  23. #include <tchar.h>
  24. #include <process.h>
  25. #include <windows.h>
  26. //
  27. ///文件型多线程日志类 class for log file
  28. //定义格式化输出
  29. #ifndef CX_LOG_DEFAULT_FORMAT
  30.     #if (defined(_MSC_VER) && _MSC_VER<=1310) || defined(__BORLANDC__)  || (defined(__GNUC__) && defined(_UNICODE))
  31.         #define CX_LOG_DEFAULT_FORMAT _T("%s %s %s(%d): %s/r/n")
  32.     #else
  33.         #define CX_LOG_DEFAULT_FORMAT _T("%s %s %s(%s, %d): %s/r/n")
  34.     #endif
  35. #endif
  36. //定义格式化输出的缓冲区大小
  37. #ifndef CX_LOG_DEFAULT_FORMAT_SIZE
  38.     #define CX_LOG_DEFAULT_FORMAT_SIZE 1024
  39. #endif
  40. //定义是否替换控制用ASCII
  41. #ifndef CX_LOG_REPLACE_CONTROL
  42.     #define CX_LOG_REPLACE_CONTROL true
  43. #endif
  44. //定义控制用ASCII的默认替换字符
  45. #ifndef CX_LOG_REPLACE_ASCII
  46.     #define CX_LOG_REPLACE_ASCII _T(' ')
  47. #endif
  48. //定义窗口通知消息
  49. #ifndef WM_CX_LOG
  50.     #define WM_CX_LOG WM_USER + 2200
  51. #endif
  52. class CxLog
  53. {
  54. public:
  55.     enum EnumType{
  56.         CX_LOG_MESSAGE = 0,
  57.         CX_LOG_WARNING,
  58.         CX_LOG_EXCEPTION,
  59.         CX_LOG_ERROR
  60.     };
  61.     static CxLog& Instance()
  62.     {
  63.         static bool alive = false;
  64.         static CxLog log(alive);
  65.         if(!alive)
  66.         {
  67.             OutputDebugString(_T("CxLog has destroy!"));
  68.             throw std::runtime_error("CxLog has destroy!");
  69.         }
  70.         return log;
  71.     }
  72.     struct Item
  73.     {
  74.         SYSTEMTIME _Time;//>time stamp
  75.         TCHAR _szTime[24];
  76.         LPTSTR _szSrc;//>source file name
  77.         LPTSTR _szFunc;//>founction name
  78.         ULONG _uLine;//>line number
  79.         EnumType _eType;//
  80.         LPTSTR _szDesc;//>content
  81.         LPBYTE _pBin;//>binary data szBuffer
  82.         ULONG _uBinSize;//>the size of binary data szBuffer
  83.         //BOOL _bLog;//>complete the log
  84.         Item() 
  85.         {
  86.             InitItem(NULL, NULL, 0, CX_LOG_MESSAGE, NULL, NULL, 0);
  87.         }
  88.         Item(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType eType, 
  89.             LPCTSTR szDesc, LPVOID pBin = NULL, ULONG uSize = 0) 
  90.         {
  91.             InitItem(szSrc, szFunc, uLine, eType, szDesc, pBin, uSize);
  92.         }
  93.         ~Item()
  94.         {
  95.             ReleaseStringBuffer(_szSrc);    
  96.             ReleaseStringBuffer(_szFunc);
  97.             ReleaseStringBuffer(_szDesc);
  98.             
  99.             if(_pBin)
  100.             {
  101.                 delete []_pBin;
  102.                 _pBin = NULL;
  103.             }
  104.         }
  105.         VOID InitItem(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType eType, 
  106.             LPCTSTR szDesc, LPVOID pBin, ULONG uSize)
  107.         {
  108.             GetLocalTime(&_Time);
  109.             wsprintf(_szTime, _T("%04d-%02d-%02d %02d:%02d:%02d.%03d"), 
  110.                 _Time.wYear,
  111.                 _Time.wMonth,
  112.                 _Time.wDay,
  113.                 _Time.wHour,
  114.                 _Time.wMinute,
  115.                 _Time.wSecond,
  116.                 _Time.wMilliseconds
  117.                 );
  118.             _eType = eType;
  119.             _uBinSize = _uLine = 0;
  120.             _szSrc = _szFunc = _szDesc = NULL;
  121.             _pBin = NULL;
  122.             if(szSrc)
  123.             {
  124.                 LPCTSTR p = szSrc;
  125.             #ifndef CX_LOG_FULL_SOURCE_NAME
  126.                 p = szSrc + _tcslen(szSrc);
  127.                 while(p>szSrc && *p!=_T('//'))
  128.                     p--;
  129.                 
  130.                 if(*p == _T('//'))
  131.                     p++;
  132.             #endif
  133.                 AllocStringBuffer(_szSrc, p);
  134.                 _uLine = uLine;
  135.             }
  136.             
  137.             AllocStringBuffer(_szFunc, szFunc);
  138.             AllocStringBuffer(_szDesc, szDesc);
  139.             if(pBin && uSize)
  140.             {
  141.                 _pBin = new BYTE[uSize];
  142.                 assert(_pBin);
  143.                 memcpy(_pBin, pBin, uSize);
  144.                 _uBinSize = uSize;
  145.             }
  146.         }
  147.         VOID AllocStringBuffer(LPTSTR& szDest, LPCTSTR& szSrc)
  148.         {
  149.             if(szSrc)
  150.             {
  151.                 ULONG uSize = _tcslen(szSrc) + 1;
  152.                 szDest = new TCHAR[uSize];
  153.                 assert(szDest);
  154.                 memcpy(szDest, szSrc, uSize*sizeof(TCHAR));
  155.             }
  156.         }
  157.         VOID ReleaseStringBuffer(LPTSTR& lpDest)
  158.         {
  159.             if(lpDest)
  160.             {
  161.                 delete []lpDest;
  162.                 lpDest = NULL;
  163.             }
  164.         }
  165.         
  166.         LPTSTR Format(LPTSTR szBuffer, ULONG uSize, ULONG* pSize = NULL)
  167.         {
  168.             static LPCTSTR szType[] = {_T("Message"), _T("Warning"), _T("Exception"), _T("Error")};
  169.             if(!szBuffer)
  170.                 return szBuffer;
  171.             int iLen;
  172.             #if (defined(_MSC_VER) && _MSC_VER<=1310) || defined(__BORLANDC__) || (defined(__GNUC__) && defined(_UNICODE))
  173.                 iLen = _sntprintf(szBuffer, uSize, 
  174.                     CX_LOG_DEFAULT_FORMAT, 
  175.                     _szTime, szType[_eType], 
  176.                     _szSrc?_szSrc:_T(""), _uLine,
  177.                     _szDesc?_szDesc:_T(""));
  178.             #else
  179.                 iLen = _sntprintf(szBuffer, uSize, 
  180.                     CX_LOG_DEFAULT_FORMAT, 
  181.                     _szTime, szType[_eType], 
  182.                     _szSrc?_szSrc:_T(""), _szFunc?_szFunc:_T(""), _uLine,
  183.                     _szDesc?_szDesc:_T(""));
  184.             #endif
  185.             if(iLen>4 && !_tcsncmp(szBuffer+iLen-4, _T("/r/n"), 2))
  186.                 *(szBuffer+iLen-2) = TCHAR(NULL), iLen -= 2;
  187.             
  188.             if(pSize)
  189.                 *pSize = iLen;
  190.             return szBuffer;
  191.         }
  192.         LPTSTR FormatBinary(LPTSTR szBuffer, ULONG uSize, ULONG* pSize = NULL,
  193.             bool bReplace  = CX_LOG_REPLACE_CONTROL, 
  194.             TCHAR chReplaceAscii = CX_LOG_REPLACE_ASCII)
  195.         {
  196.             return FormatBinary(_pBin, _uBinSize, szBuffer, uSize,  pSize, 
  197.                 bReplace, chReplaceAscii);
  198.         }
  199.         
  200.         LPTSTR FormatBinary(LPVOID lpBin, ULONG uBinSize, 
  201.             LPTSTR szBuffer, ULONG uSize,  ULONG* pSize = NULL, 
  202.             bool bReplace  = CX_LOG_REPLACE_CONTROL, 
  203.             TCHAR chReplaceAscii = CX_LOG_REPLACE_ASCII)
  204.         {
  205.             static TCHAR chHex[] = {
  206.                 _T('0'), _T('1'), _T('2'), _T('3'), _T('4'), _T('5'), _T('6'), _T('7'), 
  207.                 _T('8'), _T('9'), _T('A'), _T('B'), _T('C'), _T('D'), _T('E'), _T('F')};
  208.             TCHAR temp[8+2+3*16+16+2+1];
  209.             ULONG uActualSize = 0;
  210.             if(!_pBin)
  211.             {
  212.                 if(pSize)
  213.                     *pSize = uActualSize;
  214.                 return szBuffer;
  215.             }
  216.             if(!szBuffer)
  217.             {
  218.                 uSize = ((_uBinSize>>4)+1)*(8+2+3*16+16+2)+1;
  219.                 szBuffer = new TCHAR[uSize];
  220.                 assert(szBuffer);
  221.             }
  222.             for(ULONG p = 0; p<_uBinSize && uActualSize<uSize-1; p += 16)
  223.             {
  224.                 wsprintf(temp, _T("%08X: "), p); 
  225.                 int i;
  226.                 for(i = 0; i < 16; i++)
  227.                 {
  228.                     if(p+i<_uBinSize)
  229.                     {
  230.                         *(temp+8+2+3*i) = chHex[*(_pBin+p+i)>>4];
  231.                         *(temp+8+2+3*i+1) = chHex[*(_pBin+p+i)&0x0F];
  232.                         *(temp+8+2+3*i+2) = _T(' ');
  233.                     }
  234.                     else
  235.                         _tcscpy(temp+8+2+3*i, _T("   "));
  236.                 }
  237.                 for(i = 0; i < 16; i++)
  238.                 {
  239.                     if(p+i<_uBinSize)
  240.                         *(temp+8+2+3*16+i) = (bReplace&&_istcntrl(TCHAR(*(_pBin+p+i)))) ? chReplaceAscii : *(_pBin+p+i);
  241.                     else
  242.                         *(temp+8+2+3*16+i) = _T(' ');
  243.                 }
  244.                 
  245.                     
  246.                 _tcscpy(temp+8+2+3*16+16, _T("/r/n"));
  247.                 ULONG uLen = uSize-uActualSize-1>8+2+3*16+16+2? 8+2+3*16+16+2 : uSize-uActualSize-1;
  248.                 memcpy(szBuffer+uActualSize, temp, uLen*sizeof(TCHAR));
  249.                 uActualSize += uLen;
  250.             }
  251.             if(pSize)
  252.                 *pSize = uActualSize;
  253.             szBuffer[uActualSize] = TCHAR(NULL);
  254.             return szBuffer;
  255.         }
  256.     };
  257.     LPTSTR GetLogFileName()
  258.     {
  259.     #if defined(CX_LOG_BY_DAY) || defined(CX_LOG_BY_WEEK) || defined(CX_LOG_BY_MONTH) || defined(CX_LOG_BY_YEAR)
  260.         time_t now = time(NULL);
  261.         TCHAR szName[64];
  262.         #if defined(CX_LOG_BY_DAY)
  263.             _tcsftime(szName, 64, _T("%Y%m%d.log"), localtime(&now));
  264.         #elif defined(CX_LOG_BY_WEEK)
  265.             _tcsftime(szName, 64, _T("%Y%W.log"), localtime(&now));
  266.         #elif defined(CX_LOG_BY_MONTH)
  267.             _tcsftime(szName, 64, _T("%Y%m.log"), localtime(&now));
  268.         #elif defined(CX_LOG_BY_YEAR)
  269.             _tcsftime(szName, 64, _T("%Y.log"), localtime(&now));
  270.         #endif
  271.         _tcscat(_tcscpy(_szFileName, GetFilePath()), szName); 
  272.     #endif
  273.         return _szFileName;
  274.     }
  275.     TCHAR* GetFilePath()
  276.     {
  277.         static TCHAR szFilePath[MAX_PATH];
  278.         static BOOL bFlag = FALSE;
  279.         if(!bFlag)
  280.         {
  281.             DWORD dwLen = ::GetModuleFileName(NULL, szFilePath, MAX_PATH);
  282.             if(dwLen)
  283.             {
  284.                 LPTSTR p = szFilePath + dwLen;
  285.                 while(p>szFilePath && *p!=_T('//'))
  286.                     p--;
  287.                 
  288.                 if(*p == _T('//'))
  289.                     _tcscpy(p, _T("//Log//"));
  290.             }
  291.             else
  292.                 _tcscpy(szFilePath, _T(".//Log//"));
  293.             bFlag = TRUE;
  294.         }
  295.         return szFilePath;
  296.     }
  297. public:
  298.     
  299.     CxLog(bool &alive) : _bAlive(alive)
  300.     {
  301.         _bAlive = true;
  302.         _hWnd = NULL;
  303.     #ifdef CX_LOG_FILE_NAME
  304.         ULONG uSize = _tcslen(CX_LOG_FILE_NAME) + 1;
  305.         uSize = uSize>MAX_PATH ? MAX_PATH : uSize;
  306.         memcpy(_szFileName, CX_LOG_FILE_NAME, uSize*sizeof(TCHAR));
  307.     #else
  308.         CreateDirectory(GetFilePath(), NULL);  //>create log sub dir
  309.         #if !defined(CX_LOG_BY_DAY) && !defined(CX_LOG_BY_WEEK) && !defined(CX_LOG_BY_MONTH) && !defined(CX_LOG_BY_YEAR)
  310.             time_t now = time(NULL);
  311.             TCHAR szName[64];
  312.             _tcsftime(szName, 64, _T("%Y%m%d.log"), localtime(&now));
  313.             _tcscat(_tcscpy(_szFileName, GetFilePath()), szName); 
  314.         #endif 
  315.     #endif
  316.         _TerminateEvent = CreateEvent(0, TRUE, FALSE, NULL);
  317.         _LogHandle = CreateEvent(0, FALSE, FALSE, NULL);
  318.         ::InitializeCriticalSection(&_LogMutex);
  319.     #ifdef _MT
  320.         unsigned int id;
  321.         _hThreadHandle = (HANDLE)::_beginthreadex(NULL, 0, StaticThreadProc, this, 0, &id);
  322.     #else
  323.         DWORD id;
  324.         _hThreadHandle = ::CreateThread(NULL, 0, StaticThreadProc, this, 0, &id); 
  325.     #endif  
  326.     }
  327.     ~CxLog()
  328.     {
  329.         Destroy();  
  330.     }
  331.     VOID Destroy()
  332.     {
  333.         _bAlive = false;
  334.         if(_hThreadHandle)
  335.         {
  336.             SetEvent(_TerminateEvent);
  337.             if(::WaitForSingleObject(_hThreadHandle, 500) != WAIT_OBJECT_0)
  338.                 ::TerminateThread(_hThreadHandle, 0);
  339.             CloseHandle(_hThreadHandle);
  340.         }
  341.         ::DeleteCriticalSection(&_LogMutex);
  342.     }
  343.     VOID Lock()
  344.     {
  345.         ::EnterCriticalSection(&_LogMutex);
  346.     }
  347.     VOID Unlock()
  348.     {
  349.         ::LeaveCriticalSection(&_LogMutex);
  350.     }
  351.     VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType eType, 
  352.             LPCTSTR szDesc, LPVOID pBin = NULL, ULONG uSize = 0)
  353.     {
  354.         Item* p = new Item(szSrc, szFunc, uLine, eType, szDesc, pBin, uSize);
  355.     #if defined(_CONSOLE) || defined(_DEBUG)
  356.         TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  357.         p->Format(szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE);
  358.         LPTSTR pBinStr = p->FormatBinary(p->_pBin, p->_uBinSize, NULL, 0,  &uSize);
  359.         #ifdef _CONSOLE
  360.             if(szBuffer)
  361.                 _tprintf(szBuffer);
  362.             if(pBinStr)
  363.                 _tprintf(pBinStr);
  364.         #endif
  365.         #ifdef _DEBUG
  366.             OutputDebugString(szBuffer);
  367.             OutputDebugString(pBinStr);
  368.         #endif
  369.         delete []pBinStr;
  370.     #endif
  371.         if (IsWindow(_hWnd))
  372.         {
  373.             Item *sp = new Item(szSrc, szFunc, uLine, eType, szDesc, pBin, uSize);
  374.             PostMessage(_hWnd, WM_CX_LOG, 0, (LPARAM)sp);
  375.         }
  376.         Lock();
  377.         _ItemList.push_back(p);
  378.         Unlock();
  379.         
  380.         SetEvent(_LogHandle);
  381.     }
  382.     VOID LogBin(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType eType, LPVOID pBin, ULONG uSize)
  383.     {
  384.         Log(szSrc, szFunc, uLine, eType, NULL, pBin, uSize);
  385.     }
  386.     VOID LogN(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType eType, LPCTSTR szFormat, ...) 
  387.     {
  388.         TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE] = {0};
  389.         va_list va;
  390.         va_start(va, szFormat);
  391.         _vsntprintf(szBuffer, 1024-1, szFormat, va);
  392.         va_end(va);
  393.         Log(szSrc, szFunc, uLine, eType, szBuffer);
  394.     }
  395. #ifdef _INC_COMDEF
  396.     VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType /*eType*/, _com_error &e)
  397.     {
  398.         TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE] = {0};
  399.         _sntprintf(szBuffer, 1024, _T("_com_error Code=%08X Meaning=%s Source=%s Description=%s"), 
  400.             e.Error(),
  401.             (LPCSTR)_bstr_t(e.ErrorMessage()),
  402.             (LPCSTR)e.Source(),
  403.             (LPCSTR)e.Description());
  404.         Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
  405.     }
  406. #endif
  407.     //Log HRESULT
  408.     VOID LogResult(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType /*eType*/const HRESULT hr)
  409.     {
  410.         TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE] = {0};
  411.         int iLen = _stprintf(szBuffer, _T("(0x%X):"), hr);
  412.         FormatMessage(
  413.             FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  414.             NULL,
  415.             hr,
  416.             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  417.             szBuffer + iLen,
  418.             CX_LOG_DEFAULT_FORMAT_SIZE - iLen - 3,
  419.             NULL
  420.             );
  421.         Log(szSrc, szFunc, uLine, CxLog::CX_LOG_ERROR, szBuffer);
  422.     }
  423.     VOID LogError(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType /*eType*/const DWORD dwError)
  424.     {
  425.         TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE] = {0};
  426.         int iLen = _stprintf(szBuffer, _T("(%d):"), dwError);
  427.         FormatMessage(
  428.             FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  429.             NULL,
  430.             dwError,
  431.             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  432.             szBuffer + iLen,
  433.             CX_LOG_DEFAULT_FORMAT_SIZE - iLen - 3,
  434.             NULL
  435.             );
  436.         Log(szSrc, szFunc, uLine, CxLog::CX_LOG_ERROR, szBuffer);
  437.     }
  438. #if defined(INC_VCL) && defined(__BORLANDC__)
  439.     VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType /*eType*/, Exception *e)
  440.     {
  441.     #ifdef _UNICODE
  442.         TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  443.         e->Message.WideChar(szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE);
  444.         Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
  445.     #else
  446.         Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, e->Message.c_str());
  447.     #endif
  448.     }
  449.     VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType /*eType*/, Exception &e)
  450.     {
  451.     #ifdef _UNICODE
  452.         TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  453.         e.Message.WideChar(szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE);
  454.         Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
  455.     #else
  456.         Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, e.Message.c_str());
  457.     #endif
  458.     }
  459. #endif
  460. #if (defined(_MFC_VER) && defined(__AFX_H__))
  461.     VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType /*eType*/, CException *e)
  462.     {
  463.         TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  464.         e->GetErrorMessage(szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE, NULL);
  465.         Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
  466.     }
  467.     VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType /*eType*/, CException &e)
  468.     {
  469.         TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  470.         e.GetErrorMessage(szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE, NULL);
  471.         Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
  472.     }
  473. #endif
  474.     VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType /*eType*/const std::exception *e)
  475.     {
  476.     #ifdef _UNICODE
  477.         TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  478.         MultiByteToWideChar(CP_ACP, 0, e->what(), -1, szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE);
  479.         Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
  480.     #else
  481.         Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, e->what());
  482.     #endif
  483.     }
  484.     VOID Log(LPCTSTR szSrc, LPCTSTR szFunc, const ULONG uLine, const EnumType /*eType*/const std::exception &e)
  485.     {
  486.     #ifdef _UNICODE
  487.         TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  488.         MultiByteToWideChar(CP_ACP, 0, e.what(), -1, szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE);
  489.         Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, szBuffer);
  490.     #else
  491.         Log(szSrc, szFunc, uLine, CxLog::CX_LOG_EXCEPTION, e.what());
  492.     #endif
  493.     }
  494.     VOID SetWnd(HWND hWnd)
  495.     {
  496.         _hWnd = hWnd;
  497.     }
  498. protected:
  499.     bool& _bAlive;
  500.     CRITICAL_SECTION _LogMutex;
  501.     std::list<Item*> _ItemList;
  502.     TCHAR _szFileName[MAX_PATH];
  503.     HANDLE _hThreadHandle, _LogHandle, _TerminateEvent;
  504.     HWND _hWnd;
  505.     virtual VOID Run()
  506.     {
  507.         HANDLE HandleArray[2];
  508.         HandleArray[0] = _LogHandle;
  509.         HandleArray[1] = _TerminateEvent;
  510.         for(;;)
  511.         {
  512.             DWORD ret = ::WaitForMultipleObjects(2, HandleArray, false, INFINITE);
  513.             if(ret == WAIT_OBJECT_0)
  514.             {
  515.                 HANDLE hHandle = ::CreateFile(
  516.                     GetLogFileName(),
  517.                     GENERIC_READ | GENERIC_WRITE ,
  518.                     FILE_SHARE_READ,
  519.                     NULL,
  520.                     OPEN_ALWAYS,
  521.                     FILE_ATTRIBUTE_NORMAL, 
  522.                     NULL
  523.                     );
  524.                 if(!hHandle)
  525.                     return;
  526.                 
  527.                 DWORD dwNumberOfBytesWritten;
  528.                 SetFilePointer(hHandle, 0, 0, FILE_END);
  529.                 try
  530.                 {
  531.                     Lock();
  532.                     while(_ItemList.size())
  533.                     {
  534.                         Item *p = _ItemList.front();
  535.                         TCHAR szBuffer[CX_LOG_DEFAULT_FORMAT_SIZE];
  536.                         ULONG uSize = 0;
  537.                         p->Format(szBuffer, CX_LOG_DEFAULT_FORMAT_SIZE, &uSize);
  538.                         WriteFile(hHandle, szBuffer, uSize*sizeof(TCHAR), &dwNumberOfBytesWritten, NULL);
  539.                         if(p->_pBin && p->_uBinSize)
  540.                         {
  541.                             ULONG uSize = 0;
  542.                             LPTSTR t = p->FormatBinary(p->_pBin, p->_uBinSize, NULL, 0,  &uSize);
  543.                             WriteFile(hHandle, t, uSize*sizeof(TCHAR), &dwNumberOfBytesWritten, NULL);
  544.                             delete []t;
  545.                         }
  546.                         _ItemList.pop_front();
  547.                         //p->_bLog = TRUE;
  548.                         delete p;
  549.                     }
  550.                     Unlock();
  551.                 }
  552.                 catch (...) 
  553.                 {
  554.                     Unlock();
  555.                 }
  556.                                 
  557.                 SetEndOfFile(hHandle);
  558.                 CloseHandle(hHandle);
  559.             }
  560.             if(ret == WAIT_OBJECT_0 + 1)
  561.                 break;
  562.         }   
  563.     }
  564. private:
  565.     CxLog(const CxLog&);
  566.     CxLog& operator=(CxLog&);
  567. #ifdef _MT
  568.     static UINT APIENTRY StaticThreadProc(LPVOID lpPara) //允许C多线程运行库
  569. #else
  570.     static DWORD WINAPI StaticThreadProc(LPVOID lpPara)
  571. #endif
  572.     {
  573.         ((CxLog*)(lpPara))->Run();
  574.     #ifdef _MT
  575.         ::_endthreadex(0);
  576.     #endif
  577.         return 0;
  578.     }
  579. };
  580. #define WIDEN2(x) L ## x
  581. #define WIDEN(x) WIDEN2(x)
  582. #define __WFILE__ WIDEN(__FILE__)
  583. #ifdef _UNICODE
  584.     #define __TFILE__ __WFILE__
  585. #else
  586.     #define __TFILE__ __FILE__
  587. #endif
  588. #if (_MSC_VER && _MSC_VER<=1200) || (__BORLANDC__) 
  589.     #define __FUNCTION__ NULL
  590.     #define __WFUNCTION__ NULL
  591. #else //_MSC_VER>1200 __GNUC__ __INTEL_COMPILER
  592.     #define __WFUNCTION__ WIDEN(__FUNCTION__)
  593. #endif
  594. #ifdef _UNICODE
  595.     #ifdef __GNUC__
  596.         #define __TFUNCTION__ WIDEN(__func__)
  597.     #else
  598.         #define __TFUNCTION__ __WFUNCTION__
  599.     #endif
  600. #else
  601.     #define __TFUNCTION__ __FUNCTION__
  602. #endif
  603. #define BASE_LOG(type, msg) CxLog::Instance().Log(__TFILE__, __TFUNCTION__, __LINE__, (type), (msg))
  604. #define LOG(msg) BASE_LOG(CxLog::CX_LOG_MESSAGE, (msg))
  605. #define LOG_WARN(msg) BASE_LOG(CxLog::CX_LOG_WARNING, (msg))
  606. #define LOGE(e) CxLog::Instance().Log(__TFILE__, __TFUNCTION__, __LINE__, CxLog::CX_LOG_EXCEPTION, (e))
  607. #define LOG_ERR(msg) BASE_LOG(CxLog::CX_LOG_ERROR, (msg))
  608. #define BASE_LOG_BIN(type, bin, size) CxLog::Instance().LogBin(__TFILE__, __TFUNCTION__, __LINE__, (type), (bin), (size))
  609. #define LOG_BIN(bin, size) BASE_LOG_BIN(CxLog::CX_LOG_MESSAGE, (bin), (size))
  610. #define LOG_WARN_BIN(bin, size) BASE_LOG_BIN(CxLog::CX_LOG_WARNING, (bin), (size))
  611. #define LOG_ERR_BIN(bin, size) BASE_LOG_BIN(CxLog::CX_LOG_ERROR, (bin), (size))
  612. #if __GNUC__ || __INTEL_COMPILER || _MSC_VER>1310
  613.     #define BASE_LOGN(type, msg, ...) CxLog::Instance().LogN(__TFILE__, __TFUNCTION__, __LINE__, (type), (msg), ##__VA_ARGS__)
  614.     #define LOGN(msg, ...) BASE_LOGN(CxLog::CX_LOG_MESSAGE, (msg), ##__VA_ARGS__)
  615.     #define LOGN_WARN(msg, ...) BASE_LOGN(CxLog::CX_LOG_WARNING, (msg), ##__VA_ARGS__)
  616.     #define LOGN_ERR(msg, ...) BASE_LOGN(CxLog::CX_LOG_ERROR, (msg), ##__VA_ARGS__)
  617. #endif
  618. #define PRE_LOG CxLog::Instance().LogN(__TFILE__, __TFUNCTION__, __LINE__, CxLog::CX_LOG_MESSAGE,
  619. #define LOG1(str, p1) PRE_LOG (str), (p1))
  620. #define LOG2(str, p1, p2) PRE_LOG (str), (p1), (p2))
  621. #define LOG3(str, p1, p2, p3) PRE_LOG (str), (p1), (p2), (p3))
  622. #define LOG4(str, p1, p2, p3, p4) PRE_LOG (str), (p1), (p2), (p3), (p4))
  623. #define LOG5(str, p1, p2, p3, p4, p5) PRE_LOG (str), (p1), (p2), (p3), (p4), (p5))
  624. #define LOG6(str, p1, p2, p3, p4, p5, p6) PRE_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6))
  625. #define LOG7(str, p1, p2, p3, p4, p5, p6, p7) PRE_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7))
  626. #define LOG8(str, p1, p2, p3, p4, p5, p6, p7, p8) PRE_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8))
  627. #define LOG9(str, p1, p2, p3, p4, p5, p6, p7, p8, p9) PRE_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9))
  628. #define PRE_T_LOG CxLog::Instance().LogN(__TFILE__, __TFUNCTION__, __LINE__, 
  629. #define LOG_T1(t, str, p1) PRE_T_LOG (t), (str), (p1))
  630. #define LOG_T2(t, str, p1, p2) PRE_T_LOG (t), (str), (p1), (p2))
  631. #define LOG_T3(t, str, p1, p2, p3) PRE_T_LOG (t), (str), (p1), (p2), (p3))
  632. #define LOG_T4(t, str, p1, p2, p3, p4) PRE_T_LOG (t), (str), (p1), (p2), (p3), (p4))
  633. #define LOG_T5(t, str, p1, p2, p3, p4, p5) PRE_T_LOG (t), (str), (p1), (p2), (p3), (p4), (p5))
  634. #define LOG_T6(t, str, p1, p2, p3, p4, p5, p6) PRE_T_LOG (t), (str), (p1), (p2), (p3), (p4), (p5), (p6))
  635. #define LOG_T7(t, str, p1, p2, p3, p4, p5, p6, p7) PRE_T_LOG (t), (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7))
  636. #define LOG_T8(t, str, p1, p2, p3, p4, p5, p6, p7, p8) PRE_T_LOG (t), (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8))
  637. #define LOG_T9(t, str, p1, p2, p3, p4, p5, p6, p7, p8, p9) PRE_T_LOG (t), (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9))
  638. #define PRE_WARN_LOG CxLog::Instance().LogN(__TFILE__, __TFUNCTION__, __LINE__, CxLog::CX_LOG_WARNING, 
  639. #define LOG_WARN1(str, p1) PRE_WARN_LOG (str), (p1))
  640. #define LOG_WARN2(str, p1, p2) PRE_WARN_LOG (str), (p1), (p2))
  641. #define LOG_WARN3(str, p1, p2, p3) PRE_WARN_LOG (str), (p1), (p2), (p3))
  642. #define LOG_WARN4(str, p1, p2, p3, p4) PRE_WARN_LOG (str), (p1), (p2), (p3), (p4))
  643. #define LOG_WARN5(str, p1, p2, p3, p4, p5) PRE_WARN_LOG (str), (p1), (p2), (p3), (p4), (p5))
  644. #define LOG_WARN6(str, p1, p2, p3, p4, p5, p6) PRE_WARN_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6))
  645. #define LOG_WARN7(str, p1, p2, p3, p4, p5, p6, p7) PRE_WARN_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7))
  646. #define LOG_WARN8(str, p1, p2, p3, p4, p5, p6, p7, p8) PRE_WARN_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8))
  647. #define LOG_WARN9(str, p1, p2, p3, p4, p5, p6, p7, p8, p9) PRE_WARN_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9))
  648. #define PRE_EXCEPTION_LOG CxLog::Instance().LogN(__TFILE__, __TFUNCTION__, __LINE__, CxLog::CX_LOG_EXCEPTION,
  649. #define LOG_EXCEPTION1(str, p1) PRE_EXCEPTION_LOG (str), (p1))
  650. #define LOG_EXCEPTION2(str, p1, p2) PRE_EXCEPTION_LOG (str), (p1), (p2))
  651. #define LOG_EXCEPTION3(str, p1, p2, p3) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3))
  652. #define LOG_EXCEPTION4(str, p1, p2, p3, p4) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3), (p4))
  653. #define LOG_EXCEPTION5(str, p1, p2, p3, p4, p5) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3), (p4), (p5))
  654. #define LOG_EXCEPTION6(str, p1, p2, p3, p4, p5, p6) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6))
  655. #define LOG_EXCEPTION7(str, p1, p2, p3, p4, p5, p6, p7) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7))
  656. #define LOG_EXCEPTION8(str, p1, p2, p3, p4, p5, p6, p7, p8) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8))
  657. #define LOG_EXCEPTION9(str, p1, p2, p3, p4, p5, p6, p7, p8, p9) PRE_EXCEPTION_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9))
  658. #define PRE_ERR_LOG CxLog::Instance().LogN(__TFILE__, __TFUNCTION__, __LINE__, CxLog::CX_LOG_ERROR,
  659. #define LOG_ERR1(str, p1) PRE_ERR_LOG (str), (p1))
  660. #define LOG_ERR2(str, p1, p2) PRE_ERR_LOG (str), (p1), (p2))
  661. #define LOG_ERR3(str, p1, p2, p3) PRE_ERR_LOG (str), (p1), (p2), (p3))
  662. #define LOG_ERR4(str, p1, p2, p3, p4) PRE_ERR_LOG (str), (p1), (p2), (p3), (p4))
  663. #define LOG_ERR5(str, p1, p2, p3, p4, p5) PRE_ERR_LOG (str), (p1), (p2), (p3), (p4), (p5))
  664. #define LOG_ERR6(str, p1, p2, p3, p4, p5, p6) PRE_ERR_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6))
  665. #define LOG_ERR7(str, p1, p2, p3, p4, p5, p6, p7) PRE_ERR_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7))
  666. #define LOG_ERR8(str, p1, p2, p3, p4, p5, p6, p7, p8) PRE_ERR_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8))
  667. #define LOG_ERR9(str, p1, p2, p3, p4, p5, p6, p7, p8, p9) PRE_ERR_LOG (str), (p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9))
  668. #define LOG_LAST_ERROR() CxLog::Instance().LogError(__TFILE__, __TFUNCTION__, __LINE__, CxLog::CX_LOG_ERROR, GetLastError())
  669. #define LOG_LE LOG_LAST_ERROR
  670. #define CHECK_LAST_ERROR() do /
  671. { /
  672.     DWORD dwErr = GetLastError(); /
  673.     if(dwErr) /
  674.         CxLog::Instance().LogError(__TFILE__, __TFUNCTION__, __LINE__, CxLog::CX_LOG_ERROR, dwErr); /
  675. } /
  676. while (0)
  677. #define CHECK_LE CHECK_LAST_ERROR
  678. #define LOG_HR(hr) CxLog::Instance().LogResult(__TFILE__, __TFUNCTION__, __LINE__, CxLog::CX_LOG_ERROR, (hr))
  679. #define CHECK_HR(hr) do /
  680. { /
  681.     if(FAILED(hr)) /
  682.         LOG_HR(hr); /
  683. } /
  684. while (0)
  685. #endif //_CX_LOG_H_ 

 

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值