CLogFile.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. #include "Logstdafx.h"
  2. #include "CLogFile.h"
  3. CCLogFile::CCLogFile(LPCTSTR szFileName, bool bLogNeedManage)
  4. :m_bFileNameCommited(!bLogNeedManage)
  5. {
  6. SYSTEMTIME __sTime;
  7. ::GetLocalTime(&__sTime);
  8. if (NULL != szFileName)
  9. {
  10. m_szFile = szFileName;
  11. CString str;
  12. str.Format("%s %04d%02d%02d%02d%02d%02d%03d.log", m_szFile, __sTime.wYear, __sTime.wMonth, __sTime.wDay, __sTime.wHour, __sTime.wMinute, __sTime.wSecond, __sTime.wMilliseconds);
  13. m_szFile = str;
  14. }
  15. else
  16. {
  17. m_szFile = "hc_trace";
  18. }
  19. }
  20. CCLogFile::~CCLogFile()
  21. {
  22. }
  23. /**
  24. 纪录操作处理信息,以及信息对应的文件名和所在行,其他同C的printf用法
  25. 比如在A.CPP文件的第11行进行如下调用:
  26. TraceProgress( __FILE__, __LINE__, "hi test[%d]", 3 );
  27. 则相当于:
  28. Print( TRACER_OPE_PROGRESS, "%s:%d hi test[%d]", "A.CPP", 11, 3 );
  29. @param szFile 信息对应的源文件名
  30. @param lLine 信息所对应的行数
  31. @param szData 格式字符串
  32. @param ... 后续内容
  33. @return 无
  34. @see Print(TRACER_TYPE nType, LPCTSTR szData, ...)
  35. */
  36. ///@endcond
  37. ///@cond CHS
  38. /**
  39. Log process type information
  40. example:
  41. TraceProgress( __FILE__, __LINE__, "hi test[%d]", 3 );
  42. @param szFile File name
  43. @param lLine Program line
  44. @param szData Format string
  45. @param ... Other param
  46. */
  47. void CCLogFile::TraceProgress(LPCTSTR szFile, long lLine, LPCTSTR szData, ...)
  48. {
  49. CString str;
  50. str.Format("%s(%ld) ", szFile, lLine);
  51. str.Append(szData);
  52. va_list pArgList;
  53. va_start(pArgList, szData);
  54. PrintV(TRACER_OPE_PROGRESS, str, pArgList);
  55. va_end(pArgList);
  56. }
  57. /**
  58. 纪录错误信息,以及信息对应的文件名和所在行,其他同C的printf用法
  59. 比如在A.CPP文件的第11行进行如下调用:
  60. TraceError( __FILE__, __LINE__, "hi test[%d]", 3 );
  61. 则相当于:
  62. Print( TRACER_OPE_ERROR, "%s:%d hi test[%d]", "A.CPP", 11, 3 );
  63. @param szFile 信息对应的源文件名
  64. @param lLine 信息所对应的行数
  65. @param szData 格式字符串
  66. @param ... 后续内容
  67. @return 无
  68. @see Print(TRACER_TYPE nType, LPCTSTR szData, ...)
  69. */
  70. ///@endcond
  71. ///@cond ENG
  72. /**
  73. Log error information
  74. example:
  75. TraceError( __FILE__, __LINE__, "hi test[%d]", 3 );
  76. @param szFile File name
  77. @param lLine Program line
  78. @param szData Format string
  79. @param ... Other param
  80. */
  81. ///@endcond
  82. void CCLogFile::TraceError(LPCTSTR szFile, long lLine, LPCTSTR szData, ...)
  83. {
  84. CString str;
  85. str.Format("%s(%ld) ", szFile, lLine);
  86. str.Append(szData);
  87. va_list pArgList;
  88. va_start(pArgList, szData);
  89. PrintV(TRACER_OPE_ERROR, str, pArgList);
  90. va_end(pArgList);
  91. }
  92. /**
  93. 纪录例外信息,以及信息对应的文件名和所在行,其他同C的printf用法
  94. 比如在A.CPP文件的第11行进行如下调用:
  95. TraceException( __FILE__, __LINE__, "hi test[%d]", 3 );
  96. 则相当于:
  97. Print( TRACER_OPE_EXCEPTION, "%s:%d hi test[%d]", "A.CPP", 11, 3 );
  98. @param szFile 信息对应的源文件名
  99. @param lLine 信息所对应的行数
  100. @param szData 格式字符串
  101. @param ... 后续内容
  102. @return 无
  103. @see Print(TRACER_TYPE nType, LPCTSTR szData, ...)
  104. */
  105. ///@endcond
  106. ///@cond ENG
  107. /**
  108. Log exception information
  109. example:
  110. TraceException( __FILE__, __LINE__, "hi test[%d]", 3 );
  111. @param szFile File name
  112. @param lLine Program line
  113. @param szData Format string
  114. @param ... Other param
  115. */
  116. ///@endcond
  117. void CCLogFile::TraceException(LPCTSTR szFile, long lLine, LPCTSTR szData, ...)
  118. {
  119. CString str;
  120. str.Format("%s(%ld) ", szFile, lLine);
  121. str.Append(szData);
  122. va_list pArgList;
  123. va_start(pArgList, szData);
  124. PrintV(TRACER_OPE_EXCEPTION, str, pArgList);
  125. va_end(pArgList);
  126. }
  127. /**
  128. Log normal information
  129. example:
  130. TraceMessage( __FILE__, __LINE__, "hi test[%d]", 3 );
  131. @param szFile File name
  132. @param lLine Program line
  133. @param szData Format string
  134. @param ... Other param
  135. */
  136. ///@endcond
  137. void CCLogFile::TraceMessage(LPCTSTR szFile, long lLine, LPCTSTR szData, ...)
  138. {
  139. CString str;
  140. str.Format("%s(%ld) ", szFile, lLine);
  141. str.Append(szData);
  142. va_list pArgList;
  143. va_start(pArgList, szData);
  144. PrintV(TRACER_OPE_MESSAGE, str, pArgList);
  145. va_end(pArgList);
  146. }
  147. /**
  148. 记录二进制数据
  149. @param szHead 信息头
  150. @param pbyData 数据
  151. @param nLen 数据长度
  152. */
  153. ///@endcond
  154. ///@cond ENG
  155. /**
  156. Log binary data
  157. @param szHead Information
  158. @param pbyData Binary data
  159. @param nLen Data length
  160. */
  161. ///@endcond
  162. void CCLogFile::LogBinaryData(LPCTSTR szHead, BYTE* pbyData, UINT nLen)
  163. {
  164. SYSTEMTIME __sTime;
  165. ::GetLocalTime(&__sTime);
  166. CString str;
  167. str.Format("%s.%04d%02d%02d", m_szFile, __sTime.wYear, __sTime.wMonth, __sTime.wDay);
  168. CSingleLock lock(&this->m_csBinLog, TRUE);
  169. HANDLE hLog = this->CreateLogFile(str);
  170. if (INVALID_HANDLE_VALUE == hLog)
  171. {
  172. return;
  173. }
  174. if (!szHead)
  175. {
  176. szHead = __T(" ");
  177. }
  178. str.Format("%02d:%02d:%02d.%03d|%4d| ---> %s\r\n ----------------------------------------------------------------------------\r\n", __sTime.wHour, __sTime.wMinute, __sTime.wSecond, __sTime.wMilliseconds
  179. , GetCurrentThreadId(), szHead);
  180. DWORD iLen = str.GetLength();
  181. DWORD unBytesWritten = 0;
  182. WriteFile(hLog, str, iLen, &unBytesWritten, NULL);
  183. int iSeq = 0;
  184. CString strBin;
  185. const int BYTES_PER_LINE = 16;
  186. const int SEQ_LEN = 6;
  187. char szWkBuf[128], szCharBuf[BYTES_PER_LINE + 1];
  188. for (unsigned int iIndex = 0; iIndex < nLen; )
  189. {
  190. //000001: 12 34 56 78 AB CD EF 12 34 56 78 12 12 12 12 12 ...............
  191. sprintf(szWkBuf, " %0*d: ", SEQ_LEN, iSeq++);
  192. strBin = szWkBuf;
  193. memset(szCharBuf, 0, sizeof(szCharBuf));
  194. for (unsigned int i = 0; i < BYTES_PER_LINE && iIndex < nLen; ++i)
  195. {
  196. sprintf(szWkBuf, "%02X ", pbyData[iIndex]);
  197. strBin += szWkBuf;
  198. sprintf(szCharBuf + strlen(szCharBuf), "%c", pbyData[iIndex] < 0x20 ? '.' : pbyData[iIndex]);
  199. ++iIndex;
  200. }
  201. if (iIndex % 16)
  202. {
  203. strBin += CString(' ', 3 * (16 - iIndex % 16));
  204. }
  205. str.Format("%s; %s\r\n", strBin, szCharBuf);
  206. iLen = str.GetLength();
  207. unBytesWritten = 0;
  208. WriteFile(hLog, str, iLen, &unBytesWritten, NULL);
  209. }
  210. str = " ----------------------------------------------------------------------------\r\n\r\n";
  211. iLen = str.GetLength();
  212. WriteFile(hLog, str, iLen, &unBytesWritten, NULL);
  213. if (INVALID_HANDLE_VALUE != hLog)
  214. {
  215. CloseHandle(hLog);
  216. }
  217. }
  218. /**
  219. 采用va_list形式的可变参数打印
  220. @param nType 纪录类型
  221. - TRACER_OPE_PROGRESS
  222. - TRACER_OPE_ERROR
  223. - TRACER_OPE_EXCEPTION
  224. - TRACER_OPE_MESSAGE
  225. @param pszFormat 打印格式
  226. @param pArgList 可变参数列表指针
  227. */
  228. ///@endcond
  229. //@cond ENG
  230. /**
  231. Use va_list to Log information
  232. @param nType Information type
  233. - TRACER_OPE_PROGRESS
  234. - TRACER_OPE_ERROR
  235. - TRACER_OPE_EXCEPTION
  236. - TRACER_OPE_MESSAGE
  237. @param pszFormat Format string
  238. @param pArgList arguments
  239. */
  240. ///@endcond
  241. void CCLogFile::PrintV(TRACER_TYPE nType, LPCTSTR pszFormat, va_list pArgList)
  242. {
  243. CString strFormat;
  244. switch (nType)
  245. {
  246. case TRACER_OPE_PROGRESS:
  247. strFormat = TRACER_OPE_PROGRESS_STR;
  248. break;
  249. case TRACER_OPE_ERROR:
  250. strFormat = TRACER_OPE_ERROR_STR;
  251. break;
  252. case TRACER_OPE_EXCEPTION:
  253. strFormat = TRACER_OPE_EXCEPTION_STR;
  254. break;
  255. case TRACER_OPE_MESSAGE:
  256. strFormat = TRACER_OPE_MESSAGE_STR;
  257. break;
  258. default:
  259. strFormat = ("$$ UNKONW: ");
  260. }
  261. strFormat.Append(pszFormat);
  262. PrintV(strFormat, pArgList);
  263. }
  264. //@cond CHS
  265. /**
  266. 采用va_list形式的可变参数打印
  267. @param pszFormat 打印格式
  268. @param pArgList 可变参数列表指针
  269. */
  270. ///@endcond
  271. //@cond ENG
  272. /**
  273. Use va_list to Log information
  274. @param pszFormat Format string
  275. @param pArgList arguments
  276. */
  277. ///@endcond
  278. void CCLogFile::PrintV(LPCTSTR pszFormat, va_list pArgList)
  279. {
  280. CString str;
  281. str.FormatV(pszFormat, pArgList);
  282. str.Append(("\r\n"));
  283. //TRACE( str );
  284. LogFile(str);
  285. }
  286. /**
  287. 生成文件
  288. @param szData 数据
  289. */
  290. ///@endcond
  291. ///@cond ENG
  292. ///Log file
  293. ///@param szData Data need log to file
  294. ///@endcond
  295. void CCLogFile::LogFile(LPCTSTR szData)
  296. {
  297. SYSTEMTIME __sTime;
  298. ::GetLocalTime(&__sTime);
  299. /*
  300. CString str;
  301. str.Format(L"%s %04d%02d%02d%02d:%02d:%02d.%03d.log", m_szFile, __sTime.wYear, __sTime.wMonth, __sTime.wDay, __sTime.wHour, __sTime.wMinute, __sTime.wSecond, __sTime.wMilliseconds); */
  302. CString str;
  303. str.Format("%s", m_szFile);
  304. CSingleLock lock(&this->m_csLog, TRUE);
  305. HANDLE hLog = this->CreateLogFile(str);
  306. if (INVALID_HANDLE_VALUE == hLog)
  307. {
  308. return;
  309. }
  310. str.Format("%02d:%02d:%02d.%03d | ", __sTime.wHour, __sTime.wMinute, __sTime.wSecond, __sTime.wMilliseconds);
  311. // str = "";
  312. DWORD iLen = str.GetLength();
  313. DWORD unBytesWritten = 0;
  314. WriteFile(hLog, str, iLen, &unBytesWritten, NULL);
  315. iLen = (DWORD)_tcslen(szData) * sizeof(TCHAR);
  316. WriteFile(hLog, szData, iLen, &unBytesWritten, NULL);
  317. OutputDebugString(szData);
  318. if (INVALID_HANDLE_VALUE != hLog)
  319. {
  320. CloseHandle(hLog);
  321. }
  322. }
  323. /**
  324. 创建日志文件
  325. /@param str 文件名
  326. */
  327. ///@endcond
  328. ///@cond ENG
  329. ///Create log file
  330. ///@param str File Name
  331. ///@endcond
  332. HANDLE CCLogFile::CreateLogFile(const CString& str)
  333. {
  334. HANDLE hLog = INVALID_HANDLE_VALUE;
  335. hLog = CreateFile(str, GENERIC_READ | GENERIC_WRITE,
  336. FILE_SHARE_READ | FILE_SHARE_WRITE,
  337. NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
  338. NULL);
  339. if (INVALID_HANDLE_VALUE == hLog)
  340. {
  341. if (CheckFilePath(str))
  342. {
  343. hLog = CreateFile(str, GENERIC_READ | GENERIC_WRITE,
  344. FILE_SHARE_READ | FILE_SHARE_WRITE,
  345. NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
  346. NULL);
  347. }
  348. }
  349. if (INVALID_HANDLE_VALUE != hLog)
  350. {
  351. SetFilePointer(hLog, 0, NULL, FILE_END);
  352. }
  353. if (!this->m_bFileNameCommited)
  354. {
  355. this->m_bFileNameCommited = true;
  356. }
  357. return hLog;
  358. }
  359. bool CCLogFile::CheckFilePath(const CString& strPath)
  360. {
  361. if (strPath.IsEmpty())
  362. {
  363. return false;
  364. }
  365. int iPos = strPath.ReverseFind('\\');
  366. if (iPos < 0)
  367. {
  368. iPos = strPath.ReverseFind('/');
  369. if (iPos < 0)
  370. {
  371. return false;
  372. }
  373. }
  374. CString cstrPath = strPath.Left(iPos);
  375. return TRUE;
  376. }
  377. void CUtilityTools::WaitingWithEventLoop(int iWaitTime)
  378. {
  379. /* if (a_bWithEventLoop)
  380. {
  381. auto* pApp = AfxGetApp();
  382. if (pApp)
  383. {
  384. AMICS::UI::CAMICSAppBase* pBaseApp = dynamic_cast<AMICS::UI::CAMICSAppBase*>(pApp);
  385. if (pBaseApp)
  386. {
  387. pBaseApp->WaitingWithEventLoop(a_nMilliseconds);
  388. return;
  389. }
  390. }
  391. }*/
  392. //LogTrace(_T("Waiting %d milliseconds ..."), a_nMilliseconds);
  393. #pragma warning(disable: 28159)
  394. DWORD nStart = GetTickCount();
  395. DWORD nEnd = nStart;
  396. do
  397. {
  398. nEnd = GetTickCount();
  399. } while (nEnd >= nStart && nEnd <= (nStart + iWaitTime + 1));
  400. #pragma warning(default: 28159)
  401. }