initialize

This commit is contained in:
崔一鸣
2018-08-12 19:11:04 +08:00
parent 17e2e2050a
commit a76c0d285f
16 changed files with 8627 additions and 0 deletions

19
Makefile Normal file
View File

@@ -0,0 +1,19 @@
#opt: OPTFLAGS = -O2
#export OPTFLAGS
.PHONY: all clean opt
all:
cd src && $(MAKE)
cd sample && $(MAKE)
install:
cd src && $(MAKE) install
cd sample && $(MAKE) install
clean:
cd src && $(MAKE) clean
cd sample && $(MAKE) clean
opt:
$(MAKE) all

182
README Normal file
View File

@@ -0,0 +1,182 @@
####简介
MESA_handle_logger_new是基于开源C++日志库[easylogging++](https://github.com/muflihun/easyloggingpp)封装的新的日志库。具有以下特性:
* 线程安全
* 强大的配置功能
* 保留旧接口不变,完全兼容旧程序
#### 安装方法
```
git clone https://git.mesalab.cn/leo/MESA_handle_logger_new
cd MESA_handle_logger_new
//install到MESA_handle_logger_new/lib/下
make && make install
//指定运行时链接的日志库为新的.so的目录
export LD_LIBRARY_PATH="xxxx"
```
#### 对外接口
* 获取日志句柄
* 为了兼容旧程序,我们保留了旧的接口,同时提供了一个新的方法用来获取句柄
* MESA_create_runtime_log_handle( )和MESA_create_runtime_log_handle_new( )中会使用一份默认的日志配置。具体内容见src/MESA_handle_logger.c中的set_default_conf( )函数
```
/* functionality: 旧接口,用来获取日志句柄
params:
file_path: 日志文件保存路径, 长度不能超过256
level: 日志文件级别,>=该级别的日志才会输出,level = {RLOG_LV_DEBUG, RLOG_LV_INFO, RLOG_LV_FATAL }
returns:
void*: 返回一个日志句柄
*/
void *MESA_create_runtime_log_handle(const char *file_path, int level);
/* functionality: 新接口,用来获取日志句柄
desc: 新接口不用显示指定日志文件路径和日志级别可以在配置文件配置或者通过MESA_set_runtime_log_handle_opt指定
对于新程序,我们推荐使用这种方法
params:
logger_id: 一个logger_id唯一标识一个日志句柄
returns:
void*: 返回一个日志句柄
*/
void* MESA_create_runtime_log_handle_new(const char* logger_id);
```
* 配置日志属性
* 我们提供了两种方法用来配置日志属性
* 读取配置文件
* 在代码中显式配置某个属性
```
/* functionality: 读取日志配置文件,我们推荐使用这种方法
params:
handle: 日志句柄
conf_file_path: 配置文件路径
returns:
0: 成功
-1: 失败
*/
int MESA_read_runtime_log_handle_conf(void* handle, const char* conf_file_path);
/* functionality: 设置某个日志属性
desc: 可配置的属性值见"可配置日志属性"
params:
handle: 日志句柄
level: 设置的日志级别level = {RLOG_LV_DEBUG, RLOG_LV_INFO, RLOG_LV_FATAL }
key: 配置的属性
value: 配置的属性值
returns:
0: 成功
-1: 失败
*/
int MESA_set_runtime_log_handle_opt(void* handle, int level, const char* key, const char* value);
```
* 写日志
* 写日志接口保持和原来一致
```
/* functionality: 写日志
params:
handle: 日志句柄
level: 设置的日志级别level = {RLOG_LV_DEBUG, RLOG_LV_INFO, RLOG_LV_FATAL }
module: 日志所属模块
fmt: 格式化字符串单条日志长度不能超过4096
returns: none
*/
void MESA_handle_runtime_log(void *handle, int level, const char *module, const char *fmt, ...);
```
* 释放句柄
* 释放句柄保持和原来一致
```
/* functionality: 释放日志句柄
params:
handle: 日志句柄
returns: none
*/
void MESA_destroy_runtime_log_handle(void *handle);
```
#### 可配置日志属性
| Configuration Name | Description | Value |
| --- | --- | --- |
| enabled | Determines whether or not corresponding level for logger is enabled | {“true”, “false”} |
| to_file | Whether or not to write corresponding log to log file | {“true”, “false”} |
| to_standard_output | Whether or not to write logs to standard output e.g, terminal or command prompt | {“true”, “false”} |
| format | Determines format/pattern of logging for corresponding level and logger. | 如: ”[%level%datetime{%Y-%M-%d %H:%m:%s}]: %msg“ |
| file_name | Determines log file (full path) to write logs to for corresponding level and logger | 如: “./log2/debug_log_%datetime{%Y-%M-%d}“ |
| max_log_file_size | If log file size of corresponding level is >= specified size, log file will be truncated. | 如: “2097152” |
| sub_second_precision | Specifies subsecond precision (previously called 'milliseconds width')|{“1”, “2”, “3”, “4”, “5”, “6”,}|
|performance_tracking |determines whether or not performance tracking is enabled|{“true”, “false”}|
| log_flush_threshold | Specifies number of log entries to hold until we flush pending log data|如: “100” |
####日志配置文件格式
* 这里仅仅以FATAL级别的配置为例完整配置参考sample/new/sample.conf
* %level, %datetime是格式化变量运行时会变成对应的值
* GLOBAL是全局配置作用于所有Level。其相当于一个开关。
* 若GLOBAL中配置了属性A
* Level(DEBUGINFOFATAL)中配置了属性ALevel使用自己配置的属性A
* Level(DEBUGINFOFATAL)中没有配置属性ALevel使用GLOBAL中配置的属性A
* 若GLOBAL中没有配置属性A
* 无论Level(DEBUGINFOFATAL)中是否配置属性A属性A均不生效
```
* GLOBAL:
FORMAT = "[%level|%datetime{%Y-%M-%d %H:%M:%s}]: %msg"
FILENAME = "myeasylog.log"
ENABLED = true
TO_FILE = true
TO_STANDARD_OUTPUT = true
## SUBSECOND_PRECISION = 6
## PERFORMANCE_TRACKING = true
## MAX_LOG_FILE_SIZE = 2097152
## LOG_FLUSH_THRESHOLD = 100
* FATAL:
FORMAT = "[%level|%datetime{%Y-%M-%d %H:%m:%s}]: %msg" ##日志内容格式
FILENAME = "./log1/fatal_log_%datetime{%Y-%M-%d}" ##日志保存路径
ENABLED = true
TO_FILE = true
TO_STANDARD_OUTPUT = true
##SUBSECOND_PRECISION = 6 ## 暂时用不到
##PERFORMANCE_TRACKING = true ## 暂时用不到
##MAX_LOG_FILE_SIZE = 2097152 ## 文件最大值超过该值后日志文件会truncated这里是2MB
##LOG_FLUSH_THRESHOLD = 100 ## Flush after every 100 logs, 暂时用不到
```
####示例程序
* 旧程序
```
void* handle = MESA_create_runtime_log_handle("./log/sample_log", RLOG_LV_DEBUG);
MESA_handle_runtime_log(handle, RLOG_LV_DEBUG, "module", "test debug log:%s", "xxxxx");
MESA_destroy_runtime_log_handle(handle);
```
* 新程序
```
##通过读取配置文件设置日志属性
void* handle1 = MESA_create_runtime_log_handle_new("logger_id1");
int rtn = MESA_read_runtime_log_handle_conf(handle, "./sample.conf");
MESA_handle_runtime_log(handle, RLOG_LV_DEBUG, "module_test_read_conf", "test debug log:%s", "xxxxx");
MESA_destroy_runtime_log_handle(handle1);
##通过代码中显式设置某个日志属性
void* handle2 = MESA_create_runtime_log_handle("logger_id2");
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "Enabled", "true");
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "ToFile", "true");
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "ToStandardOutput", "true");
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "Format", "[%level|%datetime{%Y-%M-%d %H:%m:%s}]: %msg");
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "Filename", "./log2/debug_log_%datetime{%Y-%M-%d}");
MESA_handle_runtime_log(handle, RLOG_LV_DEBUG, "module_test_set_opt", "test debug log:%s", "xxxxx");
MESA_destroy_runtime_log_handle(handle2);
```
#### F.A.Q
* 对于旧的程序,如果想在不修改代码的情况下也想使用配置文件进行日志配置,可不可以呢?
* 可以在旧接口MESA_create_runtime_log_handle( )中,我们会读取 **MESA_HANDLE_LOGGER_CONF_PATH**这个环境变量。然后根据环境变量中的路径读取配置文件进行配置。
* 所以你只需要编写配置文件然后export MESA_HANDLE_LOGGER_CONF_PATH="xxxxx"就可以使用配置文件进行配置了。
* 其中xxxx为你的配置文件所在的路径

View File

@@ -0,0 +1,107 @@
#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, you can only use 3 levels: RLOG_LV_DEBUG, RLOG_LV_INFO, RLOG_LV_FATAL;
* 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_create_runtime_log_handle_new
* functionality: get runtime_log handle, it depends on easylogging++.
* we recommend you to use the new constructed function;;
* params:
* logger_id: indentify a handle;
* no parameter level, we recommand you to use MESA_set_runtime_log_handle_opt to enable or disable a level
* returns:
* not NULL, if succeeded;
* NULL, if logger_id == NULL or level is invalid;
*/
void* MESA_create_runtime_log_handle_new(const char* logger_id);
/*
* 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_read_handle_runtime_log_conf
* functionality: read and set the conf of a handle;
* params:
* handle: handle of runtime log;
* conf_file_path: path of the conf file;
* returns:
* 0, if succeeded;
* -1, if failed;
*/
int MESA_read_runtime_log_handle_conf(void* handle, const char* conf_file_path);
/*
* name: MESA_set_runtime_log_handle_opt
* functionality: set option of a runtime_log_handle;
* params:
* handle: handle of runtime log;
* level: log level;
* key: key of option ;
* value: value of option;
* returns:
* 0, if succeeded;
* -1, if failed;
*/
int MESA_set_runtime_log_handle_opt(void* handle, int level, const char* key, const char* value);
/*
* 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

19
sample/Makefile Normal file
View File

@@ -0,0 +1,19 @@
#opt: OPTFLAGS = -O2
#export OPTFLAGS
.PHONY: all clean opt
all:
cd new && $(MAKE)
cd old && $(MAKE)
install:
cd new && $(MAKE) install
cd old && $(MAKE) install
clean:
cd new && $(MAKE) clean
cd old && $(MAKE) clean
opt:
$(MAKE) all

22
sample/new/Makefile Normal file
View File

@@ -0,0 +1,22 @@
CC = gcc
TARGET = test_handle_logger
CFLAGS = -g -Wall -fPIC
LIB = -L../../lib/
LIB += -lMESA_handle_logger -lpthread
INCLUDES = -I../../include/
SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)
DEPS = $(SOURCES:.c=.d)
.PHONY : clean all install
all : $(TARGET)
$(TARGET) : $(OBJECTS)
$(CC) $(CFLAGS) -o $(TARGET) $(LIB) $(OBJECTS)
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
%.d : %.c
$(CC) $< -MM $(INCLUDES) > $@
-include $(DEPS)
clean :
-rm $(TARGET) $(OBJECTS) $(DEPS)

49
sample/new/sample.conf Normal file
View File

@@ -0,0 +1,49 @@
## Do not modify
* GLOBAL:
FORMAT = "[%level|%datetime{%Y-%M-%d %H:%M:%s}]: %msg"
FILENAME = "myeasylog.log"
ENABLED = true
TO_FILE = true
TO_STANDARD_OUTPUT = true
## Specifies subsecond precision (previously called 'milliseconds width'). Width can be within range (1-6)
## SUBSECOND_PRECISION = 6
## PERFORMANCE_TRACKING = true
## If log file size of corresponding level is >= specified size, log file will be truncated.
## MAX_LOG_FILE_SIZE = 2097152
## Specifies number of log entries to hold until we flush pending log data
## LOG_FLUSH_THRESHOLD = 100
## Do not modify
* FATAL:
FORMAT = "[%level|%datetime{%Y-%M-%d %H:%m:%s}]: %msg"
FILENAME = "./log1/fatal_log_%datetime{%Y-%M-%d}"
ENABLED = true
TO_FILE = true
TO_STANDARD_OUTPUT = true
##SUBSECOND_PRECISION = 6
##PERFORMANCE_TRACKING = true
##MAX_LOG_FILE_SIZE = 2097152 ## 2MB
##LOG_FLUSH_THRESHOLD = 100 ## Flush after every 100 logs
* INFO:
FORMAT = "[%level|%datetime{%Y-%M-%d %H:%m:%s}]: %msg"
FILENAME = "./log1/info_log_%datetime{%Y-%M-%d}"
ENABLED = true
TO_FILE = true
TO_STANDARD_OUTPUT = false
##SUBSECOND_PRECISION = 6
##PERFORMANCE_TRACKING = true
##MAX_LOG_FILE_SIZE = 2097152 ## 2MB
##LOG_FLUSH_THRESHOLD = 100 ## Flush after every 100 logs
* DEBUG:
FORMAT = "[%level|%datetime{%Y-%M-%d %H:%m:%s}]: %msg"
FILENAME = "./log1/debug_log_%datetime{%Y-%M-%d}"
ENABLED = true
TO_FILE = true
TO_STANDARD_OUTPUT = false
##SUBSECOND_PRECISION = 6
##PERFORMANCE_TRACKING = true
##MAX_LOG_FILE_SIZE = 2097152 ## 2MB - Comment starts with two hashes (##)
##LOG_FLUSH_THRESHOLD = 100 ## Flush after every 100 logs

View File

@@ -0,0 +1,60 @@
#include "../../include/MESA_handle_logger.h"
#define MAX_LOG_NUM 10
int test_default_conf(){
void* handle = MESA_create_runtime_log_handle_new("logger_id1");
int i = 0;
for(i = 0; i<MAX_LOG_NUM; i++){
MESA_handle_runtime_log(handle, RLOG_LV_DEBUG, "test_default_conf", "test debug log:%s", "xxxxx");
MESA_handle_runtime_log(handle, RLOG_LV_INFO, "test_default_conf", "test info log:%s", "xxxxx");
MESA_handle_runtime_log(handle, RLOG_LV_FATAL, "test_default_conf", "test fatal log:%s", "xxxxx");
}
MESA_destroy_runtime_log_handle(handle);
return 0;
}
int test_read_conf(){
void* handle = MESA_create_runtime_log_handle_new("logger_id1");
int rtn = MESA_read_runtime_log_handle_conf(handle, "./sample.conf");
if(rtn == -1){
return -1;
}
int i = 0;
for(i = 0; i<MAX_LOG_NUM; i++){
MESA_handle_runtime_log(handle, RLOG_LV_DEBUG, "test_read_conf", "test debug log:%s", "xxxxx");
MESA_handle_runtime_log(handle, RLOG_LV_INFO, "test_read_conf", "test info log:%s", "xxxxx");
MESA_handle_runtime_log(handle, RLOG_LV_FATAL, "test_read_conf", "test fatal log:%s", "xxxxx");
}
MESA_destroy_runtime_log_handle(handle);
return 0;
}
int test_set_opt(){
void* handle = MESA_create_runtime_log_handle_new("logger_id2");
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "enabled", "true");
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "to_file", "true");
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "to_standard_output", "true");
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "format", "[%level|%datetime{%Y-%M-%d %H:%m:%s}]: %msg");
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "file_name", "./log2/debug_log_%datetime{%Y-%M-%d}");
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_INFO, "file_name", "./log2/info_log_%datetime{%Y-%M-%d}");
MESA_set_runtime_log_handle_opt(handle, RLOG_LV_FATAL, "file_name", "./log2/fatal_log_%datetime{%Y-%M-%d}");
//MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "sub_second_precision", "6");
//MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "performance_tracking", "true");
//MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "max_log_file_size", "2097152");
//MESA_set_runtime_log_handle_opt(handle, RLOG_LV_DEBUG, "log_flush_threshold", "100");
int i = 0;
for(i = 0; i<MAX_LOG_NUM; i++){
MESA_handle_runtime_log(handle, RLOG_LV_DEBUG, "test_set_opt", "test debug log:%s", "xxxxx");
MESA_handle_runtime_log(handle, RLOG_LV_INFO, "test_set_opt", "test info log:%s", "xxxxx");
MESA_handle_runtime_log(handle, RLOG_LV_FATAL, "test_set_opt", "test fatal log:%s", "xxxxx");
}
MESA_destroy_runtime_log_handle(handle);
return 0;
}
int main(int argc, char* argv[]) {
test_default_conf();
test_read_conf();
test_set_opt();
return 0;
}

22
sample/old/Makefile Normal file
View File

@@ -0,0 +1,22 @@
CC = gcc
TARGET = test_handle_logger
CFLAGS = -g -Wall -fPIC
LIB = -L../../lib/
LIB += -lMESA_handle_logger -lpthread
INCLUDES = -I../../include/
SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)
DEPS = $(SOURCES:.c=.d)
.PHONY : clean all install
all : $(TARGET)
$(TARGET) : $(OBJECTS)
$(CC) $(CFLAGS) -o $(TARGET) $(LIB) $(OBJECTS)
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
%.d : %.c
$(CC) $< -MM $(INCLUDES) > $@
-include $(DEPS)
clean :
-rm $(TARGET) $(OBJECTS) $(DEPS)

49
sample/old/sample.conf Normal file
View File

@@ -0,0 +1,49 @@
## Do not modify
* GLOBAL:
FORMAT = "[%level|%datetime{%Y-%M-%d %H:%M:%s}]: %msg"
FILENAME = "myeasylog.log"
ENABLED = true
TO_FILE = true
TO_STANDARD_OUTPUT = true
## Specifies subsecond precision (previously called 'milliseconds width'). Width can be within range (1-6)
## SUBSECOND_PRECISION = 6
## PERFORMANCE_TRACKING = true
## If log file size of corresponding level is >= specified size, log file will be truncated.
## MAX_LOG_FILE_SIZE = 2097152
## Specifies number of log entries to hold until we flush pending log data
## LOG_FLUSH_THRESHOLD = 100
## Do not modify
* FATAL:
FORMAT = "[%level|%datetime{%Y-%M-%d %H:%m:%s}]: %msg"
FILENAME = "./log1/fatal_log_%datetime{%Y-%M-%d}"
ENABLED = true
TO_FILE = true
TO_STANDARD_OUTPUT = true
##SUBSECOND_PRECISION = 6
##PERFORMANCE_TRACKING = true
##MAX_LOG_FILE_SIZE = 2097152 ## 2MB
##LOG_FLUSH_THRESHOLD = 100 ## Flush after every 100 logs
* INFO:
FORMAT = "[%level|%datetime{%Y-%M-%d %H:%m:%s}]: %msg"
FILENAME = "./log1/info_log_%datetime{%Y-%M-%d}"
ENABLED = true
TO_FILE = true
TO_STANDARD_OUTPUT = false
##SUBSECOND_PRECISION = 6
##PERFORMANCE_TRACKING = true
##MAX_LOG_FILE_SIZE = 2097152 ## 2MB
##LOG_FLUSH_THRESHOLD = 100 ## Flush after every 100 logs
* DEBUG:
FORMAT = "[%level|%datetime{%Y-%M-%d %H:%m:%s}]: %msg"
FILENAME = "./log1/debug_log_%datetime{%Y-%M-%d}"
ENABLED = true
TO_FILE = true
TO_STANDARD_OUTPUT = false
##SUBSECOND_PRECISION = 6
##PERFORMANCE_TRACKING = true
##MAX_LOG_FILE_SIZE = 2097152 ## 2MB - Comment starts with two hashes (##)
##LOG_FLUSH_THRESHOLD = 100 ## Flush after every 100 logs

View File

@@ -0,0 +1,81 @@
#include "../../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);
MESA_HANDLE_RUNTIME_LOG(sample_handle, RLOG_LV_DEBUG, "sample", "sample_handle RUNTIEM_LOG test, i = %d, thread_num = %d", i, thread_num);
MESA_HANDLE_RUNTIME_LOG(test_handle, RLOG_LV_DEBUG, "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/sample_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;
}

Binary file not shown.

219
src/MESA_handle_logger.c Normal file
View File

@@ -0,0 +1,219 @@
#include "include/easylogging++.h"
#include "include/MESA_handle_logger.h"
#include <stdio.h>
#include <stdarg.h>
#include <cassert>
#include <unistd.h>
INITIALIZE_EASYLOGGINGPP;
#define LOGMSG_MAX_LEN 4096
#define MAX_FILE_PATH_LEN 256
#ifdef __cplusplus
extern "C"{
#endif
struct runtime_log_handle{
el::Logger* logger;
el::Configurations* conf;
};
void* create_handle_helper(el::Logger* logger, el::Configurations* conf);
int level_trans_helper(int level, el::Level& el_level);
int conf_trans_helper(const char* key, el::ConfigurationType& el_conf_type);
void set_default_conf(el::Configurations* conf);
void* create_handle_helper(el::Logger* logger, el::Configurations* conf){
el::Loggers::reconfigureLogger(logger, *conf);
struct runtime_log_handle* handle = (struct runtime_log_handle*)malloc(sizeof(struct runtime_log_handle));
handle->logger = logger;
handle->conf = conf;
return (void*)handle;
}
void set_default_conf(el::Configurations* conf){
conf->set(el::Level::Global, el::ConfigurationType::Enabled, "true");
conf->set(el::Level::Global, el::ConfigurationType::ToFile, "true");
conf->set(el::Level::Global, el::ConfigurationType::ToStandardOutput, "false");
conf->set(el::Level::Global, el::ConfigurationType::Format, "[%level|%datetime{%Y-%M-%d %H:%m:%s}]: %msg");
conf->set(el::Level::Debug, el::ConfigurationType::Filename, "./log/debug_log_%datetime{%Y-%M-%d}");
conf->set(el::Level::Info, el::ConfigurationType::Filename, "./log/info_log_%datetime{%Y-%M-%d}");
conf->set(el::Level::Fatal, el::ConfigurationType::Filename, "./log/fatal_log_%datetime{%Y-%M-%d}");
}
std::string get_logger_id_by_hash(const char* str){
std::string str1(str);
std::hash<std::string> h;
int n = h(str1);
std::string logger_id = std::to_string(n);
return logger_id;
}
void* MESA_create_runtime_log_handle(const char *file_path, int level){
if(file_path == NULL){
return NULL;
}
if(level != RLOG_LV_DEBUG && level != RLOG_LV_INFO && level != RLOG_LV_FATAL){
return NULL;
}
el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog);
std::string logger_id = get_logger_id_by_hash(file_path);
el::Logger* logger = el::Loggers::getLogger(logger_id);
el::Configurations* default_conf = new el::Configurations();
void* handle = NULL;
char* conf_file_path = getenv("MESA_HANDLE_LOGGER_CONF_PATH");
if(conf_file_path == NULL){
set_default_conf(default_conf);
if(level>RLOG_LV_DEBUG){
default_conf->set(el::Level::Debug,el::ConfigurationType::Enabled, "false");
}
if(level>RLOG_LV_INFO){
default_conf->set(el::Level::Info,el::ConfigurationType::Enabled, "false");
}
char file_path1[MAX_FILE_PATH_LEN];
strcpy(file_path1, file_path);
strcat(file_path1, "_%datetime{%Y-%M-%d}");
default_conf->set(el::Level::Global, el::ConfigurationType::Filename, file_path1);
handle = create_handle_helper(logger, default_conf);
}
else{
if(access(conf_file_path, R_OK) == -1){
return NULL;
}
handle = create_handle_helper(logger, default_conf);
int rtn = MESA_read_runtime_log_handle_conf(handle, conf_file_path);
if(rtn == -1){
return NULL;
}
}
return handle;
}
void* MESA_create_runtime_log_handle_new(const char *logger_id){
if(logger_id == NULL){
return NULL;
}
el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog);
std::string logger_id1(logger_id);
el::Logger* logger = el::Loggers::getLogger(logger_id1);
el::Configurations* default_conf = new el::Configurations();
set_default_conf(default_conf);
return create_handle_helper(logger, default_conf);
}
int level_trans_helper(int level, el::Level& el_level){
struct level_trans_item {
int level;
el::Level el_level;
};
static struct level_trans_item level_trans_map[] = {
{ RLOG_LV_DEBUG, el::Level::Debug },
{ RLOG_LV_INFO, el::Level::Info },
{ RLOG_LV_FATAL, el::Level::Fatal }
};
for(auto item : level_trans_map){
if(item.level == level){
el_level = item.el_level;
return 0;
}
}
return -1;
}
int conf_trans_helper(const char* key, el::ConfigurationType& el_conf_type){
if(key == NULL){
return -1;
}
struct conf_trans_item{
const char* key;
el::ConfigurationType conf_type;
};
static struct conf_trans_item conf_trans_map[] = {
{ "enabled", el::ConfigurationType::Enabled },
{ "to_file", el::ConfigurationType::ToFile },
{ "to_standard_output", el::ConfigurationType::ToStandardOutput },
{ "format", el::ConfigurationType::Format },
{ "file_name", el::ConfigurationType::Filename },
{ "max_log_file_size", el::ConfigurationType::MaxLogFileSize},
{ "sub_second_precision", el::ConfigurationType::SubsecondPrecision },
{ "performance_tracking", el::ConfigurationType::PerformanceTracking},
{ "log_flush_threshold", el::ConfigurationType::LogFlushThreshold },
};
for(auto item : conf_trans_map){
if(strcmp(key, item.key) == 0){
el_conf_type = item.conf_type;
return 0;
}
}
return -1;
}
int MESA_read_runtime_log_handle_conf(void* handle, const char* conf_file_path){
if(handle == NULL || conf_file_path == NULL){
return -1;
}
struct runtime_log_handle* handle1 = (struct runtime_log_handle*)handle;
el::Configurations* conf = new el::Configurations(conf_file_path);
handle1->conf = conf;
el::Loggers::reconfigureLogger(handle1->logger, *(handle1->conf));
return 0;
}
int MESA_set_runtime_log_handle_opt(void* handle, int level, const char* key, const char* value){
el::Level el_level;
int level_trans_rtn = level_trans_helper(level, el_level);
if(level_trans_rtn == -1){
return -1;
}
el::ConfigurationType el_conf_type;
int conf_trans_rtn = conf_trans_helper(key, el_conf_type);
if(conf_trans_rtn == -1){
return -1;
}
struct runtime_log_handle* handle1 = (struct runtime_log_handle*)handle;
(handle1->conf)->set(el_level, el_conf_type, value);
el::Loggers::reconfigureLogger(handle1->logger, *(handle1->conf));
return 0;
}
void MESA_handle_runtime_log(void* handle, int level, const char* module, const char* fmt, ...){
assert(handle != NULL);
assert(level == RLOG_LV_FATAL || level == RLOG_LV_INFO || level == RLOG_LV_DEBUG);
struct runtime_log_handle* handle1 = (struct runtime_log_handle*)handle;
el::Logger* logger = handle1->logger;
va_list ap;
va_start(ap, fmt);
char buf[LOGMSG_MAX_LEN];
char* buf1 = buf;
if(module != NULL){
strcpy(buf1, module);
buf1 += strlen(module);
strcpy(buf1, ", ");
buf1 += 2;
vsprintf(buf1,fmt,ap);
}
switch(level){
case RLOG_LV_FATAL:
logger->fatal(buf);
break;
case RLOG_LV_INFO:
logger->info(buf);
break;
case RLOG_LV_DEBUG:
logger->debug(buf);
break;
}
}
void MESA_destroy_runtime_log_handle(void* handle){
if(handle != NULL){
struct runtime_log_handle* handle1 = (struct runtime_log_handle*)handle;
el::Configurations* conf = handle1->conf;
delete(conf);
free(handle);
handle = NULL;
}
return;
}
#ifdef __cplusplus
}
#endif

27
src/Makefile Normal file
View File

@@ -0,0 +1,27 @@
CXX = g++ -std=c++11
TARGET_DIR = ../lib
TARGET = libMESA_handle_logger.so
CXXFLAGS = -g -Wall -fPIC -DELPP_THREAD_SAFE
LIB = -lpthread
INCLUDES = -I./include/
SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)
DEPS = $(SOURCES:.c=.d)
.PHONY : clean all install
all : $(TARGET)
$(TARGET) : $(OBJECTS)
$(CXX) $(CXXFLAGS) -shared -o $(TARGET) $(LIB) $(OBJECTS)
%.o : %.c
$(CXX) $(CXXFLAGS) -c $< -o $@
%.d : %.c
$(CXX) $< -MM $(INCLUDES) > $@
-include $(DEPS)
clean :
-rm $(TARGET) $(OBJECTS) $(DEPS)
-rm -f $(TARGET_DIR)/*
install :
-cp $(TARGET) $(TARGET_DIR)
-rm $(TARGET) $(OBJECTS) $(DEPS)

3104
src/easylogging++.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
#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, you can only use 3 levels: RLOG_LV_DEBUG, RLOG_LV_INFO, RLOG_LV_FATAL;
* 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_create_runtime_log_handle_new
* functionality: get runtime_log handle, it depends on easylogging++.
* we recommend you to use the new constructed function;;
* params:
* logger_id: indentify a handle;
* no parameter level, we recommand you to use MESA_set_runtime_log_handle_opt to enable or disable a level
* returns:
* not NULL, if succeeded;
* NULL, if logger_id == NULL or level is invalid;
*/
void* MESA_create_runtime_log_handle_new(const char* logger_id);
/*
* 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_read_handle_runtime_log_conf
* functionality: read and set the conf of a handle;
* params:
* handle: handle of runtime log;
* conf_file_path: path of the conf file;
* returns:
* 0, if succeeded;
* -1, if failed;
*/
int MESA_read_runtime_log_handle_conf(void* handle, const char* conf_file_path);
/*
* name: MESA_set_runtime_log_handle_opt
* functionality: set option of a runtime_log_handle;
* params:
* handle: handle of runtime log;
* level: log level;
* key: key of option ;
* value: value of option;
* returns:
* 0, if succeeded;
* -1, if failed;
*/
int MESA_set_runtime_log_handle_opt(void* handle, int level, const char* key, const char* value);
/*
* 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

4560
src/include/easylogging++.h Normal file

File diff suppressed because it is too large Load Diff