#include "include/easylogging++.h" #include "include/MESA_handle_logger.h" #include #include #include #include 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 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; delete(handle1->conf); 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