支持过滤模块名,支持匹配通配符"*"

This commit is contained in:
guo_peixu
2022-07-08 10:07:30 +08:00
parent 3d6d7b909a
commit 451af3b929
4 changed files with 257 additions and 57 deletions

View File

@@ -15,15 +15,19 @@
#define MESA_CONSUMER_RUNNING 1
#define MESA_CONSUMER_NOT_RUNNING 0
#define MESA_CONSUMER_CARE_PID_NUM 128
#define MESA_SHM_PID_NUM 128
#define MESA_MATCH_CONSUMER_RULE_SUCCESS 0
#define MESA_MATCH_CONSUMER_RULE_FAIL -1
#define MESA_MATCH_CONSUMER_RULE_FAIL_STATUS -2
#define MESA_MATCH_CONSUMER_RULE_FAIL_LEVEL -3
#define MESA_MATCH_CONSUMER_RULE_FAIL_PID -4
#define MESA_MATCH_CONSUMER_RULE_FAIL_MODULE -5
#define MESA_SHM_MODULE_NUM 32
#define MESA_SHM_MODULE_NAME_LEN 128
#define MESA_CONSUMER_LEVEL_ALL 0
#define MESA_CONSUMER_LEVEL_DEBUG (1 << 0)
@@ -49,14 +53,15 @@ struct MESA_shm_queue_head{
int ovw_idx;
};
struct MESA_consumer{
struct MESA_shm_consumer{
int status;
int log_level;
unsigned long long reload_age;
int care_pid[MESA_CONSUMER_CARE_PID_NUM];
int pid[MESA_SHM_PID_NUM];
char module[MESA_SHM_MODULE_NUM][sizeof(int) + MESA_SHM_MODULE_NAME_LEN];
};
struct MESA_log_buf{
struct MESA_shm_log_buf{
char *buf;
char *log_file;
char *module;
@@ -66,18 +71,18 @@ struct MESA_log_buf{
int level;
};
int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int *ovw_id, struct MESA_consumer **consumer_status);
int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int *ovw_id, struct MESA_shm_consumer **consumer_status);
struct MESA_shm_queue_head *MESA_shm_get_ring_queue();
void MESA_shm_init();
void MESA_shm_recycle_ring_queue(struct MESA_shm_queue_head *ring_queue_head);
int MESA_shm_copy_buf_to_ring_queue(struct MESA_shm_queue_head *head, struct MESA_log_buf *lbuf);
int MESA_shm_copy_buf_to_ring_queue(struct MESA_shm_queue_head *head, struct MESA_shm_log_buf *lbuf);
int MESA_shm_ring_queue_is_empty(struct MESA_shm_queue_head *head);
int MESA_shm_ring_queue_is_full(struct MESA_shm_queue_head *head);
void *MESA_shm_ring_queue_get_read_pos(struct MESA_shm_queue_head *head);
void *MESA_shm_ring_queue_get_write_pos(struct MESA_shm_queue_head *head);
void MESA_shm_ring_queue_push_read_pos(struct MESA_shm_queue_head *head);
void MESA_shm_ring_queue_push_write_pos(struct MESA_shm_queue_head *head);
int MESA_shm_match_consumer_rule(int level, int pid);
int MESA_shm_match_consumer_rule(int level, int pid, const char *module);
void MESA_shm_unlink(struct MESA_shm_overview *ovw, int ovw_shmid);
const char *loglevel_to_name(int level);

View File

@@ -22,7 +22,7 @@
#define CONSUMER_OUTPUT_MODE_FILE 0
#define CONSUMER_OUTPUT_MODE_TERMINAL 1
#define CONSUMER_CARE_PID_MAX_LEN 128
#define CONSUMER_PID_MAX_LEN 128
#ifdef CONSUMER_DEBUG
#define consumer_debug(...) \
@@ -47,14 +47,19 @@ struct log_file_list{
ino_t ino;
struct list_head list;
};
struct care_pid_list{
struct pid_list{
int pid;
struct list_head list;
};
struct module_list{
char module[MESA_SHM_MODULE_NAME_LEN];
struct list_head list;
};
struct log_file_list g_log_file_list;
struct care_pid_list g_care_pid_list;
struct pid_list g_pid_list;
struct module_list g_module_list;
int g_output_mode = CONSUMER_OUTPUT_MODE_FILE;
struct MESA_consumer *g_status = NULL;
struct MESA_shm_consumer *g_status = NULL;
int g_tmp_lv = MESA_CONSUMER_LEVEL_ALL;
int g_cur_tty_fd = -1;
struct MESA_shm_overview *g_shm_overview = NULL;
@@ -325,32 +330,33 @@ void consumer_ring_queue_to_terminal(struct MESA_shm_queue_head *head, int produ
return ;
}
int producer_pid_is_cared(int producer_pid)
int pid_is_exist(int producer_pid)
{
struct care_pid_list *tmp;
struct care_pid_list *n;
list_for_each_entry_safe(tmp, n, &g_care_pid_list.list, list){
struct pid_list *tmp;
struct pid_list *n;
list_for_each_entry_safe(tmp, n, &g_pid_list.list, list){
if(tmp->pid == producer_pid){
return 1;
}
}
return 0;
}
struct care_pid_list *create_care_pid_node(int pid)
struct pid_list *create_pid_node(int pid)
{
struct care_pid_list *node;
node = (struct care_pid_list *)malloc(sizeof(struct care_pid_list));
struct pid_list *node;
node = (struct pid_list *)malloc(sizeof(struct pid_list));
if(node == NULL){
printf("malloc pid node error\n");
return NULL;
}
memset(node, 0 ,sizeof(struct pid_list));
node->pid = pid;
return node;
}
int add_care_pid_node(struct care_pid_list *node, int pid)
int add_pid_node(struct pid_list *node)
{
if(!producer_pid_is_cared(pid)){
list_add(&node->list, &g_care_pid_list.list);
if(!pid_is_exist(node->pid)){
list_add(&node->list, &g_pid_list.list);
}else{
free(node);
printf("pid repeat\n");
@@ -358,13 +364,15 @@ int add_care_pid_node(struct care_pid_list *node, int pid)
}
return CONSUMER_SUCCESS;
}
int move_care_pid_list_to_shm(int *pid, int max_num)
int move_pid_list_to_shm(int *pid)
{
struct care_pid_list *tmp;
struct care_pid_list *n;
struct pid_list *tmp;
struct pid_list *n;
int pid_num = 0;
list_for_each_entry_safe(tmp, n, &g_care_pid_list.list, list){
if(pid_num < max_num){
list_for_each_entry_safe(tmp, n, &g_pid_list.list, list){
if(pid_num < MESA_SHM_PID_NUM){
pid[pid_num] = tmp->pid;
pid_num ++;
}
@@ -373,15 +381,14 @@ int move_care_pid_list_to_shm(int *pid, int max_num)
}
return CONSUMER_SUCCESS;
}
int parse_care_pid(char *p_pid)
int parse_pid(char *p_pid)
{
char *cur;
char *p;
char tmp_pid_str[CONSUMER_CARE_PID_MAX_LEN] = {0};
char tmp_pid_str[CONSUMER_PID_MAX_LEN] = {0};
int tmp_pid;
int argcc = 0;
struct care_pid_list *node = NULL;;
struct pid_list *node = NULL;
cur = p_pid;
p = p_pid;
int pid_num = 0;
@@ -411,17 +418,17 @@ int parse_care_pid(char *p_pid)
while(isspace(*cur)){
cur++;
}
if(pid_num >= MESA_CONSUMER_CARE_PID_NUM){
if(pid_num >= MESA_SHM_PID_NUM){
printf("pid num overload\n");
return CONSUMER_ERROR;
}
pid_num ++;
tmp_pid = atoi(tmp_pid_str);
node = create_care_pid_node(tmp_pid);
node = create_pid_node(tmp_pid);
if(node == NULL){
return CONSUMER_ERROR;
}
if(add_care_pid_node(node,tmp_pid) == CONSUMER_ERROR){
if(add_pid_node(node) == CONSUMER_ERROR){
printf("add pid error\n");
return CONSUMER_ERROR;
}
@@ -433,16 +440,16 @@ int parse_care_pid(char *p_pid)
return CONSUMER_ERROR;
}
if(*cur == 0 && tmp_pid_str[0] != '\0'){
if(pid_num >= MESA_CONSUMER_CARE_PID_NUM){
if(pid_num >= MESA_SHM_PID_NUM){
printf("pid num overload\n");
return CONSUMER_ERROR;
}
tmp_pid = atoi(tmp_pid_str);
node = create_care_pid_node(tmp_pid);
node = create_pid_node(tmp_pid);
if(node == NULL){
return CONSUMER_ERROR;
}
if(add_care_pid_node(node,tmp_pid) == CONSUMER_ERROR){
if(add_pid_node(node) == CONSUMER_ERROR){
printf("add pid error\n");
return CONSUMER_ERROR;
}
@@ -450,6 +457,120 @@ int parse_care_pid(char *p_pid)
}
return CONSUMER_SUCCESS;
}
struct module_list *create_module_node(char *module)
{
struct module_list *node;
node = (struct module_list *)malloc(sizeof(struct module_list));
if(node == NULL){
printf("malloc module node error\n");
return NULL;
}
memset(node, 0, sizeof(struct module_list));
memcpy(node->module, module, strlen(module));
return node;
}
int module_is_exist(char *module)
{
struct module_list *tmp;
struct module_list *n;
list_for_each_entry_safe(tmp, n, &g_module_list.list, list){
if(strcmp(tmp->module, module) == 0){
return 1;
}
}
return 0;
}
int add_module_node(struct module_list *node)
{
if(!module_is_exist(node->module)){
list_add(&node->list, &g_module_list.list);
}else{
free(node);
printf("module repeat\n");
return CONSUMER_ERROR;
}
return CONSUMER_SUCCESS;
}
int move_module_list_to_shm(char module[MESA_SHM_MODULE_NUM][sizeof(int) + MESA_SHM_MODULE_NAME_LEN])
{
struct module_list *tmp;
struct module_list *n;
int module_num = 0;
int module_len = 0;
list_for_each_entry_safe(tmp, n, &g_module_list.list, list){
if(module_num < MESA_SHM_MODULE_NUM){
module_len = strlen(tmp->module);
if(module_len < MESA_SHM_MODULE_NAME_LEN){
*((int *)module[module_num]) = module_len;
memcpy(module[module_num] + sizeof(int), tmp->module, module_len);
module_num ++ ;
}
}
list_del(&tmp->list);
free(tmp);
}
return CONSUMER_SUCCESS;
}
int parse_module(char *module)
{
char tmp_module[MESA_SHM_MODULE_NAME_LEN] = {0};
int argcc = 0;
char *cur = module;
int module_num = 0;
struct module_list *node = NULL;
while(isspace(*cur)){
cur++;
}
while(1){
if(*cur == '\0'){
break ;
}
if(!isspace(*cur)){
tmp_module[argcc] = *cur;
argcc++;
cur++;
}else{
while(isspace(*cur)){
cur++;
}
if(module_num >= MESA_SHM_MODULE_NUM){
printf("module num overload\n");
return CONSUMER_ERROR;
}
module_num ++;
node = create_module_node(tmp_module);
if(node == NULL){
return CONSUMER_ERROR;
}
if(add_module_node(node) == CONSUMER_ERROR){
printf("add module error\n");
return CONSUMER_ERROR;
}
memset(tmp_module, 0 ,sizeof(tmp_module));
argcc = 0;
}
if(argcc >= sizeof(tmp_module)){
printf("invalid module\n");
return CONSUMER_ERROR;
}
if(*cur == 0 && tmp_module[0] != '\0'){
if(module_num >= MESA_SHM_MODULE_NUM){
printf("module num overload\n");
return CONSUMER_ERROR;
}
node = create_module_node(tmp_module);
if(node == NULL){
return CONSUMER_ERROR;
}
if(add_module_node(node) == CONSUMER_ERROR){
printf("add module error\n");
return CONSUMER_ERROR;
}
}
}
}
int check_level(char *level)
{
if(level == NULL || level[0] == '\0'){
@@ -508,6 +629,7 @@ int parse_log_level(char *level)
}
return CONSUMER_SUCCESS;
}
int get_options(int argc, char **argv)
{
char *p;
@@ -522,7 +644,7 @@ int get_options(int argc, char **argv)
if(strcmp(argv[i], "all") == 0){
/*do nothing now*/
}else{
if(parse_care_pid(argv[i]) == CONSUMER_ERROR){
if(parse_pid(argv[i]) == CONSUMER_ERROR){
printf("parse pid error\n");
return CONSUMER_ERROR;
}
@@ -555,6 +677,19 @@ int get_options(int argc, char **argv)
printf("miss parameter\n");
return CONSUMER_ERROR;
}
}else if(strcmp(p, "module") == 0){
if(argv[++i]){
if(strcmp(argv[i], "all") == 0){
/*do nothing now*/
}else{
if(parse_module(argv[i]) == CONSUMER_ERROR){
return CONSUMER_ERROR;
}
}
}else{
printf("miss parameter\n");
return CONSUMER_ERROR;
}
}else{
printf("invalid option:%s\n",p);
return CONSUMER_ERROR;
@@ -662,10 +797,12 @@ void register_sginal_handler()
}
void print_help(char *exe_name)
{
printf("-pid default all, optional parameter\n");
printf("-mode default file, optional parameter\n");
printf("-level default all, optional parameter\n");
printf("./%s -pid [ '$pid1 $pid2 $pid3...' | all ] -mode [ file | terminal ] -level [ all | 'debug info...']\n",exe_name);
printf("-pid filter producer process pid, default all\n");
printf("-mode set the output to where, default file\n");
printf("-level filter log level, default all\n");
printf("-module filter module name, support wildcard character '*', default all\n");
printf("./%s -pid [ all | '$pid1 $pid2 $pid3...' ] -mode [ file | terminal ] -level [ all | 'debug info fatal...'] -module [ all | 'module module* *module* *module*name*...' ]\n",exe_name);
printf("./%s stop exit the consumer process\n", exe_name);
return ;
}
int main(int argc, char **argv)
@@ -679,7 +816,8 @@ int main(int argc, char **argv)
kill_old_process(exe_name);
return 0;
}
INIT_LIST_HEAD(&g_care_pid_list.list);
INIT_LIST_HEAD(&g_pid_list.list);
INIT_LIST_HEAD(&g_module_list.list);
if(get_options(argc, argv) < 0){
printf("parse options error\n");
return 0;
@@ -700,8 +838,10 @@ int main(int argc, char **argv)
return 0;
}
g_status->log_level = g_tmp_lv;
memset(g_status->care_pid, 0 ,sizeof(g_status->care_pid));
move_care_pid_list_to_shm(g_status->care_pid, MESA_CONSUMER_CARE_PID_NUM);
memset(g_status->pid, 0 ,sizeof(g_status->pid));
memset(g_status->module, 0, sizeof(g_status->module));
move_pid_list_to_shm(g_status->pid);
move_module_list_to_shm(g_status->module);
if(g_status->reload_age < ULLONG_MAX){
g_status->reload_age ++;
}

View File

@@ -332,15 +332,15 @@ void MESA_handle_runtime_log(void *handle, int level, const char *module, const
log_handle_t *p_handle = (log_handle_t *)handle;
int n = 0;
int payload_len = 0;
struct MESA_log_buf lbuf;
if(p_handle == NULL || p_handle->runtime_log_file == NULL){
struct MESA_shm_log_buf lbuf;
if(p_handle == NULL || p_handle->runtime_log_file == NULL || module == NULL){
return;
}
if(p_handle->zc == NULL){
return;
}
struct MESA_pthread_private *pri = (struct MESA_pthread_private *)pthread_getspecific(MESA_pthread_key);
int match_result = MESA_shm_match_consumer_rule(level, p_handle->pid);
int match_result = MESA_shm_match_consumer_rule(level, p_handle->pid, module);
if(match_result != MESA_MATCH_CONSUMER_RULE_SUCCESS){
if(pri != NULL && match_result == MESA_MATCH_CONSUMER_RULE_FAIL_PID){
/*the process pid will not be consumed, we need to free the memory and recycle the ring queue*/

View File

@@ -15,7 +15,7 @@
struct MESA_shm_overview *MESA_shm_ovw = NULL;
struct MESA_shm_queue_head *MESA_ring_queue_head[MESA_SHM_RING_QUEUE_NUM] = {NULL};
int MESA_shm_ovw_id = -1;
struct MESA_consumer *MESA_consumer_status = NULL;
struct MESA_shm_consumer *MESA_consumer_status = NULL;
void MESA_shm_init_ring_queue_mutex(struct MESA_shm_overview *ovw)
@@ -82,9 +82,9 @@ void MESA_shm_register_sginal_handler()
signal(SIGQUIT, MESA_shm_check_unlink);
return ;
}
int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int *ovw_id, struct MESA_consumer **consumer_status)
int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int *ovw_id, struct MESA_shm_consumer **consumer_status)
{
int shmsize = (sizeof(struct MESA_shm_overview) * MESA_SHM_RING_QUEUE_NUM) + sizeof(struct MESA_consumer);
int shmsize = (sizeof(struct MESA_shm_overview) * MESA_SHM_RING_QUEUE_NUM) + sizeof(struct MESA_shm_consumer);
struct MESA_shm_overview *shm_overview = NULL;
struct MESA_shm_overview *tmp_ovw = NULL;
int i = 0;
@@ -108,7 +108,7 @@ int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int *ovw_id, struct
}
*ovw = shm_overview;
*ovw_id = shmid;
*consumer_status = (struct MESA_consumer *)(shm_overview + MESA_SHM_RING_QUEUE_NUM);
*consumer_status = (struct MESA_shm_consumer *)(shm_overview + MESA_SHM_RING_QUEUE_NUM);
}
}else{
@@ -118,7 +118,7 @@ int MESA_shm_alloc_overview(struct MESA_shm_overview **ovw, int *ovw_id, struct
}
*ovw = shm_overview;
*ovw_id = shmid;
*consumer_status = (struct MESA_consumer *)(shm_overview + MESA_SHM_RING_QUEUE_NUM);
*consumer_status = (struct MESA_shm_consumer *)(shm_overview + MESA_SHM_RING_QUEUE_NUM);
}
return 0;
}
@@ -274,7 +274,7 @@ void MESA_shm_ring_queue_push_write_pos(struct MESA_shm_queue_head *head)
/*
(int)log_file_len + (str)log_file + '\0' + (int)level + (int)module_len + (str)module + '\0' + (int)payload_len + (str)payload + '\0'
*/
int MESA_shm_copy_buf_to_ring_queue(struct MESA_shm_queue_head *head, struct MESA_log_buf *lbuf)
int MESA_shm_copy_buf_to_ring_queue(struct MESA_shm_queue_head *head, struct MESA_shm_log_buf *lbuf)
{
int available_len = 0, payload_len = 0;
int *pi = NULL;;
@@ -375,7 +375,7 @@ int MESA_shm_match_pid(int *p_pid, int cur_pid)
if(p_pid[0] == 0){
return MESA_MATCH_CONSUMER_RULE_SUCCESS;
}
for(i = 0; i < MESA_CONSUMER_CARE_PID_NUM; i++){
for(i = 0; i < MESA_SHM_PID_NUM; i++){
if(p_pid[i] == 0){
break ;
}
@@ -385,7 +385,58 @@ int MESA_shm_match_pid(int *p_pid, int cur_pid)
}
return MESA_MATCH_CONSUMER_RULE_FAIL;
}
int MESA_shm_match_consumer_rule(int level, int pid)
int MESA_shm_string_match_success(char *src, int src_len, char *pattern, int pattern_len) {
int i = 0;
int j = 0;
int start_pos = -1;
int match = -1;
while(i < src_len){
if(j < pattern_len && src[i] == pattern[j]){
i++;
j++;
}
else if(j < pattern_len && pattern[j] == '*'){
start_pos = j;
match = i;
j = start_pos + 1;
}
else if(start_pos != -1){
match++;
i = match;
j = start_pos + 1;
}
else{
return 0;
}
}
while(j < pattern_len && pattern[j] == '*'){
j++ ;
};
return (j==pattern_len);
}
int MESA_shm_match_module(const char *module)
{
int i;
int shn_module_len;
char *shm_module;
int enable = *((int *)MESA_consumer_status->module[0]);
if(enable == 0){
return MESA_MATCH_CONSUMER_RULE_SUCCESS;
}
for(i = 0; i < MESA_SHM_MODULE_NUM; i++){
shn_module_len = *((int *)MESA_consumer_status->module[i]);
if(shn_module_len == 0){
break ;
}
shm_module = MESA_consumer_status->module[i] + sizeof(int);
if(MESA_shm_string_match_success((char *)module, (int)strlen(module), shm_module, shn_module_len)){
return MESA_MATCH_CONSUMER_RULE_SUCCESS;
}
}
return MESA_MATCH_CONSUMER_RULE_FAIL;
}
int MESA_shm_match_consumer_rule(int level, int pid, const char *module)
{
static __thread unsigned long long reload_age = 0;
static __thread int last_pid_match_result = MESA_MATCH_CONSUMER_RULE_SUCCESS;
@@ -399,12 +450,12 @@ int MESA_shm_match_consumer_rule(int level, int pid)
return MESA_MATCH_CONSUMER_RULE_FAIL_LEVEL;
}
/*
only need to match pid once after the consumer restart,
only need to match pid once after consumer or producer restart,
in order to improve matching speed for producer process
*/
if(MESA_consumer_status->reload_age != reload_age){
reload_age = MESA_consumer_status->reload_age;
if(MESA_shm_match_pid(MESA_consumer_status->care_pid, pid) == MESA_MATCH_CONSUMER_RULE_FAIL){
if(MESA_shm_match_pid(MESA_consumer_status->pid, pid) == MESA_MATCH_CONSUMER_RULE_FAIL){
last_pid_match_result = MESA_MATCH_CONSUMER_RULE_FAIL;
return MESA_MATCH_CONSUMER_RULE_FAIL_PID;
}
@@ -414,6 +465,10 @@ int MESA_shm_match_consumer_rule(int level, int pid)
return MESA_MATCH_CONSUMER_RULE_FAIL_PID;
}
}
if(MESA_shm_match_module(module) == MESA_MATCH_CONSUMER_RULE_FAIL){
return MESA_MATCH_CONSUMER_RULE_FAIL_MODULE;
}
return MESA_MATCH_CONSUMER_RULE_SUCCESS;
}