#include "MESA_handle_logger.h" #include "zlog.h" #include #include #include #include #include static int g_zlog_conf_fp = -1; char tmp_conf_filepath[1024] = ""; #define MAX_HANDLE_LOG_PATH 4096 #define GLOB_ZLOG_CONF "GLOB_ZLOG_CONF" typedef struct log_handle_t { int runtime_log_level; zlog_category_t *zc; const char *global_conf_path; char runtime_log_file[MAX_HANDLE_LOG_PATH]; } log_handle_t; //const int HANDLE_LOGGER_VERSION_20190218 = 1; #define GIT_VERSION_CATTER(v) __attribute__((__used__)) const char * GIT_VERSION_##v = NULL #define GIT_VERSION_EXPEND(v) GIT_VERSION_CATTER(v) #ifdef __cplusplus extern "C" { #endif /* VERSION TAG */ #ifdef GIT_VERSION GIT_VERSION_EXPEND(GIT_VERSION); #else static __attribute__((__used__)) const char * GIT_VERSION_UNKNOWN = NULL; #endif #undef GIT_VERSION_CATTER #undef GIT_VERSION_EXPEND #ifdef __cplusplus } #endif static int create_dir(const char *dir_path, int path_len) { if(dir_path == NULL) return -1; char *buf = (char *)calloc(path_len+1, 1); int ret = -1; memcpy(buf, dir_path, path_len); if(access(buf, R_OK) != 0) { if(mkdir(buf, 0755)!= 0) ret = -1; else ret = 0; } else ret = 1; free(buf); buf = NULL; return ret; } static int create_path(const char *path, int path_len) { const char *p_cur = path; int i = 0; if(create_dir(path, path_len) >= 0) return 0; for(;i<=path_len;i++,p_cur++) { if(*p_cur == '/') { if(create_dir(path, i+1) < 0) return -1; } } return 0; } static zlog_category_t *init_zlog(const char *conf_path, const char *category) { zlog_category_t *zc = NULL; if (access(conf_path, R_OK) != -1) { int rc = zlog_init(conf_path); if (rc) { rc = zlog_reload(conf_path); if(rc) { printf("init zlog by %s failed\n", conf_path); return NULL; } } zc = zlog_get_category(category); if (!zc) { printf("get zlog category %s in %s fail\n", category, conf_path); zlog_fini(); return NULL; } } return zc; } static int get_filepath(int fp, char *buf, int buflen) { if(buf == NULL || buflen <=0)return -1; char proclnk[0xFFF] = ""; //int fno = fileno(fp); int fno = fp; sprintf(proclnk, "/proc/self/fd/%d", fno); int r = readlink(proclnk, buf, buflen); return r; } static char tmp_template[] = "/tmp/handle_loggger.XXXXXX"; static void escape_for_zlog(char *in_buf, int buflen) { if(in_buf == NULL || buflen <= 0)return; int i = 0; for(i = 0; i < buflen; i++) { if ((!isalnum(in_buf[i])) && (in_buf[i] != '_') && (in_buf[i] != '-') && (in_buf[i] != '*') && (in_buf[i] != '!')) { in_buf[i] = '_'; } } return; } void *MESA_create_runtime_log_handle(const char *file_path, int level) { if(file_path == NULL) return NULL; int rc = -1; zlog_category_t *zc = NULL; FILE *fp = NULL; log_handle_t *p_handle = NULL; char zlog_rule_conf_content[MAX_HANDLE_LOG_PATH + 1]; char handle_name[MAX_HANDLE_LOG_PATH]; char *p_path_end = rindex(file_path, '/'); char *pathvar = getenv(GLOB_ZLOG_CONF); char *p_name = p_path_end+1; strcpy(handle_name, file_path); escape_for_zlog(handle_name, strlen(handle_name)); p_name = handle_name; if (pathvar == NULL) { //creating file_path failed, return NULL if (create_path(file_path, p_path_end - file_path) < 0) return NULL; if (g_zlog_conf_fp == -1) { //g_zlog_conf_fp = tmpfile(); char temp_filename[1024]=""; sprintf(temp_filename, "/tmp/MESA_handle_logger_%d.XXXXXX", getpid()); g_zlog_conf_fp = mkstemp(temp_filename); if (g_zlog_conf_fp == -1) { return NULL; } if (get_filepath(g_zlog_conf_fp, tmp_conf_filepath, sizeof(tmp_conf_filepath)) < 0) { goto error; } snprintf(zlog_rule_conf_content, sizeof(zlog_rule_conf_content), "[global]\ndefault format = \"%%d(%%c), %%V, %%m%%n\" \n[levels]\nDEBUG=10\nINFO=20\nFATAL=30\n[rules]\n%s.* \"%s.%%d(%%F)\"", p_name, file_path); write(g_zlog_conf_fp, zlog_rule_conf_content, strlen(zlog_rule_conf_content)); fsync(g_zlog_conf_fp); int rc = zlog_init(tmp_conf_filepath); if(rc) { goto error; } zc = zlog_get_category(p_name); if (!zc) { printf("get zlog category %s in %s fail\n", file_path, tmp_conf_filepath); error: unlink(tmp_conf_filepath); close(g_zlog_conf_fp); g_zlog_conf_fp = -1; memset(tmp_conf_filepath, 0, sizeof(tmp_conf_filepath)); zlog_fini(); return NULL; } } else { zc = zlog_get_category(p_name); if (!zc) { printf("get zlog category %s in %s fail\n", file_path, tmp_conf_filepath); return NULL; } else { //if (get_filepath(g_zlog_conf_fp, tmp_conf_filepath, sizeof(tmp_conf_filepath)) < 0) // return NULL; snprintf(zlog_rule_conf_content, sizeof(zlog_rule_conf_content), "\n%s.* \"%s.%%d(%%F)\"", p_name, file_path); write(g_zlog_conf_fp, zlog_rule_conf_content, strlen(zlog_rule_conf_content)); fsync(g_zlog_conf_fp); int rc = zlog_reload(tmp_conf_filepath); if (rc)return NULL; zc = zlog_get_category(p_name); if (!zc) { printf("get zlog category %s in %s fail\n", file_path, tmp_conf_filepath); return NULL; } } } } else { zc = init_zlog(pathvar, p_name); if (zc == NULL) goto error; } p_handle = (log_handle_t *)calloc(sizeof(log_handle_t), 1); strncpy(p_handle->runtime_log_file, file_path, sizeof(p_handle->runtime_log_file) - 1); p_handle->runtime_log_level = level; p_handle->zc = zc; p_handle->global_conf_path = pathvar; return (void *)p_handle; } void MESA_destroy_runtime_log_handle(void *handle) { if(handle != NULL) { log_handle_t *p_handle = (log_handle_t *)handle; zlog_fini(); if(g_zlog_conf_fp != -1) { unlink(tmp_conf_filepath); close(g_zlog_conf_fp); } free(handle); handle = NULL; } return; } void MESA_handle_runtime_log(void *handle, int level, const char *module, const char *fmt, ...) { log_handle_t *p_handle = (log_handle_t *)handle; if(p_handle == NULL || p_handle->runtime_log_file == NULL)return; if(level < p_handle->runtime_log_level) return; va_list ap; va_start(ap, fmt); vzlog(p_handle->zc, __FILE__, sizeof(__FILE__) - 1, __func__, sizeof(__func__) - 1, __LINE__, level, fmt, ap); va_end(ap); return ; }