Logger.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. #include "stdafx.h"
  2. #include "Logger.h"
  3. FileModeEnum Logger::m_eFileMode = Default_Mode;
  4. #if !(defined(TWINKLE_LOGGER_VERSION) && TWINKLE_LOGGER_VERSION == 2)
  5. Logger* Logger::m_pLogger = NULL;
  6. CRITICAL_SECTION Logger::s_cs;
  7. Logger::CAutoWriteHelper Logger::helper;
  8. int Logger::bInitialized = 0;
  9. tstring Logger::m_strLogDirOrFilePath = DEFAULT_LOG_NAME;
  10. #endif
  11. #if !(defined(TWINKLE_LOGGER_VERSION) && TWINKLE_LOGGER_VERSION == 2)
  12. Logger::Logger(void)
  13. :m_bWriteRealTime(true),
  14. m_fileName(DEFAULT_LOG_NAME),
  15. m_usWriteStatus(LEVEL_OVERALL_WRITEABLE),
  16. m_bufCurLen(0),
  17. hMutexForBuffer(NULL),
  18. hEventWrite(NULL)
  19. {
  20. QueryPerformanceFrequency(&m_liPerfFreq);
  21. m_strBuffer = TLOG_TEXT("");
  22. SetFileWriteMode(Day_Seperated_Mode);
  23. hMutexForBuffer = CreateMutex(NULL, FALSE, LPCTSTR("iGobalBuffer"));
  24. if(!m_bWriteRealTime)
  25. {
  26. hEventWrite = CreateEvent(NULL, TRUE, FALSE, TLOG_TEXT("iGobalTimerWriteEvent"));
  27. }
  28. }
  29. #else
  30. Logger::Logger(void)
  31. :m_name(nullptr),
  32. m_bWriteRealTime(true),
  33. m_fileName(nullptr),
  34. m_usWriteStatus(LEVEL_NONE_WRITEABLE),
  35. m_bufCurLen(0),
  36. hMutexForBuffer(NULL),
  37. hEventWrite(NULL)
  38. {
  39. QueryPerformanceFrequency(&m_liPerfFreq);
  40. m_strBuffer = TLOG_TEXT("");
  41. SetFileWriteMode(Day_Seperated_Mode);
  42. hMutexForBuffer = CreateMutex(NULL, FALSE, LPCTSTR("iGobalBuffer"));
  43. if(!m_bWriteRealTime)
  44. {
  45. hEventWrite = CreateEvent(NULL, TRUE, FALSE, TLOG_TEXT("iGobalTimerWriteEvent"));
  46. }
  47. }
  48. Logger::Logger(const tstring& name, const tchar* lpszLogSummaryDir)
  49. :m_name(name),
  50. m_bWriteRealTime(true),
  51. m_fileName(name),
  52. m_usWriteStatus(LEVEL_OVERALL_WRITEABLE),
  53. m_bufCurLen(0),
  54. hMutexForBuffer(NULL),
  55. hEventWrite(NULL)
  56. {
  57. InitializeCriticalSection(&s_cs);
  58. QueryPerformanceFrequency(&m_liPerfFreq);
  59. m_strBuffer = TLOG_TEXT("");
  60. SetFileWriteMode(Module_Seperated_Mode, lpszLogSummaryDir);
  61. tstring mtxName(name);
  62. mtxName += "iGobalBuffer";
  63. hMutexForBuffer = CreateMutex(NULL, FALSE, mtxName.c_str());
  64. if(!m_bWriteRealTime) {
  65. mtxName = name + "TimerWriteEvent";
  66. hEventWrite = CreateEvent(NULL, TRUE, FALSE, mtxName.c_str());
  67. }
  68. printf("-------------------------Logger::Contrustor: %s: \n", m_name.c_str());
  69. }
  70. #endif
  71. Logger::~Logger(void)
  72. {
  73. WaitForSingleObject(hMutexForBuffer, INFINITE);
  74. if(m_strBuffer.length() > 0)
  75. {
  76. bool retFlag = false;
  77. if(m_eFileMode == Day_Seperated_Mode)
  78. {
  79. m_fileName = GetCustomTime(For_File_Type);
  80. }
  81. retFlag = WriteToFile(m_strBuffer);
  82. if(retFlag)
  83. {
  84. m_strBuffer = TLOG_TEXT("");
  85. m_bufCurLen = 0;
  86. }
  87. }
  88. ReleaseMutex(hMutexForBuffer);
  89. if(hMutexForBuffer && hMutexForBuffer != INVALID_HANDLE_VALUE)
  90. {
  91. CloseHandle(hMutexForBuffer);
  92. hMutexForBuffer = NULL;
  93. }
  94. if(hEventWrite && hEventWrite != INVALID_HANDLE_VALUE)
  95. {
  96. CloseHandle(hEventWrite);
  97. hEventWrite = NULL;
  98. }
  99. //TODO: Bug thirsty to fix !!! -Josephus@2017913 8:29:40
  100. #if !(defined(TWINKLE_LOGGER_VERSION) && TWINKLE_LOGGER_VERSION == 2)
  101. //bInitialized = 0;
  102. #else
  103. DeleteCriticalSection(&s_cs);
  104. #endif
  105. }
  106. tstring Logger::GetCustomTime(DateTypeEnum type)
  107. {
  108. tchar strTime[MAX_TIME_LEN] = {0};
  109. time_t now;
  110. time(&now);
  111. tm *pTm = new tm;
  112. localtime_s(pTm, &now);
  113. if(type == For_File_Type)
  114. {
  115. _tcsftime(strTime, MAX_TIME_LEN*sizeof(tchar), TLOG_TEXT("%Y%m%d.log"), pTm);
  116. #ifdef LAZY_MODEL
  117. #ifndef UNICODE
  118. if(_access(m_strLogDirOrFilePath.c_str(), 0) == -1)
  119. #else
  120. char tlsDirectory[MAX_PATH] = {0};
  121. int nt = WideCharToMultiByte(CP_ACP, 0, m_strLogDirOrFilePath.c_str(),
  122. -1, tlsDirectory, MAX_PATH, NULL, NULL);
  123. if(_access(tlsDirectory, 0) == -1)
  124. #endif
  125. {
  126. CreateDirectory(m_strLogDirOrFilePath.c_str(), NULL);
  127. }
  128. #endif
  129. return (m_strLogDirOrFilePath + TLOG_TEXT("\\") + strTime);
  130. }
  131. else if(type == For_Record_Type)
  132. {
  133. _tcsftime(strTime, MAX_TIME_LEN*sizeof(tchar), TLOG_TEXT("[%Y/%m/%d %H:%M:%S] "), pTm);
  134. return tstring(strTime);
  135. }
  136. return TLOG_TEXT("");
  137. }
  138. tstring Logger::GetTimeOfDay()
  139. {
  140. FILETIME time;
  141. double timed;
  142. tchar strTime[MAX_TIME_LEN] = {0};
  143. GetSystemTimeAsFileTime( &time );
  144. // Apparently Win32 has units of 1e-7 sec (tenths of microsecs)
  145. // 4294967296 is 2^32, to shift high word over
  146. // 11644473600 is the number of seconds between
  147. // the Win32 epoch 1601-Jan-01 and the Unix epoch 1970-Jan-01
  148. // Tests found floating point to be 10x faster than 64bit int math.
  149. timed = ((time.dwHighDateTime * 4294967296e-7) - 11644473600.0) +
  150. (time.dwLowDateTime * 1e-7);
  151. tm *pTm = new tm;
  152. long temp = (long) timed;
  153. time_t clock = (long) timed;
  154. long appendix = (long) ((timed - temp) * 1e6);
  155. localtime_s(pTm, &clock);
  156. if(m_eFileMode == Day_Seperated_Mode || m_eFileMode == Module_Seperated_Mode)
  157. {
  158. _tcsftime(strTime, MAX_TIME_LEN, TLOG_TEXT("[%H:%M:%S"), pTm);
  159. }
  160. else
  161. {
  162. _tcsftime(strTime, MAX_TIME_LEN, TLOG_TEXT("[%Y/%m/%d %H:%M:%S"), pTm);
  163. }
  164. int nowLen = _tcslen(strTime);
  165. _stprintf_s(strTime+nowLen, MAX_TIME_LEN-nowLen, TLOG_TEXT(",%03d] "), appendix / 1000);
  166. //
  167. //int appendix2 = appendix % 1000;
  168. //sprintf_s(strTime+nowLen, MAX_TIME_LEN-nowLen, ",%03d.%03d] ", appendix / 1000, appendix2);
  169. return tstring(strTime);
  170. }
  171. void Logger::Trace(tstring strInfo)
  172. {
  173. bool retFlag = false;
  174. WaitForSingleObject(hMutexForBuffer, INFINITE);
  175. m_strBuffer += strInfo;
  176. m_strBuffer += TLOG_TEXT("\r\n");
  177. //Compatable for RVC framework
  178. //m_strBuffer += strInfo;
  179. if(m_bWriteRealTime || m_strBuffer.length() > MAX_INFOR_LEN)
  180. {
  181. if(m_eFileMode == Day_Seperated_Mode || m_eFileMode == Module_Seperated_Mode)
  182. {
  183. m_fileName = GetCustomTime(For_File_Type);
  184. }
  185. //MessageBox(NULL, TLOG_TEXT(m_fileName.c_str()),
  186. // TLOG_TEXT(""), MB_ICONINFORMATION | MB_OK);
  187. retFlag = WriteToFile(m_strBuffer);
  188. if(retFlag)
  189. {
  190. m_strBuffer = TLOG_TEXT("");
  191. m_bufCurLen = 0;
  192. }
  193. }
  194. ReleaseMutex(hMutexForBuffer);
  195. }
  196. #if !(defined(TWINKLE_LOGGER_VERSION) && TWINKLE_LOGGER_VERSION == 2)
  197. Logger* Logger::GetInstance()
  198. {
  199. EnterCriticalSection(&s_cs);
  200. if(m_pLogger == NULL)
  201. {
  202. m_pLogger = new Logger();
  203. //if(m_pLogger)
  204. //{
  205. // unsigned int threadID = 0;
  206. // HANDLE threadHD = (HANDLE)_beginthreadex(NULL, 0, Logger::TimerWriteProc, m_pLogger, 0, &threadID);
  207. // if(threadHD && threadHD != INVALID_HANDLE_VALUE)
  208. // {
  209. // CloseHandle(threadHD);
  210. // }
  211. //}
  212. }
  213. LeaveCriticalSection(&s_cs);
  214. return m_pLogger;
  215. }
  216. void Logger::InitLog(FileModeEnum eMode, const tchar* lpszDir)
  217. {
  218. if(bInitialized == 0)
  219. {
  220. InitializeCriticalSection(&s_cs);
  221. SetFileWriteMode(eMode, lpszDir);
  222. bInitialized = 1;
  223. }
  224. }
  225. void Logger::ReleaseLog()
  226. {
  227. if(bInitialized)
  228. {
  229. DeleteCriticalSection(&s_cs);
  230. bInitialized = 0;
  231. }
  232. }
  233. void Logger::EndLog()
  234. {
  235. if(m_pLogger != NULL)
  236. {
  237. delete m_pLogger;
  238. m_pLogger = NULL;
  239. }
  240. }
  241. #endif
  242. void Logger::SetFileWriteMode(FileModeEnum eMode, const tchar* lpszDir)
  243. {
  244. tchar fileName[MAX_PATH] = {0};
  245. if(eMode == Single_File_Mode) {
  246. if(lpszDir == NULL || _tcslen(lpszDir) <= 0) {
  247. if(GetCurExeNameOrPath(fileName, MAX_PATH, MODE_FILENAME_WITH_PATH) != -1) {
  248. _tcscat_s(fileName, MAX_PATH*sizeof(tchar), TLOG_TEXT("_log.txt"));
  249. m_strLogDirOrFilePath = fileName;
  250. m_eFileMode = Single_File_Mode;
  251. #if !(defined(TWINKLE_LOGGER_VERSION) && TWINKLE_LOGGER_VERSION == 2)
  252. if(m_pLogger != NULL && m_pLogger->RefleshFileName()){;}
  253. #endif
  254. return;
  255. }
  256. }
  257. else {
  258. if(GetCurExeNameOrPath(fileName, MAX_PATH, MODE_FILENAME_ONLY) != -1) {
  259. _tcscat_s(fileName, MAX_PATH*sizeof(tchar), TLOG_TEXT("_log.txt"));
  260. m_strLogDirOrFilePath = lpszDir;
  261. const tchar* pchSuffix = _tcsrchr(lpszDir, TLOG_TEXT('\\'));
  262. if(pchSuffix == NULL || pchSuffix[1] != '\0') {
  263. m_strLogDirOrFilePath += tstring(TLOG_TEXT("\\"));
  264. }
  265. m_strLogDirOrFilePath += fileName;
  266. m_eFileMode = Single_File_Mode;
  267. #if !(defined(TWINKLE_LOGGER_VERSION) && TWINKLE_LOGGER_VERSION == 2)
  268. if(m_pLogger != NULL && m_pLogger->RefleshFileName()){;}
  269. #endif
  270. return;
  271. }
  272. }
  273. }
  274. else if(eMode == Day_Seperated_Mode)
  275. {
  276. if(lpszDir == NULL || _tcslen(lpszDir) <= 0) {
  277. if(GetCurExeNameOrPath(fileName, MAX_PATH, MODE_DIRECTORY) != -1) {
  278. m_strLogDirOrFilePath = tstring(fileName) + TLOG_TEXT("LogFiles");
  279. }
  280. } else {
  281. const tchar* pchSuffix = _tcsrchr(lpszDir, TLOG_TEXT('\\'));
  282. if(pchSuffix != NULL && pchSuffix[1] == '\0') {
  283. _tcscpy_s(fileName, MAX_PATH*sizeof(tchar), lpszDir);
  284. fileName[_tcslen(fileName)-1] = TLOG_TEXT('\0');
  285. m_strLogDirOrFilePath = tstring(fileName);
  286. } else {
  287. m_strLogDirOrFilePath = lpszDir;
  288. }
  289. //MessageBox(NULL, TLOG_TEXT(m_strLogDirOrFilePath.c_str()),
  290. // TLOG_TEXT(""), MB_ICONINFORMATION | MB_OK);
  291. }
  292. #ifndef LAZY_MODEL
  293. #ifndef UNICODE
  294. if(_access(m_strLogDirOrFilePath.c_str(), 0) == -1)
  295. #else
  296. char tlsDirectory[MAX_PATH] = {0};
  297. int nt = WideCharToMultiByte(CP_ACP, 0, m_strLogDirOrFilePath.c_str(),
  298. -1, tlsDirectory, MAX_PATH, NULL, NULL);
  299. if(_access(tlsDirectory, 0) == -1)
  300. #endif
  301. {
  302. CreateDirectory(m_strLogDirOrFilePath.c_str(), NULL);
  303. }
  304. #endif
  305. m_eFileMode = Day_Seperated_Mode;
  306. }
  307. else if(eMode == Default_Mode)
  308. {
  309. m_eFileMode = Default_Mode;
  310. m_strLogDirOrFilePath = DEFAULT_LOG_NAME;
  311. #if !(defined(TWINKLE_LOGGER_VERSION) && TWINKLE_LOGGER_VERSION == 2)
  312. if(m_pLogger != NULL && m_pLogger->RefleshFileName()){;}
  313. #endif
  314. }
  315. #if (defined(TWINKLE_LOGGER_VERSION) && TWINKLE_LOGGER_VERSION == 2)
  316. else if(eMode == Module_Seperated_Mode) {
  317. if(m_name.length() <= 0) {
  318. printf("module name is invalid.\n");
  319. return;
  320. }
  321. if(lpszDir == NULL || _tcslen(lpszDir) <= 0) {
  322. if(GetCurExeNameOrPath(fileName, MAX_PATH, MODE_DIRECTORY) != -1) {
  323. m_strLogDirOrFilePath = tstring(fileName) + TLOG_TEXT("LogFiles");
  324. }else {
  325. printf("GetCurExeNameOrPath failed: %s", fileName);
  326. return;
  327. }
  328. }else {
  329. const tchar* pchSuffix = _tcsrchr(lpszDir, TLOG_TEXT('\\'));
  330. if(pchSuffix != NULL && pchSuffix[1] == '\0') {
  331. _tcscpy_s(fileName, MAX_PATH*sizeof(tchar), lpszDir);
  332. fileName[_tcslen(fileName)-1] = TLOG_TEXT('\0');
  333. m_strLogDirOrFilePath = tstring(fileName);
  334. }else {
  335. m_strLogDirOrFilePath = lpszDir;
  336. }
  337. }
  338. m_strLogDirOrFilePath += "\\";
  339. m_strLogDirOrFilePath += m_name;
  340. #ifndef LAZY_MODEL
  341. #ifndef UNICODE
  342. if(_access(m_strLogDirOrFilePath.c_str(), 0) == -1) {
  343. #else
  344. char tlsDirectory[MAX_PATH] = {0};
  345. int nt = WideCharToMultiByte(CP_ACP, 0, m_strLogDirOrFilePath.c_str(),
  346. -1, tlsDirectory, MAX_PATH, NULL, NULL);
  347. if(_access(tlsDirectory, 0) == -1) {
  348. #endif
  349. CreateDirectory(m_strLogDirOrFilePath.c_str(), NULL);
  350. }
  351. #endif
  352. m_eFileMode = Module_Seperated_Mode;
  353. }
  354. #endif
  355. }
  356. void Logger::TraceInfor(const tchar* strInfo)
  357. {
  358. if((m_usWriteStatus & LEVEL_INFOR_WRITEABLE) != LEVEL_INFOR_WRITEABLE) return;
  359. tstring str(GetTimeOfDay()+TRACE_INFOR);
  360. str += strInfo;
  361. Trace(str);
  362. }
  363. void Logger::TraceDebug(const tchar* strInfo)
  364. {
  365. if((m_usWriteStatus & LEVEL_DEBUG_WRITEABLE) != LEVEL_DEBUG_WRITEABLE) return;
  366. tstring str(GetTimeOfDay()+TRACE_DEBUG);
  367. str += strInfo;
  368. Trace(str);
  369. }
  370. void Logger::TraceWarning(const tchar* strInfo)
  371. {
  372. if((m_usWriteStatus & LEVEL_WARNING_WRITEABLE) != LEVEL_WARNING_WRITEABLE) return;
  373. tstring str(GetTimeOfDay() + TRACE_WARNNING);
  374. str += strInfo;
  375. Trace(str);
  376. }
  377. void Logger::TraceError(const tchar* strInfo)
  378. {
  379. if((m_usWriteStatus & LEVEL_ERROR_WRITEABLE) != LEVEL_ERROR_WRITEABLE) return;
  380. tstring str(GetTimeOfDay() + TRACE_ERROR);
  381. str += strInfo;
  382. Trace(str);
  383. }
  384. void Logger::TraceDefault(const tchar* strInfo)
  385. {
  386. if((m_usWriteStatus & LEVEL_LIMITED_WRITEABLE) != LEVEL_LIMITED_WRITEABLE) return;
  387. tstring str(GetTimeOfDay() + TRACE_DEFAULT);
  388. str += strInfo;
  389. Trace(str);
  390. }
  391. void Logger::TraceTrace(const tchar* szFile, int line, const tchar* strInfo)
  392. {
  393. if((m_usWriteStatus & LEVEL_TRACE_WRITEABLE) != LEVEL_TRACE_WRITEABLE) return;
  394. tstring str(GetTimeOfDay() + TRACE_TRACE);
  395. tstringstream tss;
  396. tss << line;
  397. str += strInfo;
  398. str = str + TLOG_TEXT(" file: {") + szFile + TLOG_TEXT("}, line: {") + tss.str() + TLOG_TEXT("}.");
  399. Trace(str);
  400. }
  401. void Logger::TraceAssert(const tchar* szFile, int line, const tchar* strInfo)
  402. {
  403. if((m_usWriteStatus & LEVEL_ERROR_WRITEABLE) != LEVEL_ERROR_WRITEABLE) return;
  404. tstring str(GetTimeOfDay() + TRACE_ASSERT);
  405. tstringstream tss;
  406. tss << line;
  407. str += strInfo;
  408. str = str + TLOG_TEXT(" file: {") + szFile + TLOG_TEXT("}, line: {") + tss.str() + TLOG_TEXT("}.");
  409. Trace(str);
  410. }
  411. void Logger::Trace_format(const tchar* fmt, va_list list_arg)
  412. {
  413. int n;
  414. n = _vsctprintf(fmt, list_arg);
  415. //#ifdef UNICODE
  416. // n = _vscwprintf(fmt, list_arg);
  417. //#else
  418. // n = _vscprintf(fmt, list_arg);
  419. //#endif
  420. if(n > 0)
  421. {
  422. tchar *buf = new tchar[n+1];
  423. memset(buf, 0, sizeof(tchar)*(n+1));
  424. _vstprintf_s(buf, n+1, fmt, list_arg);
  425. //#ifdef UNICODE
  426. // vswprintf_s(buf, n+1, fmt, list_arg);
  427. //#else
  428. // vsprintf_s(buf, n+1, fmt, list_arg);
  429. //#endif
  430. Trace(tstring(buf));
  431. delete buf;
  432. buf = NULL;
  433. }
  434. va_end(list_arg);
  435. }
  436. void Logger::TraceInfor_f(const tchar* fmt, ...)
  437. {
  438. if((m_usWriteStatus & LEVEL_INFOR_WRITEABLE) != LEVEL_INFOR_WRITEABLE) return;
  439. tstring str(GetTimeOfDay()+TRACE_INFOR + fmt);
  440. va_list arg;
  441. va_start(arg, fmt);
  442. Trace_format(str.c_str(), arg);
  443. }
  444. void Logger::TraceDebug_f(const tchar* fmt, ...)
  445. {
  446. if((m_usWriteStatus & LEVEL_DEBUG_WRITEABLE) != LEVEL_DEBUG_WRITEABLE) return;
  447. tstring str(GetTimeOfDay()+TRACE_DEBUG + fmt);
  448. va_list arg;
  449. va_start(arg, fmt);
  450. Trace_format(str.c_str(), arg);
  451. }
  452. void Logger::TraceWarning_f(const tchar* fmt, ...)
  453. {
  454. if((m_usWriteStatus & LEVEL_WARNING_WRITEABLE) != LEVEL_WARNING_WRITEABLE) return;
  455. tstring str(GetTimeOfDay()+TRACE_WARNNING + fmt);
  456. va_list arg;
  457. va_start(arg, fmt);
  458. Trace_format(str.c_str(), arg);
  459. }
  460. void Logger::TraceError_f(const tchar* fmt, ...)
  461. {
  462. if((m_usWriteStatus & LEVEL_ERROR_WRITEABLE) != LEVEL_ERROR_WRITEABLE) return;
  463. tstring str(GetTimeOfDay()+TRACE_ERROR + fmt);
  464. va_list arg;
  465. va_start(arg, fmt);
  466. Trace_format(str.c_str(), arg);
  467. }
  468. void Logger::TraceDefault_f(const tchar* fmt, ...)
  469. {
  470. if((m_usWriteStatus & LEVEL_LIMITED_WRITEABLE) != LEVEL_LIMITED_WRITEABLE) return;
  471. tstring str(GetTimeOfDay()+TRACE_DEFAULT + fmt);
  472. va_list arg;
  473. va_start(arg, fmt);
  474. Trace_format(str.c_str(), arg);
  475. }
  476. void Logger::TraceTrace_f(const tchar* szFile, int line, const tchar* fmt, ...)
  477. {
  478. if((m_usWriteStatus & LEVEL_TRACE_WRITEABLE) != LEVEL_TRACE_WRITEABLE) return;
  479. tstring str(GetTimeOfDay()+TRACE_TRACE + fmt);
  480. tstringstream tss;
  481. tss << line;
  482. //str += TLOG_TEXT("{");
  483. //str += fmt;
  484. //str += TLOG_TEXT("}");
  485. str = str + TLOG_TEXT(" file: {") + szFile + TLOG_TEXT("}, line: {") + tss.str() + TLOG_TEXT("}.");
  486. va_list arg;
  487. va_start(arg, fmt);
  488. Trace_format(str.c_str(), arg);
  489. }
  490. /*获取当前调用该日志文件的程序路径或程序名称(无类型后缀),主用于日志名称声明
  491. *@param: [out] outFilePath 获取到程序路径或程序名称的字符串
  492. * [in] sizeLen outFilePath字符数组的大小
  493. * [in] fetchKind FALSE表示仅获取程序路径,TRUE表示获取程序名称
  494. *@return 如果获取成功则表示实际得到的字符串长度,-1表示失败
  495. */
  496. DWORD Logger::GetCurExeNameOrPath(tchar* outFilePath, int sizeLen, int fetchKind)
  497. {
  498. DWORD tmpDwRes = 0;
  499. if(sizeLen <= 0)
  500. return -1;
  501. memset(outFilePath, 0, sizeof(tchar)*sizeLen);
  502. if(tmpDwRes = GetModuleFileName(NULL, outFilePath, sizeLen) == 0)
  503. {
  504. _stprintf_s(outFilePath, sizeLen, TLOG_TEXT("GetModuleFileName failed %d"), GetLastError());
  505. return -1;
  506. }
  507. if(fetchKind == MODE_DEFAULT)
  508. {
  509. return tmpDwRes;
  510. }
  511. if(fetchKind == MODE_FILENAME_WITH_PATH)
  512. {
  513. tchar* pch2 = _tcsrchr(outFilePath, TLOG_TEXT('.'));
  514. if(pch2 == NULL)
  515. {
  516. return -1;
  517. }
  518. pch2[0] = TLOG_TEXT('\0');
  519. return (int)(pch2 - outFilePath);
  520. }
  521. tchar* pch1 = _tcsrchr(outFilePath, TLOG_TEXT('\\'));
  522. if(fetchKind == MODE_DIRECTORY)
  523. {
  524. if(pch1 == NULL)
  525. {
  526. return -1;
  527. }
  528. if(int(pch1 - outFilePath) + 1 < sizeLen)
  529. {
  530. *(pch1 + 1) = TLOG_TEXT('\0');
  531. }
  532. return (int)(pch1 - outFilePath + 1);
  533. }
  534. tchar tmpFilePath[MAX_PATH] = {0};
  535. int idx = 0;
  536. tchar* pstart = pch1 + 1;
  537. if(fetchKind == MODE_FILENAME)
  538. {
  539. for(; *pstart != TLOG_TEXT('\0'); idx++)
  540. {
  541. tmpFilePath[idx] = *pstart++;
  542. }
  543. tmpFilePath[idx] = TLOG_TEXT('\0');
  544. memcpy_s(outFilePath, sizeof(tchar)*sizeLen, tmpFilePath, sizeof(tchar)*(idx+1));
  545. return idx+1;
  546. }
  547. if(fetchKind == MODE_FILENAME_ONLY)
  548. {
  549. tchar* pch2 = _tcsrchr(outFilePath, TLOG_TEXT('.'));
  550. if(pch1 == NULL || pch2 == NULL)
  551. {
  552. return -1;
  553. }
  554. for(; pstart < pch2; idx++)
  555. {
  556. tmpFilePath[idx] = *pstart++;
  557. }
  558. tmpFilePath[idx] = TLOG_TEXT('\0');
  559. memcpy_s(outFilePath, sizeof(tchar)*sizeLen, tmpFilePath, sizeof(tchar)*(idx+1));
  560. return idx+1;
  561. }
  562. return -1;
  563. }
  564. void Logger::DelayLoop(unsigned long usec)
  565. {
  566. LOG_FUNCTION();
  567. LARGE_INTEGER freq, start, now;
  568. //返回硬件支持的高精度计数器的每秒钟嘀嗒的次数,零表示硬件不支持,读取失败
  569. if (!QueryPerformanceFrequency(&freq))
  570. {
  571. Sleep(usec);
  572. }
  573. else
  574. {
  575. QueryPerformanceCounter(&start);
  576. for(;;)
  577. {
  578. QueryPerformanceCounter((LARGE_INTEGER*) &now);
  579. if( ((double)(now.QuadPart - start.QuadPart) / (double)freq.QuadPart) * 1000 > usec ) break;
  580. }
  581. }
  582. }
  583. bool Logger::WriteToFile(tstring str)
  584. {
  585. bool flag = false;
  586. EnterCriticalSection(&s_cs);
  587. try
  588. {
  589. m_logStream.open(m_fileName.c_str(), tfstream::in | tfstream::app);
  590. if(!m_logStream)
  591. {
  592. //MessageBox(NULL, TLOG_TEXT(m_fileName.c_str()),
  593. // TLOG_TEXT(""), MB_ICONINFORMATION | MB_OK);
  594. str.clear();
  595. }
  596. else if(m_logStream.is_open())
  597. {
  598. m_logStream << str.c_str();// << endl;
  599. m_logStream.close();
  600. flag = true;
  601. }
  602. }
  603. catch (std::exception e)
  604. {
  605. str.clear();
  606. LeaveCriticalSection(&s_cs);
  607. return flag;
  608. }
  609. LeaveCriticalSection(&s_cs);
  610. return flag;
  611. }
  612. bool Logger::ClearToFile()
  613. {
  614. bool flag = false;
  615. WaitForSingleObject(hMutexForBuffer, INFINITE);
  616. if(m_strBuffer.length() > 0)
  617. {
  618. if(m_eFileMode == Day_Seperated_Mode || m_eFileMode == Module_Seperated_Mode)
  619. {
  620. m_fileName = GetCustomTime(For_File_Type);
  621. }
  622. flag = WriteToFile(m_strBuffer);
  623. if(flag)
  624. {
  625. m_strBuffer = TLOG_TEXT("");
  626. m_bufCurLen = 0;
  627. }
  628. }
  629. ReleaseMutex(hMutexForBuffer);
  630. return flag;
  631. }
  632. int Logger::FormatLastError(tchar* szOutMsg, unsigned int sizeLen, DWORD erroCode)
  633. {
  634. if(sizeLen == 0 || szOutMsg == NULL)
  635. return 0;
  636. LPVOID lpMsgBuf;
  637. if(erroCode == 0)
  638. {
  639. erroCode = GetLastError();
  640. }
  641. if(!FormatMessage(
  642. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  643. FORMAT_MESSAGE_FROM_SYSTEM |
  644. FORMAT_MESSAGE_MAX_WIDTH_MASK,
  645. NULL,
  646. erroCode,
  647. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  648. (LPTSTR) &lpMsgBuf,
  649. 0, NULL ))
  650. {
  651. return 0;
  652. }
  653. _tcscpy_s(szOutMsg, sizeLen,(LPCTSTR)lpMsgBuf);
  654. LocalFree(lpMsgBuf);
  655. return _tcslen(szOutMsg);
  656. }
  657. void Logger::Start()
  658. {
  659. QueryPerformanceCounter(&m_liPerfStart);
  660. }
  661. __int64 Logger::Now() const
  662. {
  663. LARGE_INTEGER liPerfNow;
  664. QueryPerformanceCounter(&liPerfNow);
  665. return (((liPerfNow.QuadPart - m_liPerfStart.QuadPart) * 1000) / m_liPerfFreq.QuadPart);
  666. }
  667. __int64 Logger::NowInMicro() const
  668. {
  669. LARGE_INTEGER liPerfNow;
  670. QueryPerformanceCounter(&liPerfNow);
  671. return (((liPerfNow.QuadPart - m_liPerfStart.QuadPart) * 1000000) / m_liPerfFreq.QuadPart);
  672. }
  673. void Logger::TraceErrWithLastCode(const tchar* strInfo)
  674. {
  675. DWORD dwErrCode = GetLastError();
  676. TCHAR szMsg[MIN_INFOR_LEN] = {0};
  677. int nLen = FormatLastError(szMsg, MIN_INFOR_LEN, dwErrCode);
  678. TraceError_f(TLOG_TEXT("%s : (%d)%s."), strInfo, dwErrCode, szMsg);
  679. return;
  680. }
  681. const tchar * _GetFileNameForLog(const tchar *pszFilePath)
  682. {
  683. if(pszFilePath == NULL || _tcslen(pszFilePath) == 0)
  684. return TLOG_TEXT("empty");
  685. const tchar* backlash = _tcsrchr(pszFilePath, (int)(TLOG_TEXT('\\')));
  686. if(!backlash)
  687. {
  688. return pszFilePath;
  689. }
  690. return (backlash+1);
  691. }
  692. #if !(defined(TWINKLE_LOGGER_VERSION) && TWINKLE_LOGGER_VERSION == 2)
  693. unsigned int _stdcall Logger::CAutoWriteHelper::TimerWriteProc(void* param)
  694. {
  695. if(param == nullptr)
  696. {
  697. return -1;
  698. }
  699. Logger::CAutoWriteHelper* helper = (Logger::CAutoWriteHelper*)param;
  700. HANDLE hEvent = helper->GetLogTimerEvent();
  701. BOOL bLoop = TRUE;
  702. if(!hEvent)
  703. {
  704. return 0;
  705. }
  706. while(bLoop)
  707. {
  708. DWORD dwRet = WaitForSingleObject(hEvent, TIME_TO_WRITE_LOG);
  709. switch(dwRet)
  710. {
  711. case WAIT_OBJECT_0:
  712. //WRITE_TRACE_PARAM(TLOG_TEXT("WAIT_OBJECT_0"));
  713. helper->WriteToLog();
  714. bLoop = FALSE;
  715. break;
  716. case WAIT_TIMEOUT:
  717. //WRITE_TRACE_PARAM(TLOG_TEXT("WAIT_TIMEOUT"));
  718. helper->WriteToLog();
  719. break;
  720. case WAIT_FAILED:
  721. WRITE_TRACE_PARAM_INNER_USE(TLOG_TEXT("WAIT_FAILED"));
  722. bLoop = FALSE;
  723. break;
  724. }
  725. }
  726. //WRITE_TRACE_PARAM(TLOG_TEXT("hiahiahia"));
  727. return 0;
  728. }
  729. #else
  730. LoggerShell LoggerShell::GetInstance(const tstring& name)
  731. {
  732. return GetLoggerFactory()->GetLoggerProduct(name);
  733. }
  734. LoggerList LoggerShell::GetCurrentLoggers()
  735. {
  736. LoggerList list;
  737. GetLoggerFactory()->InitializeLoggerList(list);
  738. return list;
  739. }
  740. bool LoggerShell::Exists(const tstring& name)
  741. {
  742. return false;
  743. }
  744. LoggerShell LoggerShell::GetDefaultLogger()
  745. {
  746. LoggerShell instance;
  747. GetLoggerFactory()->InitializeDefaultLogger(instance);
  748. return instance;
  749. }
  750. //Define real global variable.
  751. LoggerFactory logger_factory;
  752. #endif