#include "precompile.h" #include "log.h" #include "log_mgr.h" #include "log_single.h" #include "log_periodic.h" #include "log_udpclient.h" #include "log_udpdaemon.h" #include "iniutil.h" #include "fileutil.h" #include "sockutil.h" #include "dbgutil.h" #ifdef _WIN32 #include "modCheck.h" #endif //_WIN32 #include #define XLOG_VERSION 0x0101 #ifndef _WIN32 static logmgr_t* g_mgr = 0; static int g_initialized = 0; #endif //!_WIN32 TOOLKIT_API int xlog_version(); TOOLKIT_API int xlog_init2(const char *inifile, const char *sections); TOOLKIT_API int xlog_set_level(const char* inst, int level); TOOLKIT_API int xlog_get_level(const char* inst, int *level); /*get ini file from ini|etc|conf folder under current execute directory*/ static char *find_best_config() { char path[MAX_PATH]; char *filepart; GetModuleFileNameA(NULL, path, MAX_PATH); filepart = strrchr(path, SPLIT_SLASH); if (filepart) { *filepart = 0; filepart++; if (strlen(filepart) > 4) { int i; struct { char *fmt; char *str1; char *str2; }defaultfilepath[] = { {"%s" SPLIT_SLASH_STR "ini" SPLIT_SLASH_STR "log" SPLIT_SLASH_STR "%s.ini", path, filepart}, {"%s" SPLIT_SLASH_STR "etc" SPLIT_SLASH_STR "log" SPLIT_SLASH_STR "%s.ini", path, filepart}, {"%s" SPLIT_SLASH_STR "conf" SPLIT_SLASH_STR "log" SPLIT_SLASH_STR "%s.ini", path, filepart}, {"%s" SPLIT_SLASH_STR "log.ini", path, NULL}, {"%s" SPLIT_SLASH_STR "ini" SPLIT_SLASH_STR "log.ini", path, filepart}, {"%s" SPLIT_SLASH_STR "etc" SPLIT_SLASH_STR "log.ini", path, filepart}, {"%s" SPLIT_SLASH_STR "conf" SPLIT_SLASH_STR "log.ini", path, filepart}, {NULL, NULL, NULL}, }; filepart[strlen(filepart)-4] = 0; for (i = 0; defaultfilepath[i].fmt != NULL; ++i) { char tmp[MAX_PATH]; sprintf(tmp, defaultfilepath[i].fmt, defaultfilepath[i].str1, defaultfilepath->str2); if (ExistsFileA(tmp)) return _strdup(tmp); } } } return NULL; } static int contains_name(va_list arg, const char *name) { char *p; while((p = va_arg(arg, char*)) != NULL) { if (_stricmp(name, p) == 0) return TRUE; } return 0; } TOOLKIT_API int xlog_version() { return XLOG_VERSION; } TOOLKIT_API int xlog_init(const char *file) { return xlog_init2(file, NULL); } TOOLKIT_API int xlog_init2(const char *file, const char *sections) { logfactory_t *fac; array_header_t *arr_section = NULL; char *copysections = NULL; char *best_config_file = NULL; int rc = 0; #ifdef _WIN32 if (toolkit_getResource()->g_initialized++) { return 0; } #else if (g_initialized++) { return 0; } #endif //_WIN32 winsock_init(); if (sections) { const char *delimers = ",| "; char *p; copysections = _strdup(sections); arr_section = array_make(3, sizeof(char*)); p = strtok(copysections, delimers); while (p) { ARRAY_PUSH(arr_section, char*) = p; p = strtok(NULL, delimers); } } #ifdef _WIN32 logmgr_create(&((logmgr_t *)(toolkit_getResource()->g_mgr))); #else logmgr_create(&g_mgr); #endif //_WIN32 /*gcc error: lvalue required as unary ‘&’ operand*/ //logmgr_create(&((logmgr_t*)(toolkit_getResource()->g_mgr))); singlefilefactory_create(&fac); #ifdef _WIN32 logmgr_register_factory((logmgr_t*)(toolkit_getResource()->g_mgr), fac); periodicfilefactory_create(&fac); logmgr_register_factory((logmgr_t*)(toolkit_getResource()->g_mgr), fac); udplogfactory_create(&fac); logmgr_register_factory((logmgr_t*)(toolkit_getResource()->g_mgr), fac); udplogdaemonfactory_create(&fac); logmgr_register_factory((logmgr_t*)(toolkit_getResource()->g_mgr), fac); #else logmgr_register_factory((logmgr_t*)(g_mgr), fac); periodicfilefactory_create(&fac); logmgr_register_factory((logmgr_t*)(g_mgr), fac); udplogfactory_create(&fac); logmgr_register_factory((logmgr_t*)(g_mgr), fac); udplogdaemonfactory_create(&fac); logmgr_register_factory((logmgr_t*)(g_mgr), fac); #endif //_WIN32 if (!file) { best_config_file = find_best_config(); } //file为null,而且根据正常而言也搜索不到对应的配置 if (best_config_file) { int i; array_header_t *arr_sec = inifile_read_section_all(best_config_file); if (arr_sec) { for (i = 0; i < arr_sec->nelts; ++i) { int found = 0; int kk; char *sec = ARRAY_IDX(arr_sec, i, char*); if (sections) { for (kk = 0; kk < arr_section->nelts; ++kk) if (_stricmp(sec, ARRAY_IDX(arr_section, kk, char*)) == 0) found = 1; } if (!sections || found) { array_header_t *arr_key = inifile_read_section_key_all(best_config_file, sec); if (arr_key) { char *type_tag = ARRAY_IDX(arr_key, 0, char*); if (type_tag && _stricmp(type_tag, "type") == 0) { char *type_value = inifile_read_str(best_config_file, sec, type_tag, ""); if (type_value) { if (strlen(type_value) > 0) { logbase_t *log; #ifdef _WIN32 rc = logmgr_create_log((logmgr_t*)(toolkit_getResource()->g_mgr), type_value, sec, &log); #else rc = logmgr_create_log((logmgr_t*)(g_mgr), type_value, sec, &log); #endif //_WIN32 if (rc == 0) { int k; for (k = 1; k < arr_key->nelts; ++k) { char *key_tag = ARRAY_IDX(arr_key, k, char*); char *key_value = inifile_read_str(best_config_file, sec, key_tag, ""); if (key_value) { logfactory_set_log_param(log->factory, log, key_tag, key_value); free(key_value); } } #ifdef _WIN32 rc = logmgr_init_log((logmgr_t*)(toolkit_getResource()->g_mgr), log); if (rc != 0) { logmgr_destroy_log((logmgr_t*)(toolkit_getResource()->g_mgr), log); } #else rc = logmgr_init_log((logmgr_t*)(g_mgr), log); if (rc != 0) { logmgr_destroy_log((logmgr_t*)(g_mgr), log); } #endif //_WIN32 } } free(type_value); } } array_free2(arr_key); } } } array_free2(arr_sec); } } //on_error: if (copysections) free(copysections); if (arr_section) array_free(arr_section); if (rc < 0) { #ifdef _WIN32 logmgr_destroy((logmgr_t *)(toolkit_getResource()->g_mgr)); (logmgr_t *)(toolkit_getResource()->g_mgr) = NULL; #else logmgr_destroy(g_mgr); g_mgr = NULL; #endif //_WIN32 } return rc; } TOOLKIT_API int xlog_add_logger(const char *name, const char *type, ...) { logbase_t *log; int rc; if (!name || !strlen(name)) return -1; if (!type || !strlen(type)) return -1; #ifdef _WIN32 rc = logmgr_create_log((logmgr_t*)(toolkit_getResource()->g_mgr), type, name, &log); #else rc = logmgr_create_log(g_mgr, type, name, &log); #endif //_WIN32 if (rc == 0) { va_list arg; const char *key, *value; va_start(arg, type); key = va_arg(arg, const char*); while (key) { value = va_arg(arg, const char*); logfactory_set_log_param(log->factory, log, key, value); key = va_arg(arg, const char*); } va_end(arg); #ifdef _WIN32 rc = logmgr_init_log((logmgr_t*)(toolkit_getResource()->g_mgr), log); if (rc != 0) { logmgr_destroy_log((logmgr_t*)(toolkit_getResource()->g_mgr), log); } #else rc = logmgr_init_log(g_mgr, log); if (rc != 0) { logmgr_destroy_log(g_mgr, log); } #endif //_WIN32 } return rc; } TOOLKIT_API int xlog_remove_logger(const char *name) { logbase_t *log; #ifdef _WIN32 if (name) { log = logmgr_find_log((logmgr_t*)(toolkit_getResource()->g_mgr), name); if (log) { logmgr_term_log((logmgr_t*)(toolkit_getResource()->g_mgr), log); logmgr_destroy_log((logmgr_t*)(toolkit_getResource()->g_mgr), log); return 0; } } #else if (name) { log = logmgr_find_log(g_mgr, name); if (log) { logmgr_term_log(g_mgr, log); logmgr_destroy_log(g_mgr, log); return 0; } } #endif //_WIN32 return -1; } TOOLKIT_API int xlog_term() { #ifdef _WIN32 toolkit_getResource()->g_initialized--; if (toolkit_getResource()->g_initialized) { return 0; } if ((logmgr_t*)(toolkit_getResource()->g_mgr)) { logmgr_destroy((logmgr_t*)(toolkit_getResource()->g_mgr)); (toolkit_getResource()->g_mgr) = 0; winsock_term(); return 0; } #else g_initialized--; if (g_initialized) { return 0; } if ((g_mgr)) { logmgr_destroy(g_mgr); g_mgr = 0; winsock_term(); return 0; } #endif //_WIN32 return -1; } TOOLKIT_API int xlog_set_level(const char* inst, int level) { if (!inst) return -1; #ifdef _WIN32 if ((logmgr_t*)(toolkit_getResource()->g_mgr)) { logbase_t* log = logmgr_find_log((logmgr_t*)(toolkit_getResource()->g_mgr), inst); #else if ((logmgr_t*)(g_mgr)) { logbase_t* log = logmgr_find_log((logmgr_t*)(g_mgr), inst); #endif //_WIN32 if (log) { log->level = level; return 0; } } return -1; } TOOLKIT_API int xlog_get_level(const char* inst, int *level) { if (!inst) return -1; #ifdef _WIN32 if ((logmgr_t*)(toolkit_getResource()->g_mgr)) { logbase_t* log = logmgr_find_log((logmgr_t*)(toolkit_getResource()->g_mgr), inst); #else if ((logmgr_t*)(g_mgr)) { logbase_t* log = logmgr_find_log((logmgr_t*)(g_mgr), inst); #endif //_WIN32 if (log) { *level = log->level; return 0; } } return -1; } TOOLKIT_API int xlog_log(const char *inst, int level, const char *str) { logbase_t *log; int n; #ifdef _WIN32 if (!(logmgr_t*)(toolkit_getResource()->g_mgr)) #else if (!g_mgr) #endif //_WIN32 return -1; n = str ? strlen(str) : 0; if (n == 0) return 0; #ifdef _WIN32 log = logmgr_find_log((logmgr_t*)(toolkit_getResource()->g_mgr), inst); if (log) { FILETIME ft; SYSTEMTIME st; GetSystemTime(&st); SystemTimeToFileTime(&st, &ft); logfactory_log_record(log->factory, log, level, ft.dwLowDateTime, ft.dwHighDateTime, str, n); return 0; } #else log = logmgr_find_log(g_mgr, inst); if (log) { FILETIME ft = {0, 0}; logfactory_log_record(log->factory, log, level, ft.dwLowDateTime, ft.dwHighDateTime, str, n); return 0; } #endif //_WIN32 return -1; } TOOLKIT_API int xlog_log_v(const char *inst, int level, const char *fmt, va_list arg) { int n; logbase_t *log; FILETIME ft; SYSTEMTIME st; #ifdef _WIN32 if (!(logmgr_t*)(toolkit_getResource()->g_mgr)) #else if (!g_mgr) #endif //_WIN32 return -1; #ifdef _WIN32 log = logmgr_find_log((logmgr_t*)(toolkit_getResource()->g_mgr), inst); #else log = logmgr_find_log(g_mgr, inst); #endif //_WIN32 if (!log) return -1; #ifdef _WIN32 GetSystemTime(&st); SystemTimeToFileTime(&st, &ft); #endif if (level < log->level) { logfactory_log_record(log->factory, log, level, ft.dwLowDateTime, ft.dwHighDateTime, NULL, 0); return 0; } n = _vscprintf(fmt, arg);//因为添加了Debug {}, 所以可能超过了1024长度 if (n >= 0) { int len = 1050 + 1; char *buf = malloc(len); if (buf) { memset(buf, 0, len); vsnprintf(buf, 1050, fmt, arg); logfactory_log_record(log->factory, log, level, ft.dwLowDateTime, ft.dwHighDateTime, buf, strlen(buf)); free(buf); } return 0; } return -1; } TOOLKIT_API logbase_t *xlog_find_log(const char *inst) { #ifdef _WIN32 return logmgr_find_log((logmgr_t*)(toolkit_getResource()->g_mgr), inst); #else return logmgr_find_log(g_mgr, inst); #endif //_WIN32 }