SpHostLog.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. #include "precompile.h"
  2. #if defined(_MSC_VER)
  3. #include <Windows.h>
  4. #else
  5. #include <algorithm>
  6. #include "fileutil.h"
  7. #include <winpr/sysinfo.h>
  8. #include <winpr/synch.h>
  9. #include <winpr/wlog.h>
  10. #include <winpr/thread.h>
  11. #define TAG "SpHostLog"
  12. #include <sys/stat.h>
  13. #define RWRWRE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
  14. #endif //_MSC_VER
  15. #include "SpHostLog.h"
  16. #include <fstream>
  17. #include <strstream>
  18. using namespace std;
  19. #include "sp_dir.h"
  20. #include "sp_def.h"
  21. #include "SpBase.h"
  22. #include <string>
  23. #include <algorithm>
  24. #include <locale>
  25. #include <path.h>
  26. #define SPHOST_LOG_LOCK_NAME "sphost_Log_Lock"
  27. void* g_logProducer = NULL;
  28. class CMyLogFile
  29. {
  30. public:
  31. void PrintCurTime();
  32. explicit CMyLogFile();
  33. ~CMyLogFile();
  34. void LOGERROR(const char* formatString, va_list argList);
  35. private:
  36. ofstream *m_cOutFile;
  37. bool GetRootDir(char *dirPath);
  38. void Init();
  39. void Release();
  40. BOOL Lock(DWORD dwTime);
  41. void Unlock();
  42. void Output(const char* data);
  43. HANDLE m_hLock;
  44. private:
  45. CMyLogFile& operator <<(long lVal);
  46. CMyLogFile& operator <<(const char* str);
  47. CMyLogFile& operator <<(char tch);
  48. CMyLogFile& operator <<(int nVal);
  49. CMyLogFile& operator <<(unsigned long ulVal);
  50. CMyLogFile& operator <<(double dVal);
  51. CMyLogFile& operator <<(unsigned int unVal);
  52. #if defined(_MSC_VER)
  53. CMyLogFile& operator <<(unsigned __int64 unllVal);
  54. #endif //_MSC_VER
  55. };
  56. CMyLogFile::CMyLogFile()
  57. :m_cOutFile(NULL)
  58. {
  59. }
  60. CMyLogFile::~CMyLogFile()
  61. {
  62. }
  63. void CMyLogFile::Output(const char *data)
  64. {
  65. if (NULL != m_cOutFile)
  66. m_cOutFile->write(data, strlen(data));
  67. }
  68. #if defined(_MSC_VER)
  69. bool checkDirExist(char *filePath)
  70. {
  71. return (CreateDirectoryA(filePath, NULL) || (GetLastError() == ERROR_ALREADY_EXISTS));
  72. }
  73. #endif //_MSC_VER
  74. void CMyLogFile::Init()
  75. {
  76. char tmp[MAX_PATH];
  77. //TODO(Gifur): duplicate path value set, which would makd memory leak
  78. GetModuleFileNameA(NULL, tmp, MAX_PATH);
  79. *strrchr(tmp, SPLIT_SLASH) = 0;
  80. *strrchr(tmp, SPLIT_SLASH) = 0;
  81. *strrchr(tmp, SPLIT_SLASH) = 0;
  82. *strrchr(tmp, SPLIT_SLASH) = 0;
  83. *strrchr(tmp, SPLIT_SLASH) = 0;
  84. if (!m_cOutFile)
  85. {
  86. char m_dirPath[_MAX_PATH] = "";
  87. sprintf_s(m_dirPath, _MAX_PATH, "%s" SPLIT_SLASH_STR "rvc" SPLIT_SLASH_STR "dbg" SPLIT_SLASH_STR "SpHost", tmp);
  88. #if defined(_MSC_VER)
  89. if (!checkDirExist(m_dirPath))
  90. #else
  91. if (!ExistsDirA(m_dirPath) && !CreateDirA(m_dirPath, TRUE))
  92. #endif
  93. return;
  94. SYSTEMTIME cur;
  95. GetSystemTime(&cur);
  96. sprintf(m_dirPath, "%s" SPLIT_SLASH_STR "%4d%.2d%.2d.log", m_dirPath, cur.wYear, cur.wMonth,
  97. cur.wDay);
  98. m_cOutFile = new ofstream(m_dirPath, ios_base::app);
  99. if (m_cOutFile->is_open())
  100. return;
  101. delete m_cOutFile;
  102. m_cOutFile = NULL;
  103. }
  104. }
  105. void CMyLogFile::Release()
  106. {
  107. if (NULL != m_cOutFile)
  108. {
  109. m_cOutFile->close();
  110. delete m_cOutFile;
  111. m_cOutFile = NULL;
  112. }
  113. }
  114. BOOL CMyLogFile::Lock(DWORD dwTime)
  115. {
  116. // 如果还没有创建锁就先创建一个
  117. if (!m_hLock)
  118. {
  119. std::string strLockName = SPHOST_LOG_LOCK_NAME;
  120. m_hLock = ::CreateMutex(NULL, FALSE, strLockName.c_str());
  121. if (!m_hLock)
  122. return FALSE;
  123. }
  124. // 哪个线程最先调用等待函数就最先占用这个互斥量
  125. DWORD dwRet = ::WaitForSingleObject(m_hLock, dwTime);
  126. return (dwRet == WAIT_OBJECT_0 || dwRet == WAIT_ABANDONED);
  127. }
  128. void CMyLogFile::Unlock()
  129. {
  130. if (m_hLock)
  131. ::ReleaseMutex(m_hLock);
  132. }
  133. ///*TODO(80374374@3/23/2023): */
  134. bool CMyLogFile::GetRootDir(char *dirPath)
  135. {
  136. char pathbuf[1024] = "";
  137. int pathlen = ::GetModuleFileNameA(NULL, pathbuf, 1024);//获得GuiConsole路径
  138. // 替换掉单杠
  139. int times = 0;
  140. while (pathlen > 0)
  141. {
  142. if (pathbuf[pathlen--] == SPLIT_SLASH)
  143. times++;
  144. if (2 == times)
  145. break;
  146. }
  147. pathbuf[++pathlen] = '\0';
  148. memcpy(dirPath, pathbuf, (pathlen + 1 > 1024 ? 1024 : pathlen + 1));
  149. return pathlen;
  150. }
  151. void CMyLogFile::PrintCurTime()
  152. {
  153. char dateString[52];
  154. SYSTEMTIME cur;
  155. GetLocalTime(&cur);
  156. sprintf(dateString, "[%4d%.2d%.2d %.2d:%.2d:%.2d.%03d][%u][%u] - ", cur.wYear, cur.wMonth,
  157. cur.wDay, cur.wHour, cur.wMinute, cur.wSecond, cur.wMilliseconds, GetCurrentProcessId(),
  158. #if defined(_MSC_VER)
  159. GetCurrentThreadId());
  160. #else
  161. GetCurrentThreadIdFromSys());
  162. #endif //_MSC_VER
  163. Output(dateString);
  164. }
  165. CMyLogFile& CMyLogFile::operator <<(unsigned int unVal)
  166. {
  167. strstream tmp;
  168. tmp << unVal;
  169. tmp << '\0';
  170. char* output = tmp.str();
  171. Output(output);
  172. tmp.freeze(false);
  173. return *this;
  174. }
  175. CMyLogFile& CMyLogFile::operator <<(long lVal)
  176. {
  177. strstream tmp;
  178. tmp << lVal;
  179. tmp << '\0';
  180. char* output = tmp.str();
  181. Output(output);
  182. tmp.freeze(false);
  183. return *this;
  184. }
  185. CMyLogFile& CMyLogFile::operator <<(const char* str)
  186. {
  187. Output(str);
  188. return *this;
  189. }
  190. CMyLogFile& CMyLogFile::operator <<(char tch)
  191. {
  192. char szCh[2];
  193. szCh[0] = tch;
  194. szCh[1] = '\0';
  195. Output(szCh);
  196. return *this;
  197. }
  198. CMyLogFile& CMyLogFile::operator <<(int nVal)
  199. {
  200. strstream tmp;
  201. tmp << nVal;
  202. tmp << '\0';
  203. char* output = tmp.str();
  204. Output(output);
  205. tmp.freeze(false);
  206. return *this;
  207. }
  208. CMyLogFile& CMyLogFile::operator <<(unsigned long ulVal)
  209. {
  210. strstream tmp;
  211. tmp << ulVal;
  212. tmp << '\0';
  213. char* output = tmp.str();
  214. Output(output);
  215. tmp.freeze(false);
  216. return *this;
  217. }
  218. CMyLogFile& CMyLogFile::operator <<(double dVal)
  219. {
  220. strstream tmp;
  221. tmp << dVal;
  222. tmp << '\0';
  223. char* output = tmp.str();
  224. Output(output);
  225. tmp.freeze(false);
  226. return *this;
  227. }
  228. #if defined(_MSC_VER)
  229. CMyLogFile& CMyLogFile::operator <<(unsigned __int64 unllVal)
  230. {
  231. strstream tmp;
  232. tmp << unllVal;
  233. tmp << '\0';
  234. char* output = tmp.str();
  235. Output(output);
  236. tmp.freeze(false);
  237. return *this;
  238. }
  239. #endif //_MSC_VER
  240. void CMyLogFile::LOGERROR(const char* formatString, va_list argList)
  241. {
  242. Lock(INFINITE);
  243. Init();
  244. #if defined(_MSC_VER)
  245. __try{
  246. if (NULL != m_cOutFile && !m_cOutFile->is_open())
  247. return;
  248. /*
  249. ** Insert the current time..
  250. */
  251. PrintCurTime();
  252. /*
  253. ** Parse the format string and write to the file
  254. */
  255. if (formatString == NULL)
  256. {
  257. /*
  258. ** No point in continuiing
  259. */
  260. return;
  261. }
  262. const char* ptr = formatString;
  263. while (*ptr != '\0')
  264. {
  265. char* str = NULL;
  266. int nInteger = 0;
  267. unsigned int unInt = 0;
  268. long lLong = 0;
  269. unsigned long ulLong = 0;
  270. double dDoub = 0;
  271. unsigned __int64 ullLong = 0;
  272. if (*ptr == '%')
  273. {
  274. switch (*(ptr + 1))
  275. {
  276. case 's':
  277. str = va_arg(argList, char*);
  278. if (NULL == str)
  279. break;
  280. *this << str;
  281. ptr++;
  282. break;
  283. case 'd':
  284. nInteger = va_arg(argList, int);
  285. *this << nInteger;
  286. ptr++;
  287. break;
  288. case 'u':
  289. unInt = va_arg(argList, unsigned int);
  290. *this << unInt;
  291. ptr++;
  292. break;
  293. case 'l':
  294. ptr++;
  295. if (*(ptr + 1) == 'd')
  296. {
  297. lLong = va_arg(argList, long);
  298. *this << lLong;
  299. ptr++;
  300. }
  301. else if (*(ptr + 1) == 'u')
  302. {
  303. ulLong = va_arg(argList, unsigned long);
  304. *this << ulLong;
  305. ptr++;
  306. }
  307. else if (*(ptr + 1) == 'q')
  308. {
  309. ullLong = va_arg(argList, unsigned __int64);
  310. *this << ullLong;
  311. ptr++;
  312. }
  313. break;
  314. case 'f':
  315. dDoub = va_arg(argList, double);
  316. *this << dDoub;
  317. ptr++;
  318. break;
  319. default:
  320. *this << *ptr;
  321. }
  322. } // if(*ptr == '%')
  323. else
  324. {
  325. *this << *ptr;
  326. }
  327. /*
  328. ** Increment pointer..
  329. */
  330. ptr++;
  331. }
  332. *this << '\n';
  333. }
  334. __finally
  335. {
  336. Release();
  337. Unlock();
  338. }
  339. #else
  340. do
  341. {
  342. if (NULL != m_cOutFile && !m_cOutFile->is_open())
  343. break;
  344. PrintCurTime();
  345. if (formatString == NULL) {
  346. break;
  347. }
  348. const char* ptr = formatString;
  349. while (*ptr != '\0') {
  350. char* str = NULL;
  351. int nInteger = 0;
  352. unsigned int unInt = 0;
  353. long lLong = 0;
  354. unsigned long ulLong = 0;
  355. double dDoub = 0;
  356. u__int64_t ullLong = 0;
  357. if (*ptr == '%') {
  358. switch (*(ptr + 1)) {
  359. case 's':
  360. str = va_arg(argList, char*);
  361. if (NULL == str)
  362. break;
  363. *this << str;
  364. ptr++;
  365. break;
  366. case 'd':
  367. nInteger = va_arg(argList, int);
  368. *this << nInteger;
  369. ptr++;
  370. break;
  371. case 'u':
  372. unInt = va_arg(argList, unsigned int);
  373. *this << unInt;
  374. ptr++;
  375. break;
  376. case 'l':
  377. ptr++;
  378. if (*(ptr + 1) == 'd') {
  379. lLong = va_arg(argList, long);
  380. *this << lLong;
  381. ptr++;
  382. } else if (*(ptr + 1) == 'u') {
  383. ulLong = va_arg(argList, unsigned long);
  384. *this << ulLong;
  385. ptr++;
  386. } else if (*(ptr + 1) == 'q') {
  387. ullLong = va_arg(argList, u__int64_t);
  388. *this << ullLong;
  389. ptr++;
  390. }
  391. break;
  392. case 'f':
  393. dDoub = va_arg(argList, double);
  394. *this << dDoub;
  395. ptr++;
  396. break;
  397. default:
  398. *this << *ptr;
  399. }
  400. } else {
  401. *this << *ptr;
  402. }
  403. ptr++;
  404. }
  405. *this << '\n';
  406. } while (false);
  407. Release();
  408. Unlock();
  409. #endif
  410. }
  411. void DbgSphost(const char* formatStr, ...)
  412. {
  413. CMyLogFile log;
  414. va_list args;
  415. va_start(args, formatStr);
  416. log.LOGERROR(formatStr, args);
  417. va_end(args);
  418. }
  419. void DbgWithLink_sphost(const char* formatStr, ...) {
  420. va_list arg;
  421. va_start(arg, formatStr);
  422. //不这么写?貌似到DbgWithLink内后,arg会被析构?
  423. int n = _vscprintf(formatStr, arg);
  424. char* buf = (char*)_alloca(n + 1);
  425. vsprintf(buf, formatStr, arg);
  426. std::string dstPrint = std::string("<") + std::to_string((long long)GetCurrentProcessId()) + std::string(">") + std::string(buf);
  427. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).withLogProducer(g_logProducer).withExtendLog(false)(dstPrint.c_str());
  428. //DbgSphost(buf);
  429. va_end(arg);
  430. }
  431. int createLogProducer(const char* entityName, const char *id)
  432. {
  433. g_logProducer = create_log_producer_storage("sphost", id, "", "", "");
  434. if (g_logProducer == NULL)
  435. return -1;
  436. return 0;
  437. }
  438. void DestroyLogProducer()
  439. {
  440. if (g_logProducer != NULL) {
  441. destroy_log_producer_storage(g_logProducer);
  442. g_logProducer = NULL;
  443. }
  444. }