SpHostLog.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  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(), GetCurrentThreadId());
  158. Output(dateString);
  159. }
  160. CMyLogFile& CMyLogFile::operator <<(unsigned int unVal)
  161. {
  162. strstream tmp;
  163. tmp << unVal;
  164. tmp << '\0';
  165. char* output = tmp.str();
  166. Output(output);
  167. tmp.freeze(false);
  168. return *this;
  169. }
  170. CMyLogFile& CMyLogFile::operator <<(long lVal)
  171. {
  172. strstream tmp;
  173. tmp << lVal;
  174. tmp << '\0';
  175. char* output = tmp.str();
  176. Output(output);
  177. tmp.freeze(false);
  178. return *this;
  179. }
  180. CMyLogFile& CMyLogFile::operator <<(const char* str)
  181. {
  182. Output(str);
  183. return *this;
  184. }
  185. CMyLogFile& CMyLogFile::operator <<(char tch)
  186. {
  187. char szCh[2];
  188. szCh[0] = tch;
  189. szCh[1] = '\0';
  190. Output(szCh);
  191. return *this;
  192. }
  193. CMyLogFile& CMyLogFile::operator <<(int nVal)
  194. {
  195. strstream tmp;
  196. tmp << nVal;
  197. tmp << '\0';
  198. char* output = tmp.str();
  199. Output(output);
  200. tmp.freeze(false);
  201. return *this;
  202. }
  203. CMyLogFile& CMyLogFile::operator <<(unsigned long ulVal)
  204. {
  205. strstream tmp;
  206. tmp << ulVal;
  207. tmp << '\0';
  208. char* output = tmp.str();
  209. Output(output);
  210. tmp.freeze(false);
  211. return *this;
  212. }
  213. CMyLogFile& CMyLogFile::operator <<(double dVal)
  214. {
  215. strstream tmp;
  216. tmp << dVal;
  217. tmp << '\0';
  218. char* output = tmp.str();
  219. Output(output);
  220. tmp.freeze(false);
  221. return *this;
  222. }
  223. #if defined(_MSC_VER)
  224. CMyLogFile& CMyLogFile::operator <<(unsigned __int64 unllVal)
  225. {
  226. strstream tmp;
  227. tmp << unllVal;
  228. tmp << '\0';
  229. char* output = tmp.str();
  230. Output(output);
  231. tmp.freeze(false);
  232. return *this;
  233. }
  234. #endif //_MSC_VER
  235. void CMyLogFile::LOGERROR(const char* formatString, va_list argList)
  236. {
  237. Lock(INFINITE);
  238. Init();
  239. #if defined(_MSC_VER)
  240. __try{
  241. if (NULL != m_cOutFile && !m_cOutFile->is_open())
  242. return;
  243. /*
  244. ** Insert the current time..
  245. */
  246. PrintCurTime();
  247. /*
  248. ** Parse the format string and write to the file
  249. */
  250. if (formatString == NULL)
  251. {
  252. /*
  253. ** No point in continuiing
  254. */
  255. return;
  256. }
  257. const char* ptr = formatString;
  258. while (*ptr != '\0')
  259. {
  260. char* str = NULL;
  261. int nInteger = 0;
  262. unsigned int unInt = 0;
  263. long lLong = 0;
  264. unsigned long ulLong = 0;
  265. double dDoub = 0;
  266. unsigned __int64 ullLong = 0;
  267. if (*ptr == '%')
  268. {
  269. switch (*(ptr + 1))
  270. {
  271. case 's':
  272. str = va_arg(argList, char*);
  273. if (NULL == str)
  274. break;
  275. *this << str;
  276. ptr++;
  277. break;
  278. case 'd':
  279. nInteger = va_arg(argList, int);
  280. *this << nInteger;
  281. ptr++;
  282. break;
  283. case 'u':
  284. unInt = va_arg(argList, unsigned int);
  285. *this << unInt;
  286. ptr++;
  287. break;
  288. case 'l':
  289. ptr++;
  290. if (*(ptr + 1) == 'd')
  291. {
  292. lLong = va_arg(argList, long);
  293. *this << lLong;
  294. ptr++;
  295. }
  296. else if (*(ptr + 1) == 'u')
  297. {
  298. ulLong = va_arg(argList, unsigned long);
  299. *this << ulLong;
  300. ptr++;
  301. }
  302. else if (*(ptr + 1) == 'q')
  303. {
  304. ullLong = va_arg(argList, unsigned __int64);
  305. *this << ullLong;
  306. ptr++;
  307. }
  308. break;
  309. case 'f':
  310. dDoub = va_arg(argList, double);
  311. *this << dDoub;
  312. ptr++;
  313. break;
  314. default:
  315. *this << *ptr;
  316. }
  317. } // if(*ptr == '%')
  318. else
  319. {
  320. *this << *ptr;
  321. }
  322. /*
  323. ** Increment pointer..
  324. */
  325. ptr++;
  326. }
  327. *this << '\n';
  328. }
  329. __finally
  330. {
  331. Release();
  332. Unlock();
  333. }
  334. #else
  335. do
  336. {
  337. if (NULL != m_cOutFile && !m_cOutFile->is_open())
  338. break;
  339. PrintCurTime();
  340. if (formatString == NULL) {
  341. break;
  342. }
  343. const char* ptr = formatString;
  344. while (*ptr != '\0') {
  345. char* str = NULL;
  346. int nInteger = 0;
  347. unsigned int unInt = 0;
  348. long lLong = 0;
  349. unsigned long ulLong = 0;
  350. double dDoub = 0;
  351. u__int64_t ullLong = 0;
  352. if (*ptr == '%') {
  353. switch (*(ptr + 1)) {
  354. case 's':
  355. str = va_arg(argList, char*);
  356. if (NULL == str)
  357. break;
  358. *this << str;
  359. ptr++;
  360. break;
  361. case 'd':
  362. nInteger = va_arg(argList, int);
  363. *this << nInteger;
  364. ptr++;
  365. break;
  366. case 'u':
  367. unInt = va_arg(argList, unsigned int);
  368. *this << unInt;
  369. ptr++;
  370. break;
  371. case 'l':
  372. ptr++;
  373. if (*(ptr + 1) == 'd') {
  374. lLong = va_arg(argList, long);
  375. *this << lLong;
  376. ptr++;
  377. } else if (*(ptr + 1) == 'u') {
  378. ulLong = va_arg(argList, unsigned long);
  379. *this << ulLong;
  380. ptr++;
  381. } else if (*(ptr + 1) == 'q') {
  382. ullLong = va_arg(argList, u__int64_t);
  383. *this << ullLong;
  384. ptr++;
  385. }
  386. break;
  387. case 'f':
  388. dDoub = va_arg(argList, double);
  389. *this << dDoub;
  390. ptr++;
  391. break;
  392. default:
  393. *this << *ptr;
  394. }
  395. } else {
  396. *this << *ptr;
  397. }
  398. ptr++;
  399. }
  400. *this << '\n';
  401. } while (false);
  402. Release();
  403. Unlock();
  404. #endif
  405. }
  406. void DbgSphost(const char* formatStr, ...)
  407. {
  408. CMyLogFile log;
  409. va_list args;
  410. va_start(args, formatStr);
  411. log.LOGERROR(formatStr, args);
  412. va_end(args);
  413. }
  414. void DbgWithLink_sphost(const char* formatStr, ...) {
  415. va_list arg;
  416. va_start(arg, formatStr);
  417. //不这么写?貌似到DbgWithLink内后,arg会被析构?
  418. int n = _vscprintf(formatStr, arg);
  419. char* buf = (char*)_alloca(n + 1);
  420. vsprintf(buf, formatStr, arg);
  421. std::string dstPrint = std::string("<") + std::to_string((long long)GetCurrentProcessId()) + std::string(">") + std::string(buf);
  422. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).withLogProducer(g_logProducer).withExtendLog(false)(dstPrint.c_str());
  423. //DbgSphost(buf);
  424. va_end(arg);
  425. }
  426. int createLogProducer(const char* entityName, const char *id)
  427. {
  428. g_logProducer = create_log_producer_storage("sphost", id, "", "", "");
  429. if (g_logProducer == NULL)
  430. return -1;
  431. return 0;
  432. }
  433. void DestroyLogProducer()
  434. {
  435. if (g_logProducer != NULL) {
  436. destroy_log_producer_storage(g_logProducer);
  437. g_logProducer = NULL;
  438. }
  439. }