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