log.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. #include "precompile.h"
  2. #include "log.h"
  3. #include "log_mgr.h"
  4. #include "log_single.h"
  5. #include "log_periodic.h"
  6. #include "log_udpclient.h"
  7. #include "log_udpdaemon.h"
  8. #include "iniutil.h"
  9. #include "fileutil.h"
  10. #include "sockutil.h"
  11. #include "dbgutil.h"
  12. #ifdef _WIN32
  13. #include "modCheck.h"
  14. #endif //_WIN32
  15. #include <winpr/string.h>
  16. #define XLOG_VERSION 0x0101
  17. #ifndef _WIN32
  18. static logmgr_t* g_mgr = 0;
  19. static int g_initialized = 0;
  20. #endif //!_WIN32
  21. TOOLKIT_API int xlog_version();
  22. TOOLKIT_API int xlog_init2(const char *inifile, const char *sections);
  23. TOOLKIT_API int xlog_set_level(const char* inst, int level);
  24. TOOLKIT_API int xlog_get_level(const char* inst, int *level);
  25. /*get ini file from ini|etc|conf folder under current execute directory*/
  26. static char *find_best_config()
  27. {
  28. char path[MAX_PATH];
  29. char *filepart;
  30. GetModuleFileNameA(NULL, path, MAX_PATH);
  31. filepart = strrchr(path, SPLIT_SLASH);
  32. if (filepart) {
  33. *filepart = 0;
  34. filepart++;
  35. if (strlen(filepart) > 4) {
  36. int i;
  37. struct {
  38. char *fmt;
  39. char *str1;
  40. char *str2;
  41. }defaultfilepath[] = {
  42. {"%s" SPLIT_SLASH_STR "ini" SPLIT_SLASH_STR "log" SPLIT_SLASH_STR "%s.ini", path, filepart},
  43. {"%s" SPLIT_SLASH_STR "etc" SPLIT_SLASH_STR "log" SPLIT_SLASH_STR "%s.ini", path, filepart},
  44. {"%s" SPLIT_SLASH_STR "conf" SPLIT_SLASH_STR "log" SPLIT_SLASH_STR "%s.ini", path, filepart},
  45. {"%s" SPLIT_SLASH_STR "log.ini", path, NULL},
  46. {"%s" SPLIT_SLASH_STR "ini" SPLIT_SLASH_STR "log.ini", path, filepart},
  47. {"%s" SPLIT_SLASH_STR "etc" SPLIT_SLASH_STR "log.ini", path, filepart},
  48. {"%s" SPLIT_SLASH_STR "conf" SPLIT_SLASH_STR "log.ini", path, filepart},
  49. {NULL, NULL, NULL},
  50. };
  51. filepart[strlen(filepart)-4] = 0;
  52. for (i = 0; defaultfilepath[i].fmt != NULL; ++i) {
  53. char tmp[MAX_PATH];
  54. sprintf(tmp, defaultfilepath[i].fmt, defaultfilepath[i].str1, defaultfilepath->str2);
  55. if (ExistsFileA(tmp))
  56. return _strdup(tmp);
  57. }
  58. }
  59. }
  60. return NULL;
  61. }
  62. static int contains_name(va_list arg, const char *name)
  63. {
  64. char *p;
  65. while((p = va_arg(arg, char*)) != NULL) {
  66. if (_stricmp(name, p) == 0)
  67. return TRUE;
  68. }
  69. return 0;
  70. }
  71. TOOLKIT_API int xlog_version()
  72. {
  73. return XLOG_VERSION;
  74. }
  75. TOOLKIT_API int xlog_init(const char *file)
  76. {
  77. return xlog_init2(file, NULL);
  78. }
  79. TOOLKIT_API int xlog_init2(const char *file, const char *sections)
  80. {
  81. logfactory_t *fac;
  82. array_header_t *arr_section = NULL;
  83. char *copysections = NULL;
  84. char *best_config_file = NULL;
  85. int rc = 0;
  86. #ifdef _WIN32
  87. if (toolkit_getResource()->g_initialized++) {
  88. return 0;
  89. }
  90. #else
  91. if (g_initialized++) {
  92. return 0;
  93. }
  94. #endif //_WIN32
  95. winsock_init();
  96. if (sections) {
  97. const char *delimers = ",| ";
  98. char *p;
  99. copysections = _strdup(sections);
  100. arr_section = array_make(3, sizeof(char*));
  101. p = strtok(copysections, delimers);
  102. while (p) {
  103. ARRAY_PUSH(arr_section, char*) = p;
  104. p = strtok(NULL, delimers);
  105. }
  106. }
  107. #ifdef _WIN32
  108. logmgr_create(&((logmgr_t *)(toolkit_getResource()->g_mgr)));
  109. #else
  110. logmgr_create(&g_mgr);
  111. #endif //_WIN32
  112. /*gcc error: lvalue required as unary ‘&’ operand*/
  113. //logmgr_create(&((logmgr_t*)(toolkit_getResource()->g_mgr)));
  114. singlefilefactory_create(&fac);
  115. #ifdef _WIN32
  116. logmgr_register_factory((logmgr_t*)(toolkit_getResource()->g_mgr), fac);
  117. periodicfilefactory_create(&fac);
  118. logmgr_register_factory((logmgr_t*)(toolkit_getResource()->g_mgr), fac);
  119. udplogfactory_create(&fac);
  120. logmgr_register_factory((logmgr_t*)(toolkit_getResource()->g_mgr), fac);
  121. udplogdaemonfactory_create(&fac);
  122. logmgr_register_factory((logmgr_t*)(toolkit_getResource()->g_mgr), fac);
  123. #else
  124. logmgr_register_factory((logmgr_t*)(g_mgr), fac);
  125. periodicfilefactory_create(&fac);
  126. logmgr_register_factory((logmgr_t*)(g_mgr), fac);
  127. udplogfactory_create(&fac);
  128. logmgr_register_factory((logmgr_t*)(g_mgr), fac);
  129. udplogdaemonfactory_create(&fac);
  130. logmgr_register_factory((logmgr_t*)(g_mgr), fac);
  131. #endif //_WIN32
  132. if (!file) {
  133. best_config_file = find_best_config();
  134. }
  135. //file为null,而且根据正常而言也搜索不到对应的配置
  136. if (best_config_file)
  137. {
  138. int i;
  139. array_header_t *arr_sec = inifile_read_section_all(best_config_file);
  140. if (arr_sec) {
  141. for (i = 0; i < arr_sec->nelts; ++i) {
  142. int found = 0;
  143. int kk;
  144. char *sec = ARRAY_IDX(arr_sec, i, char*);
  145. if (sections) {
  146. for (kk = 0; kk < arr_section->nelts; ++kk)
  147. if (_stricmp(sec, ARRAY_IDX(arr_section, kk, char*)) == 0)
  148. found = 1;
  149. }
  150. if (!sections || found) {
  151. array_header_t *arr_key = inifile_read_section_key_all(best_config_file, sec);
  152. if (arr_key) {
  153. char *type_tag = ARRAY_IDX(arr_key, 0, char*);
  154. if (type_tag && _stricmp(type_tag, "type") == 0) {
  155. char *type_value = inifile_read_str(best_config_file, sec, type_tag, "");
  156. if (type_value) {
  157. if (strlen(type_value) > 0) {
  158. logbase_t *log;
  159. #ifdef _WIN32
  160. rc = logmgr_create_log((logmgr_t*)(toolkit_getResource()->g_mgr), type_value, sec, &log);
  161. #else
  162. rc = logmgr_create_log((logmgr_t*)(g_mgr), type_value, sec, &log);
  163. #endif //_WIN32
  164. if (rc == 0) {
  165. int k;
  166. for (k = 1; k < arr_key->nelts; ++k) {
  167. char *key_tag = ARRAY_IDX(arr_key, k, char*);
  168. char *key_value = inifile_read_str(best_config_file, sec, key_tag, "");
  169. if (key_value) {
  170. logfactory_set_log_param(log->factory, log, key_tag, key_value);
  171. free(key_value);
  172. }
  173. }
  174. #ifdef _WIN32
  175. rc = logmgr_init_log((logmgr_t*)(toolkit_getResource()->g_mgr), log);
  176. if (rc != 0) {
  177. logmgr_destroy_log((logmgr_t*)(toolkit_getResource()->g_mgr), log);
  178. }
  179. #else
  180. rc = logmgr_init_log((logmgr_t*)(g_mgr), log);
  181. if (rc != 0) {
  182. logmgr_destroy_log((logmgr_t*)(g_mgr), log);
  183. }
  184. #endif //_WIN32
  185. }
  186. }
  187. free(type_value);
  188. }
  189. }
  190. array_free2(arr_key);
  191. }
  192. }
  193. }
  194. array_free2(arr_sec);
  195. }
  196. }
  197. //on_error:
  198. if (copysections)
  199. free(copysections);
  200. if (arr_section)
  201. array_free(arr_section);
  202. if (rc < 0) {
  203. #ifdef _WIN32
  204. logmgr_destroy((logmgr_t *)(toolkit_getResource()->g_mgr));
  205. (logmgr_t *)(toolkit_getResource()->g_mgr) = NULL;
  206. #else
  207. logmgr_destroy(g_mgr);
  208. g_mgr = NULL;
  209. #endif //_WIN32
  210. }
  211. return rc;
  212. }
  213. TOOLKIT_API int xlog_add_logger(const char *name, const char *type, ...)
  214. {
  215. logbase_t *log;
  216. int rc;
  217. if (!name || !strlen(name))
  218. return -1;
  219. if (!type || !strlen(type))
  220. return -1;
  221. #ifdef _WIN32
  222. rc = logmgr_create_log((logmgr_t*)(toolkit_getResource()->g_mgr), type, name, &log);
  223. #else
  224. rc = logmgr_create_log(g_mgr, type, name, &log);
  225. #endif //_WIN32
  226. if (rc == 0) {
  227. va_list arg;
  228. const char *key, *value;
  229. va_start(arg, type);
  230. key = va_arg(arg, const char*);
  231. while (key) {
  232. value = va_arg(arg, const char*);
  233. logfactory_set_log_param(log->factory, log, key, value);
  234. key = va_arg(arg, const char*);
  235. }
  236. va_end(arg);
  237. #ifdef _WIN32
  238. rc = logmgr_init_log((logmgr_t*)(toolkit_getResource()->g_mgr), log);
  239. if (rc != 0) {
  240. logmgr_destroy_log((logmgr_t*)(toolkit_getResource()->g_mgr), log);
  241. }
  242. #else
  243. rc = logmgr_init_log(g_mgr, log);
  244. if (rc != 0) {
  245. logmgr_destroy_log(g_mgr, log);
  246. }
  247. #endif //_WIN32
  248. }
  249. return rc;
  250. }
  251. TOOLKIT_API int xlog_remove_logger(const char *name)
  252. {
  253. logbase_t *log;
  254. #ifdef _WIN32
  255. if (name) {
  256. log = logmgr_find_log((logmgr_t*)(toolkit_getResource()->g_mgr), name);
  257. if (log) {
  258. logmgr_term_log((logmgr_t*)(toolkit_getResource()->g_mgr), log);
  259. logmgr_destroy_log((logmgr_t*)(toolkit_getResource()->g_mgr), log);
  260. return 0;
  261. }
  262. }
  263. #else
  264. if (name) {
  265. log = logmgr_find_log(g_mgr, name);
  266. if (log) {
  267. logmgr_term_log(g_mgr, log);
  268. logmgr_destroy_log(g_mgr, log);
  269. return 0;
  270. }
  271. }
  272. #endif //_WIN32
  273. return -1;
  274. }
  275. TOOLKIT_API int xlog_term()
  276. {
  277. #ifdef _WIN32
  278. toolkit_getResource()->g_initialized--;
  279. if (toolkit_getResource()->g_initialized) {
  280. return 0;
  281. }
  282. if ((logmgr_t*)(toolkit_getResource()->g_mgr)) {
  283. logmgr_destroy((logmgr_t*)(toolkit_getResource()->g_mgr));
  284. (toolkit_getResource()->g_mgr) = 0;
  285. winsock_term();
  286. return 0;
  287. }
  288. #else
  289. g_initialized--;
  290. if (g_initialized) {
  291. return 0;
  292. }
  293. if ((g_mgr)) {
  294. logmgr_destroy(g_mgr);
  295. g_mgr = 0;
  296. winsock_term();
  297. return 0;
  298. }
  299. #endif //_WIN32
  300. return -1;
  301. }
  302. TOOLKIT_API int xlog_set_level(const char* inst, int level)
  303. {
  304. if (!inst)
  305. return -1;
  306. #ifdef _WIN32
  307. if ((logmgr_t*)(toolkit_getResource()->g_mgr)) {
  308. logbase_t* log = logmgr_find_log((logmgr_t*)(toolkit_getResource()->g_mgr), inst);
  309. #else
  310. if ((logmgr_t*)(g_mgr)) {
  311. logbase_t* log = logmgr_find_log((logmgr_t*)(g_mgr), inst);
  312. #endif //_WIN32
  313. if (log) {
  314. log->level = level;
  315. return 0;
  316. }
  317. }
  318. return -1;
  319. }
  320. TOOLKIT_API int xlog_get_level(const char* inst, int *level)
  321. {
  322. if (!inst)
  323. return -1;
  324. #ifdef _WIN32
  325. if ((logmgr_t*)(toolkit_getResource()->g_mgr)) {
  326. logbase_t* log = logmgr_find_log((logmgr_t*)(toolkit_getResource()->g_mgr), inst);
  327. #else
  328. if ((logmgr_t*)(g_mgr)) {
  329. logbase_t* log = logmgr_find_log((logmgr_t*)(g_mgr), inst);
  330. #endif //_WIN32
  331. if (log) {
  332. *level = log->level;
  333. return 0;
  334. }
  335. }
  336. return -1;
  337. }
  338. TOOLKIT_API int xlog_log(const char *inst, int level, const char *str)
  339. {
  340. logbase_t *log;
  341. int n;
  342. #ifdef _WIN32
  343. if (!(logmgr_t*)(toolkit_getResource()->g_mgr))
  344. #else
  345. if (!g_mgr)
  346. #endif //_WIN32
  347. return -1;
  348. n = str ? strlen(str) : 0;
  349. if (n == 0)
  350. return 0;
  351. #ifdef _WIN32
  352. log = logmgr_find_log((logmgr_t*)(toolkit_getResource()->g_mgr), inst);
  353. if (log) {
  354. FILETIME ft;
  355. SYSTEMTIME st;
  356. GetSystemTime(&st);
  357. SystemTimeToFileTime(&st, &ft);
  358. logfactory_log_record(log->factory, log, level, ft.dwLowDateTime, ft.dwHighDateTime, str, n);
  359. return 0;
  360. }
  361. #else
  362. log = logmgr_find_log(g_mgr, inst);
  363. if (log) {
  364. FILETIME ft = {0, 0};
  365. logfactory_log_record(log->factory, log, level, ft.dwLowDateTime, ft.dwHighDateTime, str, n);
  366. return 0;
  367. }
  368. #endif //_WIN32
  369. return -1;
  370. }
  371. TOOLKIT_API int xlog_log_v(const char *inst, int level, const char *fmt, va_list arg)
  372. {
  373. int n;
  374. logbase_t *log;
  375. FILETIME ft;
  376. SYSTEMTIME st;
  377. #ifdef _WIN32
  378. if (!(logmgr_t*)(toolkit_getResource()->g_mgr))
  379. #else
  380. if (!g_mgr)
  381. #endif //_WIN32
  382. return -1;
  383. #ifdef _WIN32
  384. log = logmgr_find_log((logmgr_t*)(toolkit_getResource()->g_mgr), inst);
  385. #else
  386. log = logmgr_find_log(g_mgr, inst);
  387. #endif //_WIN32
  388. if (!log)
  389. return -1;
  390. #ifdef _WIN32
  391. GetSystemTime(&st);
  392. SystemTimeToFileTime(&st, &ft);
  393. #endif
  394. if (level < log->level)
  395. {
  396. logfactory_log_record(log->factory, log, level, ft.dwLowDateTime, ft.dwHighDateTime, NULL, 0);
  397. return 0;
  398. }
  399. n = _vscprintf(fmt, arg);//因为添加了Debug {}, 所以可能超过了1024长度
  400. if (n >= 0 && n < 1050) {
  401. char *buf = _alloca(n+1);
  402. vsprintf(buf, fmt, arg);
  403. logfactory_log_record(log->factory, log, level, ft.dwLowDateTime, ft.dwHighDateTime, buf, n);
  404. return 0;
  405. }
  406. return -1;
  407. }
  408. TOOLKIT_API logbase_t *xlog_find_log(const char *inst)
  409. {
  410. #ifdef _WIN32
  411. return logmgr_find_log((logmgr_t*)(toolkit_getResource()->g_mgr), inst);
  412. #else
  413. return logmgr_find_log(g_mgr, inst);
  414. #endif //_WIN32
  415. }