同步内网版本
This commit is contained in:
14
Makefile
Normal file
14
Makefile
Normal file
@@ -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
|
||||||
33
README
Normal file
33
README
Normal file
@@ -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
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
23
demo/Makefile
Normal file
23
demo/Makefile
Normal file
@@ -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)
|
||||||
80
demo/test_handle_logger.c
Normal file
80
demo/test_handle_logger.c
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#include "MESA_handle_logger.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
68
inc/MESA_handle_logger.h
Normal file
68
inc/MESA_handle_logger.h
Normal file
@@ -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
|
||||||
|
|
||||||
|
|
||||||
BIN
lib/libMESA_handle_logger.a
Normal file
BIN
lib/libMESA_handle_logger.a
Normal file
Binary file not shown.
BIN
lib/libMESA_handle_logger.so
Normal file
BIN
lib/libMESA_handle_logger.so
Normal file
Binary file not shown.
218
src/MESA_handle_logger.c
Normal file
218
src/MESA_handle_logger.c
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
#include "MESA_handle_logger.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include<sys/stat.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
25
src/Makefile
Normal file
25
src/Makefile
Normal file
@@ -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)
|
||||||
Reference in New Issue
Block a user