commit 075accef5fbd934e13cc90079974dd7d8961ba9e Author: liuxueli Date: Thu Nov 15 17:10:05 2018 +0800 同步内网版本 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1bdf032 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +#opt: OPTFLAGS = -O2 +#export OPTFLAGS + +.PHONY: all clean opt + +all: + cd src && $(MAKE) + cd demo && $(MAKE) +clean: + cd demo && $(MAKE) clean + cd src && $(MAKE) clean + +opt: + $(MAKE) all diff --git a/README b/README new file mode 100644 index 0000000..d933733 --- /dev/null +++ b/README @@ -0,0 +1,33 @@ +/* + *NAME:MESA_handle_logger + *INTRODUCTION:Based on logger and thread_safe, provide runtime_log function with independent handle for different users. + *Author:yangwei@iie.ac.cn + *History: + 2014-03-24 created by yw + 1)first version + + 2014-04-16 modified by yw + 1)strict inspection parameters, compatible with g++ 4.4.4 + + 2014-05-29 update by yw + 1)create directory is supported +------------------------------------------------------------------------------------- + NOTICE: + 1)compatible with g++, extern with c; + 2)thread_safe IS supported; + 3)DO destroy handle process before exit. + 4)demo requires lpthread support +*/ + + + + + + + + + + + + + diff --git a/demo/Makefile b/demo/Makefile new file mode 100644 index 0000000..10956e6 --- /dev/null +++ b/demo/Makefile @@ -0,0 +1,23 @@ +vpath %.h ../inc +vpath %.a ../lib + +CC=gcc + +CFLAGS= -g3 -Wall -fPIC -O -Werror +CFLAGS+=-I../inc/ + +LIB=-L../lib/ +LIB+=-lMESA_handle_logger -lpthread + +LIB_FILE=$(wildcard ../lib/*.a) + +SRC=test_handle_logger.c +TARGET=test_handle_logger + +all:$(TARGET) + +$(TARGET):$(SRC) $(LIB_FILE) + $(CC) $(CFLAGS) $(INC) $(LIBPATH) $< -static $(LIB) -o $@ + +clean : + rm -f $(TARGET) diff --git a/demo/test_handle_logger.c b/demo/test_handle_logger.c new file mode 100644 index 0000000..ce18567 --- /dev/null +++ b/demo/test_handle_logger.c @@ -0,0 +1,80 @@ +#include "MESA_handle_logger.h" + +#include +#include +#include +#include + +void *sample_handle = NULL; +void *test_handle = NULL; + +#define LOG_NUM 100 +#define THREAD_NUM 100 + +void call_logger(int log_num, int thread_num) +{ + int i = 0; + for(i = 0; i < log_num; i++) + { + MESA_handle_runtime_log(sample_handle, RLOG_LV_INFO, "sample", "sample_handle MESA_handle_runtime_log, i = %d, thread_num = %d", i, thread_num); + //sleep(1); + MESA_handle_runtime_log(test_handle, RLOG_LV_INFO, "test", "test_handle MESA_handle_runtime_log, i = %d, thread_num = %d", i, thread_num); + MESA_HANDLE_RUNTIME_LOG(sample_handle, RLOG_LV_FATAL, "sample", "sample_handle RUNTIEM_LOG test, i = %d, thread_num = %d", i, thread_num); + //sleep(1); + MESA_HANDLE_RUNTIME_LOG(test_handle, RLOG_LV_FATAL, "test", "test_handle RUNTIEM_LOG test, i = %d, thread_num = %d", i, thread_num); + } + return; +} + + +void *thread_logger(void *arg) +{ + int thread_num = (int)(unsigned long long)arg; + printf("thread %d created! \n", thread_num); + call_logger(LOG_NUM, thread_num); + printf("thread %d finished! \n", thread_num); + return NULL; +} + +void sig_handler(int sig) +{ + printf("ctrl+c recviced!\n"); + MESA_destroy_runtime_log_handle(sample_handle); + MESA_destroy_runtime_log_handle(test_handle); + sample_handle = NULL; + test_handle = NULL; + exit(0); +} + +int main() +{ + pthread_t t[THREAD_NUM]; + int i = 0; + + sample_handle = MESA_create_runtime_log_handle("./log/", RLOG_LV_DEBUG); + if(sample_handle == NULL) + { + printf("get log sample_handle error\n"); + return -1; + } + + test_handle = MESA_create_runtime_log_handle("./log/test_log", RLOG_LV_DEBUG); + if(test_handle == NULL) + { + printf("get log test_handle error\n"); + return -1; + } + + for(i = 0; i < THREAD_NUM; i++) + { + pthread_create(&t[i], NULL, thread_logger, (void *)(unsigned long)(i)); + } + signal(SIGINT, sig_handler); + while(1) + ; + //MESA_destroy_runtime_log_handle(sample_handle); + //MESA_destroy_runtime_log_handle(test_handle); + //sample_handle = NULL; + //test_handle = NULL; + return 0; +} diff --git a/inc/MESA_handle_logger.h b/inc/MESA_handle_logger.h new file mode 100644 index 0000000..c615b53 --- /dev/null +++ b/inc/MESA_handle_logger.h @@ -0,0 +1,68 @@ +#ifndef MESA_HANDLE__LOGGER_H +#define MESA_HANDLE__LOGGER_H + +/* + * runtime_log with handle, + * based on runtime_log. + * yang wei + * create time:2014-03-24 + * version:20140324 + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define RLOG_LV_DEBUG 10 +#define RLOG_LV_INFO 20 +#define RLOG_LV_FATAL 30 + + +#define MESA_HANDLE_RUNTIME_LOG(handle, lv, mod, fmt, args...) \ + MESA_handle_runtime_log((handle), (lv), (mod), "file %s, line %d, " fmt, \ + __FILE__, __LINE__, ##args) + +/* + * name: MESA_create_runtime_log_handle + * functionality: get runtime_log handle; + * params: + * file_path: path of log file, like "./log/runtime_log"; + * level: level of log; + * returns: + * not NULL, if succeeded; + * NULL, if file is not absolute path, or failed to create log file; + */ +void *MESA_create_runtime_log_handle(const char *file_path, int level); + +/* + * name: MESA_handle_runtime_log + * functionality: appends log message to runtime log file; + * params: + * handle:handle of runtime log, which is created by MESA_create_runtime_log_handle; + * level: log level, messages with level value smaller the global var + * "runtime_log_level" are ignored; + * module: name of loggin module; + * fmt: format string; + * returns: + * none; + */ +void MESA_handle_runtime_log(void *handle, int level, const char *module, const char *fmt, ...); + +/* + * name: MESA_destroy_runtime_log_handle + * functionality: release runtime log handle memory. + * params: + * handle: runtime log handle which is going to be released; + * returns: + * none; + */ +void MESA_destroy_runtime_log_handle(void *handle); + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/lib/libMESA_handle_logger.a b/lib/libMESA_handle_logger.a new file mode 100644 index 0000000..19f576a Binary files /dev/null and b/lib/libMESA_handle_logger.a differ diff --git a/lib/libMESA_handle_logger.so b/lib/libMESA_handle_logger.so new file mode 100644 index 0000000..65586ad Binary files /dev/null and b/lib/libMESA_handle_logger.so differ diff --git a/src/MESA_handle_logger.c b/src/MESA_handle_logger.c new file mode 100644 index 0000000..b24104b --- /dev/null +++ b/src/MESA_handle_logger.c @@ -0,0 +1,218 @@ +#include "MESA_handle_logger.h" + +#include +#include +#include +#include +#include +#include +#include + +typedef struct log_handle_t +{ + int runtime_log_level; + char runtime_log_file[1200]; +} log_handle_t; + +#define THREAD_CTIME(t, buf, len) thread_safe_ctime(t, buf, len) +#define LOGMSG_MAX_LEN 4096 + +const int HANDLE_LOGGER_VERSION_20170816 = 1; + +char *thread_safe_ctime(const time_t *tp, char *buf, int len) +{ + unsigned int year, month, day, weekday, hour, min, sec; + unsigned int year_days = 365; + unsigned int month_days[12] = + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + static unsigned char weekday_str[7][4] = + {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + static unsigned char month_str[12][4] = {"Jan", "Feb", "Mar", "Apr", + "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + sec = * tp; + min = sec / 60; sec = sec % 60; + hour = min / 60; min = min % 60; hour += 8; + day = hour / 24; hour = hour % 24; + weekday = day % 7; weekday = (weekday + 4) % 7; + + for(year = 1970; day >= year_days;) + { + day -= year_days; + year ++; + + if(0 == year % 4 && (0 != year % 100 || 0 == year % 400)) + year_days = 366; + else year_days = 365; + } + + if(366 == year_days) month_days[1] = 29; + + //bug fix by yw 20120808 + for(month = 0; day >= month_days[month];) + { + day -= month_days[month]; + month ++; + } + + /* + snprintf(buf, len, "%02d:%02d:%02d, %04d/%02d/%02d, %s", + hour, min, sec, year, month, day, weekday_str[week_day]); + */ + snprintf(buf, len, "%s %s %d %02d:%02d:%02d %d", weekday_str[weekday], + month_str[month], day + 1, hour, min, sec, year); + return buf; +} + +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; +} + +void *MESA_create_runtime_log_handle(const char *file_path, int level) +{ + if(file_path == NULL) + return NULL; + + FILE *fp = NULL; + log_handle_t *p_handle = NULL; + + //creating file_path failed, return NULL + char *p_path = rindex(file_path, '/'); + if(p_path != 0) + { + if(create_path(file_path, p_path - file_path) < 0) + return NULL; + } + if(NULL == (fp = fopen(file_path, "w"))) + return NULL; + + fclose(fp); + //remove(file_path); + p_handle = (log_handle_t *)calloc(sizeof(log_handle_t), 1); + + if(p_handle == NULL) + return NULL; + + strncpy(p_handle->runtime_log_file, file_path, 1024); + p_handle->runtime_log_file[1024] = '\0'; + p_handle->runtime_log_level = level; + return (void *)p_handle; +} + +void MESA_destroy_runtime_log_handle(void *handle) +{ + if(handle != NULL) + { + free(handle); + handle = NULL; + } + + return; +} + +void MESA_handle_runtime_log(void *handle, int level, const char *module, const char *fmt, ...) +{ + char buf[LOGMSG_MAX_LEN + 1]; + time_t t; + int len; + va_list ap; + FILE *fp; + struct tm local_time; + char tmp_log_file_name[1201]; + 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; + + time(&t); + THREAD_CTIME(&t, buf, LOGMSG_MAX_LEN); + len = strlen(buf); + + switch(level) + { + case RLOG_LV_DEBUG: + len += snprintf(buf + len, + LOGMSG_MAX_LEN - len, ", %s, ", "DEBUG"); + break; + + case RLOG_LV_INFO: + len += snprintf(buf + len, + LOGMSG_MAX_LEN - len, ", %s, ", "INFO"); + break; + + case RLOG_LV_FATAL: + len += snprintf(buf + len, + LOGMSG_MAX_LEN - len, ", %s, ", "FATAL"); + break; + + default: + len += snprintf(buf + len, + LOGMSG_MAX_LEN - len, ", %s, ", "UNKNOWN"); + break; + } + + if(0 >= LOGMSG_MAX_LEN - len) return; + + len += snprintf(buf + len, LOGMSG_MAX_LEN - len, "%s, ", module); + + if(0 >= LOGMSG_MAX_LEN - len) return; + + va_start(ap, fmt); + len += vsnprintf(buf + len, LOGMSG_MAX_LEN - len, fmt, ap); + va_end(ap); + + if(0 >= LOGMSG_MAX_LEN - len) return; + + len += snprintf(buf + len, LOGMSG_MAX_LEN - len, "\n"); + + if(NULL == (localtime_r(&t, &local_time))) return; + + sprintf(tmp_log_file_name, "%s.%04d-%02d-%02d", p_handle->runtime_log_file, + local_time.tm_year + 1900, local_time.tm_mon + 1, + local_time.tm_mday); + + if(NULL == (fp = fopen(tmp_log_file_name, "a"))) return; + + fprintf(fp, "%s", buf); + fclose(fp); +} + diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..a7a913c --- /dev/null +++ b/src/Makefile @@ -0,0 +1,25 @@ +CC=gcc +VPATH=../inc +CFLAGS= -g3 -Wall -fPIC -O -Werror +CFLAGS+=-I../inc/ + +SRC=MESA_handle_logger.c +OBJS=$(SRC:.c=.o) + +TARGET=libMESA_handle_logger.a libMESA_handle_logger.so + +all:$(TARGET) + cp -f $(TARGET) ../lib + +libMESA_handle_logger.a:$(OBJS) + ar cqs $@ $< + +libMESA_handle_logger.so:$(OBJS) + $(CC) $(CFLAGS) -shared $< -o $@ +.c.o: + +#$(OBJS):$(SRC) +# $(CC) $(CFLAGS) $(INC) -c $< -o $@ + +clean : + rm -f $(OBJS) $(TARGET)