zlog.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025
  1. /*
  2. * This file is part of the zlog Library.
  3. *
  4. * Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
  5. *
  6. * Licensed under the LGPL v2.1, see the file COPYING in base directory.
  7. */
  8. #include "fmacros.h"
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <stdarg.h>
  12. #include <string.h>
  13. #include <pthread.h>
  14. #include "conf.h"
  15. #include "category_table.h"
  16. #include "record_table.h"
  17. #include "mdc.h"
  18. #include "zc_defs.h"
  19. #include "rule.h"
  20. #include "version.h"
  21. /*******************************************************************************/
  22. extern char *zlog_git_sha1;
  23. /*******************************************************************************/
  24. static pthread_rwlock_t zlog_env_lock = PTHREAD_RWLOCK_INITIALIZER;
  25. zlog_conf_t *zlog_env_conf;
  26. static pthread_key_t zlog_thread_key;
  27. static zc_hashtable_t *zlog_env_categories;
  28. static zc_hashtable_t *zlog_env_records;
  29. static zlog_category_t *zlog_default_category;
  30. static size_t zlog_env_reload_conf_count;
  31. static int zlog_env_is_init = 0;
  32. static int zlog_env_init_version = 0;
  33. /*******************************************************************************/
  34. /* inner no need thread-safe */
  35. static void zlog_fini_inner(void)
  36. {
  37. /* pthread_key_delete(zlog_thread_key); */
  38. /* never use pthread_key_delete,
  39. * it will cause other thread can't release zlog_thread_t
  40. * after one thread call pthread_key_delete
  41. * also key not init will cause a core dump
  42. */
  43. if (zlog_env_categories) zlog_category_table_del(zlog_env_categories);
  44. zlog_env_categories = NULL;
  45. zlog_default_category = NULL;
  46. if (zlog_env_records) zlog_record_table_del(zlog_env_records);
  47. zlog_env_records = NULL;
  48. if (zlog_env_conf) zlog_conf_del(zlog_env_conf);
  49. zlog_env_conf = NULL;
  50. return;
  51. }
  52. static void zlog_clean_rest_thread(void)
  53. {
  54. zlog_thread_t *a_thread;
  55. a_thread = pthread_getspecific(zlog_thread_key);
  56. if (!a_thread) return;
  57. zlog_thread_del(a_thread);
  58. return;
  59. }
  60. static int zlog_init_inner(const char *config)
  61. {
  62. int rc = 0;
  63. /* the 1st time in the whole process do init */
  64. if (zlog_env_init_version == 0) {
  65. /* clean up is done by OS when a thread call pthread_exit */
  66. rc = pthread_key_create(&zlog_thread_key, (void (*) (void *)) zlog_thread_del);
  67. if (rc) {
  68. zc_error("pthread_key_create fail, rc[%d]", rc);
  69. goto err;
  70. }
  71. /* if some thread do not call pthread_exit, like main thread
  72. * atexit will clean it
  73. */
  74. rc = atexit(zlog_clean_rest_thread);
  75. if (rc) {
  76. zc_error("atexit fail, rc[%d]", rc);
  77. goto err;
  78. }
  79. zlog_env_init_version++;
  80. } /* else maybe after zlog_fini() and need not create pthread_key */
  81. zlog_env_conf = zlog_conf_new(config);
  82. if (!zlog_env_conf) {
  83. zc_error("zlog_conf_new[%s] fail", config);
  84. goto err;
  85. }
  86. zlog_env_categories = zlog_category_table_new();
  87. if (!zlog_env_categories) {
  88. zc_error("zlog_category_table_new fail");
  89. goto err;
  90. }
  91. zlog_env_records = zlog_record_table_new();
  92. if (!zlog_env_records) {
  93. zc_error("zlog_record_table_new fail");
  94. goto err;
  95. }
  96. return 0;
  97. err:
  98. zlog_fini_inner();
  99. return -1;
  100. }
  101. /*******************************************************************************/
  102. int zlog_init(const char *config)
  103. {
  104. int rc;
  105. zc_debug("------zlog_init start------");
  106. zc_debug("------compile time[%s %s], version[%s]------", __DATE__, __TIME__, ZLOG_VERSION);
  107. rc = pthread_rwlock_wrlock(&zlog_env_lock);
  108. if (rc) {
  109. zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
  110. return -1;
  111. }
  112. if (zlog_env_is_init) {
  113. zc_error("already init, use zlog_reload pls");
  114. goto err;
  115. }
  116. if (zlog_init_inner(config)) {
  117. zc_error("zlog_init_inner[%s] fail", config);
  118. goto err;
  119. }
  120. zlog_env_is_init = 1;
  121. zlog_env_init_version++;
  122. zc_debug("------zlog_init success end------");
  123. rc = pthread_rwlock_unlock(&zlog_env_lock);
  124. if (rc) {
  125. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  126. return -1;
  127. }
  128. return 0;
  129. err:
  130. zc_error("------zlog_init fail end------");
  131. rc = pthread_rwlock_unlock(&zlog_env_lock);
  132. if (rc) {
  133. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  134. return -1;
  135. }
  136. return -1;
  137. }
  138. int dzlog_init(const char *config, const char *cname)
  139. {
  140. int rc = 0;
  141. zc_debug("------dzlog_init start------");
  142. zc_debug("------compile time[%s %s], version[%s]------",
  143. __DATE__, __TIME__, ZLOG_VERSION);
  144. rc = pthread_rwlock_wrlock(&zlog_env_lock);
  145. if (rc) {
  146. zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
  147. return -1;
  148. }
  149. if (zlog_env_is_init) {
  150. zc_error("already init, use zlog_reload pls");
  151. goto err;
  152. }
  153. if (zlog_init_inner(config)) {
  154. zc_error("zlog_init_inner[%s] fail", config);
  155. goto err;
  156. }
  157. zlog_default_category = zlog_category_table_fetch_category(
  158. zlog_env_categories,
  159. cname,
  160. zlog_env_conf->rules);
  161. if (!zlog_default_category) {
  162. zc_error("zlog_category_table_fetch_category[%s] fail", cname);
  163. goto err;
  164. }
  165. zlog_env_is_init = 1;
  166. zlog_env_init_version++;
  167. zc_debug("------dzlog_init success end------");
  168. rc = pthread_rwlock_unlock(&zlog_env_lock);
  169. if (rc) {
  170. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  171. return -1;
  172. }
  173. return 0;
  174. err:
  175. zc_error("------dzlog_init fail end------");
  176. rc = pthread_rwlock_unlock(&zlog_env_lock);
  177. if (rc) {
  178. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  179. return -1;
  180. }
  181. return -1;
  182. }
  183. /*******************************************************************************/
  184. int zlog_reload(const char *config)
  185. {
  186. int rc = 0;
  187. int i = 0;
  188. zlog_conf_t *new_conf = NULL;
  189. zlog_rule_t *a_rule;
  190. int c_up = 0;
  191. zc_debug("------zlog_reload start------");
  192. rc = pthread_rwlock_wrlock(&zlog_env_lock);
  193. if (rc) {
  194. zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
  195. return -1;
  196. }
  197. if (!zlog_env_is_init) {
  198. zc_error("never call zlog_init() or dzlog_init() before");
  199. goto quit;
  200. }
  201. /* use last conf file */
  202. if (config == NULL) config = zlog_env_conf->file;
  203. /* reach reload period */
  204. if (config == (char*)-1) {
  205. /* test again, avoid other threads already reloaded */
  206. if (zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period) {
  207. config = zlog_env_conf->file;
  208. } else {
  209. /* do nothing, already done */
  210. goto quit;
  211. }
  212. }
  213. /* reset counter, whether automaticlly or mannually */
  214. zlog_env_reload_conf_count = 0;
  215. new_conf = zlog_conf_new(config);
  216. if (!new_conf) {
  217. zc_error("zlog_conf_new fail");
  218. goto err;
  219. }
  220. zc_arraylist_foreach(new_conf->rules, i, a_rule) {
  221. zlog_rule_set_record(a_rule, zlog_env_records);
  222. }
  223. if (zlog_category_table_update_rules(zlog_env_categories, new_conf->rules)) {
  224. c_up = 0;
  225. zc_error("zlog_category_table_update fail");
  226. goto err;
  227. } else {
  228. c_up = 1;
  229. }
  230. zlog_env_init_version++;
  231. if (c_up) zlog_category_table_commit_rules(zlog_env_categories);
  232. zlog_conf_del(zlog_env_conf);
  233. zlog_env_conf = new_conf;
  234. zc_debug("------zlog_reload success, total init verison[%d] ------", zlog_env_init_version);
  235. rc = pthread_rwlock_unlock(&zlog_env_lock);
  236. if (rc) {
  237. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  238. return -1;
  239. }
  240. return 0;
  241. err:
  242. /* fail, roll back everything */
  243. zc_warn("zlog_reload fail, use old conf file, still working");
  244. if (new_conf) zlog_conf_del(new_conf);
  245. if (c_up) zlog_category_table_rollback_rules(zlog_env_categories);
  246. zc_error("------zlog_reload fail, total init version[%d] ------", zlog_env_init_version);
  247. rc = pthread_rwlock_unlock(&zlog_env_lock);
  248. if (rc) {
  249. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  250. return -1;
  251. }
  252. return -1;
  253. quit:
  254. zc_debug("------zlog_reload do nothing------");
  255. rc = pthread_rwlock_unlock(&zlog_env_lock);
  256. if (rc) {
  257. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  258. return -1;
  259. }
  260. return 0;
  261. }
  262. /*******************************************************************************/
  263. void zlog_fini(void)
  264. {
  265. int rc = 0;
  266. zc_debug("------zlog_fini start------");
  267. rc = pthread_rwlock_wrlock(&zlog_env_lock);
  268. if (rc) {
  269. zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
  270. return;
  271. }
  272. if (!zlog_env_is_init) {
  273. zc_error("before finish, must zlog_init() or dzlog_init() first");
  274. goto exit;
  275. }
  276. zlog_fini_inner();
  277. zlog_env_is_init = 0;
  278. exit:
  279. zc_debug("------zlog_fini end------");
  280. rc = pthread_rwlock_unlock(&zlog_env_lock);
  281. if (rc) {
  282. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  283. return;
  284. }
  285. return;
  286. }
  287. /*******************************************************************************/
  288. zlog_category_t *zlog_get_category(const char *cname)
  289. {
  290. int rc = 0;
  291. zlog_category_t *a_category = NULL;
  292. zc_assert(cname, NULL);
  293. zc_debug("------zlog_get_category[%s] start------", cname);
  294. rc = pthread_rwlock_wrlock(&zlog_env_lock);
  295. if (rc) {
  296. zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
  297. return NULL;
  298. }
  299. if (!zlog_env_is_init) {
  300. zc_error("never call zlog_init() or dzlog_init() before");
  301. a_category = NULL;
  302. goto err;
  303. }
  304. a_category = zlog_category_table_fetch_category(
  305. zlog_env_categories,
  306. cname,
  307. zlog_env_conf->rules);
  308. if (!a_category) {
  309. zc_error("zlog_category_table_fetch_category[%s] fail", cname);
  310. goto err;
  311. }
  312. zc_debug("------zlog_get_category[%s] success, end------ ", cname);
  313. rc = pthread_rwlock_unlock(&zlog_env_lock);
  314. if (rc) {
  315. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  316. return NULL;
  317. }
  318. return a_category;
  319. err:
  320. zc_error("------zlog_get_category[%s] fail, end------ ", cname);
  321. rc = pthread_rwlock_unlock(&zlog_env_lock);
  322. if (rc) {
  323. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  324. return NULL;
  325. }
  326. return NULL;
  327. }
  328. int dzlog_set_category(const char *cname)
  329. {
  330. int rc = 0;
  331. zc_assert(cname, -1);
  332. zc_debug("------dzlog_set_category[%s] start------", cname);
  333. rc = pthread_rwlock_wrlock(&zlog_env_lock);
  334. if (rc) {
  335. zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
  336. return -1;
  337. }
  338. if (!zlog_env_is_init) {
  339. zc_error("never call zlog_init() or dzlog_init() before");
  340. goto err;
  341. }
  342. zlog_default_category = zlog_category_table_fetch_category(
  343. zlog_env_categories,
  344. cname,
  345. zlog_env_conf->rules);
  346. if (!zlog_default_category) {
  347. zc_error("zlog_category_table_fetch_category[%s] fail", cname);
  348. goto err;
  349. }
  350. zc_debug("------dzlog_set_category[%s] end, success------ ", cname);
  351. rc = pthread_rwlock_unlock(&zlog_env_lock);
  352. if (rc) {
  353. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  354. return -1;
  355. }
  356. return 0;
  357. err:
  358. zc_error("------dzlog_set_category[%s] end, fail------ ", cname);
  359. rc = pthread_rwlock_unlock(&zlog_env_lock);
  360. if (rc) {
  361. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  362. return -1;
  363. }
  364. return -1;
  365. }
  366. /*******************************************************************************/
  367. #define zlog_fetch_thread(a_thread, fail_goto) do { \
  368. int rd = 0; \
  369. a_thread = pthread_getspecific(zlog_thread_key); \
  370. if (!a_thread) { \
  371. a_thread = zlog_thread_new(zlog_env_init_version, \
  372. zlog_env_conf->buf_size_min, zlog_env_conf->buf_size_max, \
  373. zlog_env_conf->time_cache_count); \
  374. if (!a_thread) { \
  375. zc_error("zlog_thread_new fail"); \
  376. goto fail_goto; \
  377. } \
  378. \
  379. rd = pthread_setspecific(zlog_thread_key, a_thread); \
  380. if (rd) { \
  381. zlog_thread_del(a_thread); \
  382. zc_error("pthread_setspecific fail, rd[%d]", rd); \
  383. goto fail_goto; \
  384. } \
  385. } \
  386. \
  387. if (a_thread->init_version != zlog_env_init_version) { \
  388. /* as mdc is still here, so can not easily del and new */ \
  389. rd = zlog_thread_rebuild_msg_buf(a_thread, \
  390. zlog_env_conf->buf_size_min, \
  391. zlog_env_conf->buf_size_max); \
  392. if (rd) { \
  393. zc_error("zlog_thread_resize_msg_buf fail, rd[%d]", rd); \
  394. goto fail_goto; \
  395. } \
  396. \
  397. rd = zlog_thread_rebuild_event(a_thread, zlog_env_conf->time_cache_count); \
  398. if (rd) { \
  399. zc_error("zlog_thread_resize_msg_buf fail, rd[%d]", rd); \
  400. goto fail_goto; \
  401. } \
  402. a_thread->init_version = zlog_env_init_version; \
  403. } \
  404. } while (0)
  405. /*******************************************************************************/
  406. int zlog_put_mdc(const char *key, const char *value)
  407. {
  408. int rc = 0;
  409. zlog_thread_t *a_thread;
  410. zc_assert(key, -1);
  411. zc_assert(value, -1);
  412. rc = pthread_rwlock_rdlock(&zlog_env_lock);
  413. if (rc) {
  414. zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
  415. return -1;
  416. }
  417. if (!zlog_env_is_init) {
  418. zc_error("never call zlog_init() or dzlog_init() before");
  419. goto err;
  420. }
  421. zlog_fetch_thread(a_thread, err);
  422. if (zlog_mdc_put(a_thread->mdc, key, value)) {
  423. zc_error("zlog_mdc_put fail, key[%s], value[%s]", key, value);
  424. goto err;
  425. }
  426. rc = pthread_rwlock_unlock(&zlog_env_lock);
  427. if (rc) {
  428. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  429. return -1;
  430. }
  431. return 0;
  432. err:
  433. rc = pthread_rwlock_unlock(&zlog_env_lock);
  434. if (rc) {
  435. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  436. return -1;
  437. }
  438. return -1;
  439. }
  440. char *zlog_get_mdc(char *key)
  441. {
  442. int rc = 0;
  443. char *value = NULL;
  444. zlog_thread_t *a_thread;
  445. zc_assert(key, NULL);
  446. rc = pthread_rwlock_rdlock(&zlog_env_lock);
  447. if (rc) {
  448. zc_error("pthread_rwlock_rdlock fail, rc[%d]", rc);
  449. return NULL;
  450. }
  451. if (!zlog_env_is_init) {
  452. zc_error("never call zlog_init() or dzlog_init() before");
  453. goto err;
  454. }
  455. a_thread = pthread_getspecific(zlog_thread_key);
  456. if (!a_thread) {
  457. zc_error("thread not found, maybe not use zlog_put_mdc before");
  458. goto err;
  459. }
  460. value = zlog_mdc_get(a_thread->mdc, key);
  461. if (!value) {
  462. zc_error("key[%s] not found in mdc", key);
  463. goto err;
  464. }
  465. rc = pthread_rwlock_unlock(&zlog_env_lock);
  466. if (rc) {
  467. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  468. return NULL;
  469. }
  470. return value;
  471. err:
  472. rc = pthread_rwlock_unlock(&zlog_env_lock);
  473. if (rc) {
  474. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  475. return NULL;
  476. }
  477. return NULL;
  478. }
  479. void zlog_remove_mdc(char *key)
  480. {
  481. int rc = 0;
  482. zlog_thread_t *a_thread;
  483. zc_assert(key, );
  484. rc = pthread_rwlock_rdlock(&zlog_env_lock);
  485. if (rc) {
  486. zc_error("pthread_rwlock_rdlock fail, rc[%d]", rc);
  487. return;
  488. }
  489. if (!zlog_env_is_init) {
  490. zc_error("never call zlog_init() or dzlog_init() before");
  491. goto exit;
  492. }
  493. a_thread = pthread_getspecific(zlog_thread_key);
  494. if (!a_thread) {
  495. zc_error("thread not found, maybe not use zlog_put_mdc before");
  496. goto exit;
  497. }
  498. zlog_mdc_remove(a_thread->mdc, key);
  499. exit:
  500. rc = pthread_rwlock_unlock(&zlog_env_lock);
  501. if (rc) {
  502. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  503. return;
  504. }
  505. return;
  506. }
  507. void zlog_clean_mdc(void)
  508. {
  509. int rc = 0;
  510. zlog_thread_t *a_thread;
  511. rc = pthread_rwlock_rdlock(&zlog_env_lock);
  512. if (rc) {;
  513. zc_error("pthread_rwlock_rdlock fail, rc[%d]", rc);
  514. return;
  515. }
  516. if (!zlog_env_is_init) {
  517. zc_error("never call zlog_init() or dzlog_init() before");
  518. goto exit;
  519. }
  520. a_thread = pthread_getspecific(zlog_thread_key);
  521. if (!a_thread) {
  522. zc_error("thread not found, maybe not use zlog_put_mdc before");
  523. goto exit;
  524. }
  525. zlog_mdc_clean(a_thread->mdc);
  526. exit:
  527. rc = pthread_rwlock_unlock(&zlog_env_lock);
  528. if (rc) {
  529. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  530. return;
  531. }
  532. return;
  533. }
  534. int zlog_level_switch(zlog_category_t * category, int level)
  535. {
  536. // This is NOT thread safe.
  537. memset(category->level_bitmap, 0x00, sizeof(category->level_bitmap));
  538. category->level_bitmap[level / 8] |= ~(0xFF << (8 - level % 8));
  539. memset(category->level_bitmap + level / 8 + 1, 0xFF,
  540. sizeof(category->level_bitmap) - level / 8 - 1);
  541. return 0;
  542. }
  543. /*******************************************************************************/
  544. void vzlog(zlog_category_t * category,
  545. const char *file, size_t filelen,
  546. const char *func, size_t funclen,
  547. long line, int level,
  548. const char *format, va_list args)
  549. {
  550. zlog_thread_t *a_thread;
  551. /* The bitmap determination here is not under the protection of rdlock.
  552. * It may be changed by other CPU by zlog_reload() halfway.
  553. *
  554. * Old or strange value may be read here,
  555. * but it is safe, the bitmap is valid as long as category exist,
  556. * And will be the right value after zlog_reload()
  557. *
  558. * For speed up, if one log will not be ouput,
  559. * There is no need to aquire rdlock.
  560. */
  561. if (zlog_category_needless_level(category, level)) return;
  562. pthread_rwlock_rdlock(&zlog_env_lock);
  563. if (!zlog_env_is_init) {
  564. zc_error("never call zlog_init() or dzlog_init() before");
  565. goto exit;
  566. }
  567. zlog_fetch_thread(a_thread, exit);
  568. zlog_event_set_fmt(a_thread->event,
  569. category->name, category->name_len,
  570. file, filelen, func, funclen, line, level,
  571. format, args);
  572. if (zlog_category_output(category, a_thread)) {
  573. zc_error("zlog_output fail, srcfile[%s], srcline[%ld]", file, line);
  574. goto exit;
  575. }
  576. if (zlog_env_conf->reload_conf_period &&
  577. ++zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period ) {
  578. /* under the protection of lock read env conf */
  579. goto reload;
  580. }
  581. exit:
  582. pthread_rwlock_unlock(&zlog_env_lock);
  583. return;
  584. reload:
  585. pthread_rwlock_unlock(&zlog_env_lock);
  586. /* will be wrlock, so after unlock */
  587. if (zlog_reload((char *)-1)) {
  588. zc_error("reach reload-conf-period but zlog_reload fail, zlog-chk-conf [file] see detail");
  589. }
  590. return;
  591. }
  592. void hzlog(zlog_category_t *category,
  593. const char *file, size_t filelen,
  594. const char *func, size_t funclen,
  595. long line, int level,
  596. const void *buf, size_t buflen)
  597. {
  598. zlog_thread_t *a_thread;
  599. if (zlog_category_needless_level(category, level)) return;
  600. pthread_rwlock_rdlock(&zlog_env_lock);
  601. if (!zlog_env_is_init) {
  602. zc_error("never call zlog_init() or dzlog_init() before");
  603. goto exit;
  604. }
  605. zlog_fetch_thread(a_thread, exit);
  606. zlog_event_set_hex(a_thread->event,
  607. category->name, category->name_len,
  608. file, filelen, func, funclen, line, level,
  609. buf, buflen);
  610. if (zlog_category_output(category, a_thread)) {
  611. zc_error("zlog_output fail, srcfile[%s], srcline[%ld]", file, line);
  612. goto exit;
  613. }
  614. if (zlog_env_conf->reload_conf_period &&
  615. ++zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period ) {
  616. /* under the protection of lock read env conf */
  617. goto reload;
  618. }
  619. exit:
  620. pthread_rwlock_unlock(&zlog_env_lock);
  621. return;
  622. reload:
  623. pthread_rwlock_unlock(&zlog_env_lock);
  624. /* will be wrlock, so after unlock */
  625. if (zlog_reload((char *)-1)) {
  626. zc_error("reach reload-conf-period but zlog_reload fail, zlog-chk-conf [file] see detail");
  627. }
  628. return;
  629. }
  630. /*******************************************************************************/
  631. /* for speed up, copy from vzlog */
  632. void vdzlog(const char *file, size_t filelen,
  633. const char *func, size_t funclen,
  634. long line, int level,
  635. const char *format, va_list args)
  636. {
  637. zlog_thread_t *a_thread;
  638. if (zlog_category_needless_level(zlog_default_category, level)) return;
  639. pthread_rwlock_rdlock(&zlog_env_lock);
  640. if (!zlog_env_is_init) {
  641. zc_error("never call zlog_init() or dzlog_init() before");
  642. goto exit;
  643. }
  644. /* that's the differnce, must judge default_category in lock */
  645. if (!zlog_default_category) {
  646. zc_error("zlog_default_category is null,"
  647. "dzlog_init() or dzlog_set_cateogry() is not called above");
  648. goto exit;
  649. }
  650. zlog_fetch_thread(a_thread, exit);
  651. zlog_event_set_fmt(a_thread->event,
  652. zlog_default_category->name, zlog_default_category->name_len,
  653. file, filelen, func, funclen, line, level,
  654. format, args);
  655. if (zlog_category_output(zlog_default_category, a_thread)) {
  656. zc_error("zlog_output fail, srcfile[%s], srcline[%ld]", file, line);
  657. goto exit;
  658. }
  659. if (zlog_env_conf->reload_conf_period &&
  660. ++zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period ) {
  661. /* under the protection of lock read env conf */
  662. goto reload;
  663. }
  664. exit:
  665. pthread_rwlock_unlock(&zlog_env_lock);
  666. return;
  667. reload:
  668. pthread_rwlock_unlock(&zlog_env_lock);
  669. /* will be wrlock, so after unlock */
  670. if (zlog_reload((char *)-1)) {
  671. zc_error("reach reload-conf-period but zlog_reload fail, zlog-chk-conf [file] see detail");
  672. }
  673. return;
  674. }
  675. void hdzlog(const char *file, size_t filelen,
  676. const char *func, size_t funclen,
  677. long line, int level,
  678. const void *buf, size_t buflen)
  679. {
  680. zlog_thread_t *a_thread;
  681. if (zlog_category_needless_level(zlog_default_category, level)) return;
  682. pthread_rwlock_rdlock(&zlog_env_lock);
  683. if (!zlog_env_is_init) {
  684. zc_error("never call zlog_init() or dzlog_init() before");
  685. goto exit;
  686. }
  687. /* that's the differnce, must judge default_category in lock */
  688. if (!zlog_default_category) {
  689. zc_error("zlog_default_category is null,"
  690. "dzlog_init() or dzlog_set_cateogry() is not called above");
  691. goto exit;
  692. }
  693. zlog_fetch_thread(a_thread, exit);
  694. zlog_event_set_hex(a_thread->event,
  695. zlog_default_category->name, zlog_default_category->name_len,
  696. file, filelen, func, funclen, line, level,
  697. buf, buflen);
  698. if (zlog_category_output(zlog_default_category, a_thread)) {
  699. zc_error("zlog_output fail, srcfile[%s], srcline[%ld]", file, line);
  700. goto exit;
  701. }
  702. if (zlog_env_conf->reload_conf_period &&
  703. ++zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period ) {
  704. /* under the protection of lock read env conf */
  705. goto reload;
  706. }
  707. exit:
  708. pthread_rwlock_unlock(&zlog_env_lock);
  709. return;
  710. reload:
  711. pthread_rwlock_unlock(&zlog_env_lock);
  712. /* will be wrlock, so after unlock */
  713. if (zlog_reload((char *)-1)) {
  714. zc_error("reach reload-conf-period but zlog_reload fail, zlog-chk-conf [file] see detail");
  715. }
  716. return;
  717. }
  718. /*******************************************************************************/
  719. void zlog(zlog_category_t * category,
  720. const char *file, size_t filelen, const char *func, size_t funclen,
  721. long line, const int level,
  722. const char *format, ...)
  723. {
  724. zlog_thread_t *a_thread;
  725. va_list args;
  726. if (category && zlog_category_needless_level(category, level)) return;
  727. pthread_rwlock_rdlock(&zlog_env_lock);
  728. if (!zlog_env_is_init) {
  729. zc_error("never call zlog_init() or dzlog_init() before");
  730. goto exit;
  731. }
  732. zlog_fetch_thread(a_thread, exit);
  733. va_start(args, format);
  734. zlog_event_set_fmt(a_thread->event, category->name, category->name_len,
  735. file, filelen, func, funclen, line, level,
  736. format, args);
  737. if (zlog_category_output(category, a_thread)) {
  738. zc_error("zlog_output fail, srcfile[%s], srcline[%ld]", file, line);
  739. va_end(args);
  740. goto exit;
  741. }
  742. va_end(args);
  743. if (zlog_env_conf->reload_conf_period &&
  744. ++zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period ) {
  745. /* under the protection of lock read env conf */
  746. goto reload;
  747. }
  748. exit:
  749. pthread_rwlock_unlock(&zlog_env_lock);
  750. return;
  751. reload:
  752. pthread_rwlock_unlock(&zlog_env_lock);
  753. /* will be wrlock, so after unlock */
  754. if (zlog_reload((char *)-1)) {
  755. zc_error("reach reload-conf-period but zlog_reload fail, zlog-chk-conf [file] see detail");
  756. }
  757. return;
  758. }
  759. /*******************************************************************************/
  760. void dzlog(const char *file, size_t filelen, const char *func, size_t funclen, long line, int level,
  761. const char *format, ...)
  762. {
  763. zlog_thread_t *a_thread;
  764. va_list args;
  765. pthread_rwlock_rdlock(&zlog_env_lock);
  766. if (!zlog_env_is_init) {
  767. zc_error("never call zlog_init() or dzlog_init() before");
  768. goto exit;
  769. }
  770. /* that's the differnce, must judge default_category in lock */
  771. if (!zlog_default_category) {
  772. zc_error("zlog_default_category is null,"
  773. "dzlog_init() or dzlog_set_cateogry() is not called above");
  774. goto exit;
  775. }
  776. if (zlog_category_needless_level(zlog_default_category, level)) goto exit;
  777. zlog_fetch_thread(a_thread, exit);
  778. va_start(args, format);
  779. zlog_event_set_fmt(a_thread->event,
  780. zlog_default_category->name, zlog_default_category->name_len,
  781. file, filelen, func, funclen, line, level,
  782. format, args);
  783. if (zlog_category_output(zlog_default_category, a_thread)) {
  784. zc_error("zlog_output fail, srcfile[%s], srcline[%ld]", file, line);
  785. va_end(args);
  786. goto exit;
  787. }
  788. va_end(args);
  789. if (zlog_env_conf->reload_conf_period &&
  790. ++zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period ) {
  791. /* under the protection of lock read env conf */
  792. goto reload;
  793. }
  794. exit:
  795. pthread_rwlock_unlock(&zlog_env_lock);
  796. return;
  797. reload:
  798. pthread_rwlock_unlock(&zlog_env_lock);
  799. /* will be wrlock, so after unlock */
  800. if (zlog_reload((char *)-1)) {
  801. zc_error("reach reload-conf-period but zlog_reload fail, zlog-chk-conf [file] see detail");
  802. }
  803. return;
  804. }
  805. /*******************************************************************************/
  806. void zlog_profile(void)
  807. {
  808. int rc = 0;
  809. rc = pthread_rwlock_rdlock(&zlog_env_lock);
  810. if (rc) {
  811. zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
  812. return;
  813. }
  814. zc_warn("------zlog_profile start------ ");
  815. zc_warn("is init:[%d]", zlog_env_is_init);
  816. zc_warn("init version:[%d]", zlog_env_init_version);
  817. zlog_conf_profile(zlog_env_conf, ZC_WARN);
  818. zlog_record_table_profile(zlog_env_records, ZC_WARN);
  819. zlog_category_table_profile(zlog_env_categories, ZC_WARN);
  820. if (zlog_default_category) {
  821. zc_warn("-default_category-");
  822. zlog_category_profile(zlog_default_category, ZC_WARN);
  823. }
  824. zc_warn("------zlog_profile end------ ");
  825. rc = pthread_rwlock_unlock(&zlog_env_lock);
  826. if (rc) {
  827. zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
  828. return;
  829. }
  830. return;
  831. }
  832. /*******************************************************************************/
  833. int zlog_set_record(const char *rname, zlog_record_fn record_output)
  834. {
  835. int rc = 0;
  836. int rd = 0;
  837. zlog_rule_t *a_rule;
  838. zlog_record_t *a_record;
  839. int i = 0;
  840. zc_assert(rname, -1);
  841. zc_assert(record_output, -1);
  842. rd = pthread_rwlock_wrlock(&zlog_env_lock);
  843. if (rd) {
  844. zc_error("pthread_rwlock_rdlock fail, rd[%d]", rd);
  845. return -1;
  846. }
  847. if (!zlog_env_is_init) {
  848. zc_error("never call zlog_init() or dzlog_init() before");
  849. goto zlog_set_record_exit;
  850. }
  851. a_record = zlog_record_new(rname, record_output);
  852. if (!a_record) {
  853. rc = -1;
  854. zc_error("zlog_record_new fail");
  855. goto zlog_set_record_exit;
  856. }
  857. rc = zc_hashtable_put(zlog_env_records, a_record->name, a_record);
  858. if (rc) {
  859. zlog_record_del(a_record);
  860. zc_error("zc_hashtable_put fail");
  861. goto zlog_set_record_exit;
  862. }
  863. zc_arraylist_foreach(zlog_env_conf->rules, i, a_rule) {
  864. zlog_rule_set_record(a_rule, zlog_env_records);
  865. }
  866. zlog_set_record_exit:
  867. rd = pthread_rwlock_unlock(&zlog_env_lock);
  868. if (rd) {
  869. zc_error("pthread_rwlock_unlock fail, rd=[%d]", rd);
  870. return -1;
  871. }
  872. return rc;
  873. }
  874. /*******************************************************************************/
  875. int zlog_level_enabled(zlog_category_t *category, const int level)
  876. {
  877. return category && (zlog_category_needless_level(category, level) == 0);
  878. }
  879. const char *zlog_version(void) { return ZLOG_VERSION; }