diff --git a/libzlog/category.c b/libzlog/category.c index d707bd3d..86051d86 100644 --- a/libzlog/category.c +++ b/libzlog/category.c @@ -53,6 +53,18 @@ void zlog_category_del(zlog_category_t * a_category) return; } +/* overlap one rule's level bitmap to cateogry, + * so category can judge whether a log level will be output by itself + * It is safe when configure is reloaded, when rule will be released an recreated + */ +static void zlog_cateogry_overlap_bitmap(zlog_category_t * a_category, zlog_rule_t *a_rule) +{ + int i; + for(i = 0; i < sizeof(a_rule->level_bitmap); i++) { + a_category->level_bitmap[i] |= a_rule->level_bitmap[i]; + } +} + static int zlog_category_obtain_rules(zlog_category_t * a_category, zc_arraylist_t * rules) { int i; @@ -64,6 +76,8 @@ static int zlog_category_obtain_rules(zlog_category_t * a_category, zc_arraylist /* before set, clean last fit rules first */ if (a_category->fit_rules) zc_arraylist_del(a_category->fit_rules); + memset(a_category->level_bitmap, 0x00, sizeof(a_category->level_bitmap)); + a_category->fit_rules = zc_arraylist_new(NULL); if (!(a_category->fit_rules)) { zc_error("zc_arraylist_new fail"); @@ -78,6 +92,7 @@ static int zlog_category_obtain_rules(zlog_category_t * a_category, zc_arraylist zc_error("zc_arrylist_add fail"); goto err; } + zlog_cateogry_overlap_bitmap(a_category, a_rule); count++; } @@ -93,6 +108,7 @@ static int zlog_category_obtain_rules(zlog_category_t * a_category, zc_arraylist zc_error("zc_arrylist_add fail"); goto err; } + zlog_cateogry_overlap_bitmap(a_category, wastebin_rule); count++; } else { zc_debug("category[%s], no match rules & no wastebin_rule", a_category->name); @@ -149,6 +165,9 @@ int zlog_category_update_rules(zlog_category_t * a_category, zc_arraylist_t * ne if (a_category->fit_rules_backup) zc_arraylist_del(a_category->fit_rules_backup); a_category->fit_rules_backup = a_category->fit_rules; a_category->fit_rules = NULL; + + memcpy(a_category->level_bitmap_backup, a_category->level_bitmap, + sizeof(a_category->level_bitmap)); /* 2nd, obtain new_rules to fit_rules */ if (zlog_category_obtain_rules(a_category, new_rules)) { @@ -173,6 +192,8 @@ void zlog_category_commit_rules(zlog_category_t * a_category) zc_arraylist_del(a_category->fit_rules_backup); a_category->fit_rules_backup = NULL; + memset(a_category->level_bitmap_backup, 0x00, + sizeof(a_category->level_bitmap_backup)); return; } @@ -197,6 +218,12 @@ void zlog_category_rollback_rules(zlog_category_t * a_category) a_category->fit_rules = a_category->fit_rules_backup; a_category->fit_rules_backup = NULL; } + + memcpy(a_category->level_bitmap, a_category->level_bitmap_backup, + sizeof(a_category->level_bitmap)); + memset(a_category->level_bitmap_backup, 0x00, + sizeof(a_category->level_bitmap_backup)); + return; /* always success */ } @@ -224,11 +251,10 @@ int zlog_category_output(zlog_category_t * a_category, zlog_thread_t * a_thread) int zlog_category_should_ouput(zlog_category_t * a_category, int level) { - int i, r; + int i; zlog_rule_t *a_rule; zc_arraylist_foreach(a_category->fit_rules, i, a_rule) { - zlog_rule_should_output(a_rule, level, r); - if (r) return 1; + if (zlog_rule_should_output(a_rule, level)) return 1; } return 0; diff --git a/libzlog/category.h b/libzlog/category.h index 03bf6a40..e5a2091d 100644 --- a/libzlog/category.h +++ b/libzlog/category.h @@ -26,6 +26,8 @@ typedef struct zlog_category_s { char name[MAXLEN_PATH + 1]; size_t name_len; + unsigned char level_bitmap[32]; + unsigned char level_bitmap_backup[32]; zc_arraylist_t *fit_rules; zc_arraylist_t *fit_rules_backup; } zlog_category_t; @@ -41,6 +43,8 @@ void zlog_category_rollback_rules(zlog_category_t * a_category); int zlog_category_output(zlog_category_t * a_category, zlog_thread_t * a_thread); -int zlog_category_should_ouput(zlog_category_t * a_category, int level); +#define zlog_category_needless_level(a_category, lv) \ + !((a_category->level_bitmap[lv/8] >> (7 - lv % 8)) & 0x01) + #endif diff --git a/libzlog/rule.c b/libzlog/rule.c index ccf3f535..ee795ead 100644 --- a/libzlog/rule.c +++ b/libzlog/rule.c @@ -519,6 +519,30 @@ zlog_rule_t *zlog_rule_new(char *line, } a_rule->level = zlog_level_list_atoi(a_rule->levels, p); + /* level_bit is a bitmap represents which level can be output + * 32bytes, [0-255] levels, see level.c + * which bit field is 1 means allow output and 0 not + */ + switch (a_rule->compare_char) { + case '=': + memset(a_rule->level_bitmap, 0x00, sizeof(a_rule->level_bitmap)); + a_rule->level_bitmap[a_rule->level / 8] |= (1 << (7 - a_rule->level % 8)); + break; + case '!': + memset(a_rule->level_bitmap, 0xFF, sizeof(a_rule->level_bitmap)); + a_rule->level_bitmap[a_rule->level / 8] &= ~(1 << (7 - a_rule->level % 8)); + break; + case '*': + memset(a_rule->level_bitmap, 0xFF, sizeof(a_rule->level_bitmap)); + break; + case '.': + memset(a_rule->level_bitmap, 0x00, sizeof(a_rule->level_bitmap)); + a_rule->level_bitmap[a_rule->level / 8] |= ~(0xFF << (8 - a_rule->level % 8)); + memset(a_rule->level_bitmap + a_rule->level / 8 + 1, 0xFF, + sizeof(a_rule->level_bitmap) - a_rule->level / 8 - 1); + break; + } + /* action ["%H/log/aa.log", 20MB * 12 ; MyTemplate] * output ["%H/log/aa.log", 20MB * 12] * format [MyTemplate] diff --git a/libzlog/rule.h b/libzlog/rule.h index cecbb28c..86d4b995 100644 --- a/libzlog/rule.h +++ b/libzlog/rule.h @@ -39,7 +39,6 @@ typedef int (*zlog_rule_output_fn) (zlog_rule_t * a_rule, zlog_thread_t * a_thre struct zlog_rule_s { char category[MAXLEN_CFG_LINE + 1]; - int level; char compare_char; /* * [*] log all level @@ -47,6 +46,8 @@ struct zlog_rule_s { * [=] log level == rule level * [!] log level != rule level */ + int level; + unsigned char level_bitmap[32]; char file_path[MAXLEN_PATH + 1]; zc_arraylist_t *dynamic_file_specs; @@ -115,8 +116,6 @@ int zlog_rule_output(zlog_rule_t * a_rule, zlog_thread_t * a_thread); break; \ } \ } while(0) -#endif - #define zlog_rule_should_output(a_rule, l, result) do { \ switch (a_rule->compare_char) { \ case '*' : \ @@ -133,6 +132,11 @@ int zlog_rule_output(zlog_rule_t * a_rule, zlog_thread_t * a_thread); break; \ } \ } while(0) +#endif + + +#define zlog_rule_should_output(a_rule, l) \ + ((a_rule->level_bitmap[l/8] >> (7 - l % 8)) & 0x01) #endif diff --git a/libzlog/zlog.c b/libzlog/zlog.c index 2cf61931..f58b0a07 100644 --- a/libzlog/zlog.c +++ b/libzlog/zlog.c @@ -604,6 +604,18 @@ void vzlog(zlog_category_t * category, { zlog_thread_t *a_thread; + /* The bitmap determination here is not under the protection of rdlock. + * It may be changed by other CPU by zlog_reload() halfway. + * + * Old or strange value may be read here, + * but it is safe, the bitmap is valid as long as category exist, + * And will be the right value after zlog_reload() + * + * For speed up, if one log will not be ouput, + * There is no need to aquire rdlock. + */ + if (zlog_category_needless_level(category, level)) return; + pthread_rwlock_rdlock(&zlog_env_lock); if (zlog_env_init_flag < 0) { @@ -611,10 +623,6 @@ void vzlog(zlog_category_t * category, goto exit; } - if (!zlog_category_should_ouput(category, level)) { - goto exit; - } - a_thread = pthread_getspecific(zlog_thread_key); if (!a_thread) { pthread_rwlock_unlock(&zlog_env_lock); @@ -665,6 +673,8 @@ void hzlog(zlog_category_t *category, { zlog_thread_t *a_thread; + if (zlog_category_needless_level(category, level)) return; + pthread_rwlock_rdlock(&zlog_env_lock); if (zlog_env_init_flag < 0) { @@ -672,10 +682,6 @@ void hzlog(zlog_category_t *category, goto exit; } - if (!zlog_category_should_ouput(category, level)) { - goto exit; - } - a_thread = pthread_getspecific(zlog_thread_key); if (!a_thread) { pthread_rwlock_unlock(&zlog_env_lock); @@ -727,6 +733,8 @@ void vdzlog(const char *file, size_t filelen, { zlog_thread_t *a_thread; + if (zlog_category_needless_level(zlog_default_category, level)) return; + pthread_rwlock_rdlock(&zlog_env_lock); if (zlog_env_init_flag < 0) { @@ -741,10 +749,6 @@ void vdzlog(const char *file, size_t filelen, goto exit; } - if (!zlog_category_should_ouput(zlog_default_category, level)) { - goto exit; - } - a_thread = pthread_getspecific(zlog_thread_key); if (!a_thread) { pthread_rwlock_unlock(&zlog_env_lock); @@ -794,6 +798,8 @@ void hdzlog(const char *file, size_t filelen, { zlog_thread_t *a_thread; + if (zlog_category_needless_level(zlog_default_category, level)) return; + pthread_rwlock_rdlock(&zlog_env_lock); if (zlog_env_init_flag < 0) { @@ -808,10 +814,6 @@ void hdzlog(const char *file, size_t filelen, goto exit; } - if (!zlog_category_should_ouput(zlog_default_category, level)) { - goto exit; - } - a_thread = pthread_getspecific(zlog_thread_key); if (!a_thread) { pthread_rwlock_unlock(&zlog_env_lock); @@ -863,6 +865,10 @@ void zlog(zlog_category_t * category, zlog_thread_t *a_thread; va_list args; + zc_error("%d", ((category->level_bitmap[level/8] >> (7 - level % 8)) & 0x01)); + zc_error("%d", zlog_category_needless_level(category, level)); + if (zlog_category_needless_level(category, level)) return; + pthread_rwlock_rdlock(&zlog_env_lock); if (zlog_env_init_flag < 0) { @@ -870,10 +876,6 @@ void zlog(zlog_category_t * category, goto exit; } - if (!zlog_category_should_ouput(category, level)) { - goto exit; - } - a_thread = pthread_getspecific(zlog_thread_key); if (!a_thread) { pthread_rwlock_unlock(&zlog_env_lock); @@ -924,6 +926,8 @@ void dzlog(const char *file, size_t filelen, const char *func, size_t funclen, l zlog_thread_t *a_thread; va_list args; + if (zlog_category_needless_level(zlog_default_category, level)) return; + pthread_rwlock_rdlock(&zlog_env_lock); if (zlog_env_init_flag < 0) { @@ -938,10 +942,6 @@ void dzlog(const char *file, size_t filelen, const char *func, size_t funclen, l goto exit; } - if (!zlog_category_should_ouput(zlog_default_category, level)) { - goto exit; - } - a_thread = pthread_getspecific(zlog_thread_key); if (!a_thread) { pthread_rwlock_unlock(&zlog_env_lock); diff --git a/test/Makefile.am b/test/Makefile.am index 93c341c5..132cd3d3 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -8,6 +8,7 @@ LDADD = \ noinst_PROGRAMS = \ test_tmp \ test_buf \ + test_bitmap \ test_filemv \ test_hashtable \ test_hello \ diff --git a/test/test_bitmap.c b/test/test_bitmap.c new file mode 100644 index 00000000..e8e3c3ce --- /dev/null +++ b/test/test_bitmap.c @@ -0,0 +1,50 @@ +/* + * This file is part of the zlog Library. + * + * Copyright (C) 2011 by Hardy Simpson + * + * The zlog Library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The zlog Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the zlog Library. If not, see . + */ + +#include +#include +#include "zlog.h" + +int main(int argc, char** argv) +{ + unsigned char aa[32]; + int i, j; + + dzlog_init(NULL, "AA"); + + + i = atoi(argv[1]); + j = atoi(argv[2]); + + memset(aa, 0x00, sizeof(aa)); + + aa[i/8] |= ~(0xFF << (8 - i % 8)); + memset(aa + i/8 + 1, 0xFF, sizeof(aa) - i/8 - 1); + + HDZLOG_INFO(aa, sizeof(aa)); + + DZLOG_INFO("%0x", aa[j/8]); + DZLOG_INFO("%0x", aa[j/8] >> 6); + + DZLOG_INFO("%0x", ~((aa[j/8] >> (7 - j % 8)) & 0x01) ); + + zlog_fini(); + + return 0; +}