inner_log.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. #include "inner_log.h"
  2. #include <errno.h>
  3. #include "log_util.h"
  4. #include "log_multi_thread.h"
  5. #ifdef _WIN32
  6. #include <windows.h>
  7. #include <direct.h>
  8. #else
  9. #include <unistd.h>
  10. #include <sys/syscall.h>
  11. #include <sys/stat.h>
  12. #endif
  13. //////////////////////////////////////////////////////////////////////////
  14. typedef struct RvcLog
  15. {
  16. CRITICALSECTION lock;
  17. FILE* file_handle;
  18. int show_file_info; //是否显示文件行号
  19. int log_level;
  20. char log_filename_prefix[512]; //日志文件前缀名
  21. char log_file_name[512];
  22. char* log_buf;
  23. char* write_log_buf;
  24. int write_log_buf_size;
  25. int write_log_len;
  26. }RvcLog;
  27. //私有方法,外部不要调用
  28. int _rvclog_init_internal(RvcLog* rvc_log);
  29. int _rvclog_destroy_internal(RvcLog* rvc_log);
  30. int _flush_log(RvcLog* rvc_log);
  31. int _close_log_file(RvcLog* rvc_log);
  32. int _remove_log_file(RvcLog* rvc_log);
  33. void _get_daylog_filename(RvcLog* rvc_log, char* buf);
  34. int _open_logfile(RvcLog* rvc_log);
  35. int _set_logfile(RvcLog* rvc_log, const char* logfileName);
  36. int _create_dir(const char* szPath);
  37. static RvcLog *rvc_system_log = NULL;
  38. static int is_prd = 1;//set 1 to no log in product
  39. char* rcv_log_buf = NULL;
  40. char* AllocLogBuf(void)
  41. {
  42. if (!rcv_log_buf)
  43. {
  44. rcv_log_buf = (char*)malloc(MFLOG_BUFSIZE + 1);
  45. memset(rcv_log_buf, 0, MFLOG_BUFSIZE + 1);
  46. return rcv_log_buf;
  47. }
  48. else {
  49. return rcv_log_buf;
  50. }
  51. }
  52. void MakeLogPrefix(int nLevel, char* szLevel, char* szTime)
  53. {
  54. struct tm* today;
  55. time_t ltime;
  56. #if defined(_MSC_VER)
  57. time(&ltime);
  58. today = localtime(&ltime);
  59. #else
  60. struct timeval tv;
  61. time(&ltime);
  62. today = localtime(&ltime);
  63. gettimeofday(&tv, NULL);
  64. #endif //_MSC_VER
  65. switch (nLevel)
  66. {
  67. case LM_TRACE:
  68. strcpy(szLevel, "TRACE");
  69. break;
  70. case LM_DEBUG:
  71. strcpy(szLevel, "DEBUG");
  72. break;
  73. case LM_INFO:
  74. strcpy(szLevel, "INFO");
  75. break;
  76. case LM_NOTICE:
  77. strcpy(szLevel, "NOTICE");
  78. break;
  79. case LM_WARNING:
  80. strcpy(szLevel, "WARNING");
  81. break;
  82. case LM_ERROR:
  83. strcpy(szLevel, "ERROR");
  84. break;
  85. case LM_CRITICAL:
  86. strcpy(szLevel, "CRITICAL");
  87. break;
  88. default:
  89. strcpy(szLevel, "UNKNOWN");
  90. break;
  91. }
  92. #if defined(_MSC_VER)
  93. sprintf(szTime, "%02d%02d%02d %02d%02d%02d",
  94. today->tm_year + 1900 - 2000,
  95. today->tm_mon + 1,
  96. today->tm_mday,
  97. today->tm_hour,
  98. today->tm_min,
  99. today->tm_sec
  100. );
  101. #else
  102. sprintf(szTime, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
  103. today->tm_year + 1900,
  104. today->tm_mon + 1,
  105. today->tm_mday,
  106. today->tm_hour,
  107. today->tm_min,
  108. today->tm_sec,
  109. tv.tv_usec / 1000
  110. );
  111. #endif //_MSC_VER
  112. }
  113. int RvcLog_init(const char* log_dir, const char* log_name, int level, int show_file_line)
  114. {
  115. if (level == LM_OFF) {
  116. is_prd = 1;
  117. return 0;
  118. }
  119. is_prd = 0;
  120. if (rvc_system_log != NULL) {
  121. return 0;
  122. }
  123. rvc_system_log = (RvcLog*)malloc(sizeof(RvcLog));
  124. _rvclog_init_internal(rvc_system_log);
  125. rvc_system_log->log_level = level;
  126. rvc_system_log->show_file_info = show_file_line;
  127. {
  128. char buf[512];
  129. strncpy(buf, log_dir, 512);
  130. #ifdef WIN32
  131. strncpy(buf + strlen(buf), "\\", 512 - strlen(buf));
  132. #else
  133. strncpy(buf + strlen(buf), "/", 512 - strlen(buf));
  134. #endif
  135. strncpy(buf + strlen(buf), log_name, 512 - strlen(buf));
  136. _set_logfile(rvc_system_log, buf);
  137. }
  138. return 0;
  139. }
  140. int RvcLog_destroy()
  141. {
  142. //huchen add for 生产,不写日志
  143. if (is_prd) {
  144. return 0;
  145. }
  146. _rvclog_destroy_internal(rvc_system_log);
  147. if (rcv_log_buf)
  148. free(rcv_log_buf);
  149. return 0;
  150. }
  151. int RvcLog_log(const char* szSrcFileName, int iLine, int console, int iLevel, char* szLevel, char* szTime, char* szLog)
  152. {
  153. RvcLog* rvc_log;
  154. char* fileSuffix;
  155. //huchen add for 生产,不写日志
  156. if (is_prd) {
  157. return 0;
  158. }
  159. rvc_log = rvc_system_log;
  160. if (iLevel < rvc_log->log_level)
  161. return 0;
  162. //多线程要加锁
  163. CS_ENTER(rvc_log->lock);
  164. if (rvc_log->log_buf == NULL) {
  165. CS_LEAVE(rvc_log->lock);
  166. return -1;
  167. }
  168. if (rvc_log->show_file_info)
  169. {
  170. #if defined(_MSC_VER)
  171. fileSuffix = strrchr(szSrcFileName, '\\');
  172. #else
  173. fileSuffix = strrchr(szSrcFileName, '/');
  174. #endif //_MSC_VER
  175. if (fileSuffix != NULL) {
  176. fileSuffix += 1;
  177. } else {
  178. ///*TODO: (80374374@10/24/2023)*/
  179. fileSuffix = szSrcFileName;
  180. }
  181. snprintf(rvc_log->log_buf, MFLOG_BUFSIZE, "%s:%s:%ld:[%d@%s]:%s\n",
  182. szTime,
  183. szLevel,
  184. #if defined(_MSC_VER)
  185. GetCurrentThreadId(),
  186. #else
  187. (size_t)syscall(SYS_gettid),
  188. #endif //_MSC_VER
  189. iLine,
  190. fileSuffix,
  191. szLog
  192. );
  193. }
  194. else
  195. {
  196. snprintf(rvc_log->log_buf, MFLOG_BUFSIZE, "%s[%ld]:%s\n",
  197. szTime,
  198. #if defined(_MSC_VER)
  199. GetCurrentThreadId(),
  200. #else
  201. (size_t)syscall(SYS_gettid),
  202. #endif //_MSC_VER
  203. szLog
  204. );
  205. }
  206. {
  207. int tmpLen = strlen(rvc_log->log_buf);
  208. if (tmpLen + rvc_log->write_log_len > rvc_log->write_log_buf_size)
  209. {
  210. _flush_log(rvc_log);
  211. rvc_log->write_log_len = 0;
  212. }
  213. memcpy(rvc_log->write_log_buf + rvc_log->write_log_len, rvc_log->log_buf, tmpLen);
  214. rvc_log->write_log_buf[rvc_log->write_log_len + tmpLen] = 0;
  215. rvc_log->write_log_len += tmpLen;
  216. if (rvc_log->write_log_len >= MF_LOG_STR_BUFSIZE)
  217. {
  218. _flush_log(rvc_log);
  219. rvc_log->write_log_len = 0;
  220. }
  221. //////////////////////////////////////////////////////////////////////////
  222. _flush_log(rvc_log);
  223. rvc_log->write_log_len = 0;
  224. //////////////////////////////////////////////////////////////////////////
  225. }
  226. if (console) {
  227. printf("%s", rvc_log->log_buf);
  228. }
  229. CS_LEAVE(rvc_log->lock);
  230. return 0;
  231. }
  232. int _rvclog_init_internal(RvcLog* rvc_log)
  233. {
  234. if (!rvc_log)
  235. return -1;
  236. rvc_log->file_handle = NULL;
  237. rvc_log->log_buf = (char*)malloc(MFLOG_BUFSIZE + 1);
  238. memset(rvc_log->log_buf, 0, MFLOG_BUFSIZE + 1);
  239. rvc_log->log_buf[MFLOG_BUFSIZE] = 0;
  240. rvc_log->write_log_buf = (char*)malloc(MF_LOG_STR_BUFSIZE);
  241. memset(rvc_log->write_log_buf, 0, MF_LOG_STR_BUFSIZE);
  242. rvc_log->write_log_buf_size = MF_LOG_STR_BUFSIZE;
  243. rvc_log->write_log_len = 0;
  244. rvc_log->log_level = 0;
  245. rvc_log->show_file_info = 0;
  246. rvc_log->lock = CreateCriticalSection();
  247. return 0;
  248. }
  249. int _rvclog_destroy_internal(RvcLog* rvc_log)
  250. {
  251. if (!rvc_log)
  252. return -1;
  253. _flush_log(rvc_log);
  254. _close_log_file(rvc_log);
  255. if (rvc_log->log_buf)
  256. free(rvc_log->log_buf);
  257. if (rvc_log->write_log_buf)
  258. free(rvc_log->write_log_buf);
  259. ReleaseCriticalSection(rvc_log->lock);
  260. free(rvc_log);
  261. return 0;
  262. }
  263. int _flush_log(RvcLog* rvc_log)
  264. {
  265. //多线程还要考虑同步问题,这里先不考虑
  266. //CMutexGuard g( m_LogMutex );
  267. int iRC;
  268. if (rvc_log->write_log_len == 0 || !rvc_log->write_log_buf)
  269. return -1;
  270. iRC = fwrite(rvc_log->write_log_buf, rvc_log->write_log_len, 1, rvc_log->file_handle);
  271. fflush(rvc_log->file_handle);
  272. if (iRC <= 0)
  273. {
  274. }
  275. else
  276. {
  277. char buf[512];
  278. _get_daylog_filename(rvc_log, buf);
  279. if (0 != strcmp(rvc_log->log_file_name, (const char*)buf))
  280. {
  281. _close_log_file(rvc_log);
  282. _remove_log_file(rvc_log);
  283. strncpy(rvc_log->log_file_name, buf, 512);
  284. _open_logfile(rvc_log);
  285. }
  286. }
  287. rvc_log->write_log_len = 0;
  288. return 0;
  289. }
  290. int _remove_log_file(RvcLog* rvc_log)
  291. {
  292. if (rvc_log->log_file_name)
  293. {
  294. remove(rvc_log->log_file_name);
  295. }
  296. return 0;
  297. }
  298. int _close_log_file(RvcLog* rvc_log)
  299. {
  300. if (rvc_log->file_handle)
  301. {
  302. fclose(rvc_log->file_handle);
  303. rvc_log->file_handle = NULL;
  304. }
  305. return 0;
  306. }
  307. int _open_logfile(RvcLog* rvc_log)
  308. {
  309. rvc_log->file_handle = fopen(rvc_log->log_file_name, "r");
  310. if (rvc_log->file_handle)
  311. {
  312. fclose(rvc_log->file_handle);
  313. rvc_log->file_handle = NULL;
  314. rvc_log->file_handle = fopen(rvc_log->log_file_name, "a");
  315. }
  316. else
  317. rvc_log->file_handle = fopen(rvc_log->log_file_name, "w");
  318. if (rvc_log->file_handle)
  319. return 0;
  320. return -1;
  321. }
  322. void _get_daylog_filename(RvcLog* rvc_log, char* buf)
  323. {
  324. time_t lTime = time(NULL);
  325. struct tm* tm1 = localtime(&lTime);
  326. sprintf(buf, "%s%02d%02d%02d.log",
  327. rvc_log->log_filename_prefix,
  328. tm1->tm_year + 1900 - 2000,
  329. tm1->tm_mon + 1,
  330. tm1->tm_mday
  331. );
  332. }
  333. int _set_logfile(RvcLog* rvc_log, const char* logfileName)
  334. {
  335. //多线程同步
  336. int len = strlen(logfileName);
  337. int iSub = 0;
  338. int i = 0;
  339. char FileDir[255];
  340. if (!logfileName || strlen(logfileName) <= 0) {
  341. return -1;
  342. }
  343. for (i = len - 1; i >= 0; i--) {
  344. if (logfileName[i] == '/'|| logfileName[i] == '\\') {
  345. iSub = i;
  346. break;
  347. }
  348. }
  349. memcpy(FileDir, logfileName, iSub + 1);
  350. FileDir[iSub + 1] = 0;
  351. if (strlen(FileDir) > 0)
  352. {
  353. if (mkdir_foreach(FileDir, strlen(FileDir)) != 0){
  354. return -1;
  355. }
  356. }
  357. strcpy(rvc_log->log_filename_prefix, logfileName);
  358. _close_log_file(rvc_log);
  359. _get_daylog_filename(rvc_log, rvc_log->log_file_name);
  360. _remove_log_file(rvc_log);
  361. return _open_logfile(rvc_log);
  362. }
  363. int _create_dir(const char* szPath)
  364. {
  365. char buf[128] = { 0 };
  366. int i = 0;
  367. int buf_idx = 0;
  368. if (!szPath)
  369. return -1;
  370. while (szPath[i] != 0)
  371. {
  372. if (szPath[i] == '\\' || szPath[i] == '/')
  373. {
  374. if (buf_idx > 0)
  375. {
  376. #if defined(_MSC_VER)
  377. if (mkdir(buf))
  378. #else
  379. if (mkdir(buf, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
  380. #endif //_MSC_VER
  381. {
  382. if (EEXIST != errno)
  383. {
  384. return -2;
  385. }
  386. }
  387. }
  388. }
  389. {
  390. buf[buf_idx] = szPath[i];
  391. buf_idx++;
  392. }
  393. i++;
  394. }
  395. if (buf_idx > 0)
  396. {
  397. #if defined(_MSC_VER)
  398. if (mkdir(buf))
  399. #else
  400. if (mkdir(buf, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
  401. #endif //_MSC_VER
  402. {
  403. if (EEXIST != errno)
  404. {
  405. return -2;
  406. }
  407. }
  408. }
  409. return 0;
  410. }