#include "inner_log.h" #include #include "log_util.h" #include "log_multi_thread.h" #ifdef _WIN32 #include #include #else #include #include #include #endif ////////////////////////////////////////////////////////////////////////// typedef struct RvcLog { CRITICALSECTION lock; FILE* file_handle; int show_file_info; //是否显示文件行号 int log_level; char log_filename_prefix[512]; //日志文件前缀名 char log_file_name[512]; char* log_buf; char* write_log_buf; int write_log_buf_size; int write_log_len; }RvcLog; //私有方法,外部不要调用 int _rvclog_init_internal(RvcLog* rvc_log); int _rvclog_destroy_internal(RvcLog* rvc_log); int _flush_log(RvcLog* rvc_log); int _close_log_file(RvcLog* rvc_log); int _remove_log_file(RvcLog* rvc_log); void _get_daylog_filename(RvcLog* rvc_log, char* buf); int _open_logfile(RvcLog* rvc_log); int _set_logfile(RvcLog* rvc_log, const char* logfileName); int _create_dir(const char* szPath); static RvcLog *rvc_system_log = NULL; static int is_prd = 1;//set 1 to no log in product char* rcv_log_buf = NULL; char* AllocLogBuf(void) { if (!rcv_log_buf) { rcv_log_buf = (char*)malloc(MFLOG_BUFSIZE + 1); memset(rcv_log_buf, 0, MFLOG_BUFSIZE + 1); return rcv_log_buf; } else { return rcv_log_buf; } } void MakeLogPrefix(int nLevel, char* szLevel, char* szTime) { struct tm* today; time_t ltime; #if defined(_MSC_VER) time(<ime); today = localtime(<ime); #else struct timeval tv; time(<ime); today = localtime(<ime); gettimeofday(&tv, NULL); #endif //_MSC_VER switch (nLevel) { case LM_TRACE: strcpy(szLevel, "TRACE"); break; case LM_DEBUG: strcpy(szLevel, "DEBUG"); break; case LM_INFO: strcpy(szLevel, "INFO"); break; case LM_NOTICE: strcpy(szLevel, "NOTICE"); break; case LM_WARNING: strcpy(szLevel, "WARNING"); break; case LM_ERROR: strcpy(szLevel, "ERROR"); break; case LM_CRITICAL: strcpy(szLevel, "CRITICAL"); break; default: strcpy(szLevel, "UNKNOWN"); break; } #if defined(_MSC_VER) sprintf(szTime, "%02d%02d%02d %02d%02d%02d", today->tm_year + 1900 - 2000, today->tm_mon + 1, today->tm_mday, today->tm_hour, today->tm_min, today->tm_sec ); #else sprintf(szTime, "%04d-%02d-%02d %02d:%02d:%02d.%03d", today->tm_year + 1900, today->tm_mon + 1, today->tm_mday, today->tm_hour, today->tm_min, today->tm_sec, tv.tv_usec / 1000 ); #endif //_MSC_VER } int RvcLog_init(const char* log_dir, const char* log_name, int level, int show_file_line) { if (level == LM_OFF) { is_prd = 1; return 0; } is_prd = 0; if (rvc_system_log != NULL) { return 0; } rvc_system_log = (RvcLog*)malloc(sizeof(RvcLog)); _rvclog_init_internal(rvc_system_log); rvc_system_log->log_level = level; rvc_system_log->show_file_info = show_file_line; { char buf[512]; strncpy(buf, log_dir, 512); #ifdef WIN32 strncpy(buf + strlen(buf), "\\", 512 - strlen(buf)); #else strncpy(buf + strlen(buf), "/", 512 - strlen(buf)); #endif strncpy(buf + strlen(buf), log_name, 512 - strlen(buf)); _set_logfile(rvc_system_log, buf); } return 0; } int RvcLog_destroy() { //huchen add for 生产,不写日志 if (is_prd) { return 0; } _rvclog_destroy_internal(rvc_system_log); if (rcv_log_buf) free(rcv_log_buf); return 0; } int RvcLog_log(const char* szSrcFileName, int iLine, int console, int iLevel, char* szLevel, char* szTime, char* szLog) { RvcLog* rvc_log; char* fileSuffix; //huchen add for 生产,不写日志 if (is_prd) { return 0; } rvc_log = rvc_system_log; if (iLevel < rvc_log->log_level) return 0; //多线程要加锁 CS_ENTER(rvc_log->lock); if (rvc_log->log_buf == NULL) { CS_LEAVE(rvc_log->lock); return -1; } if (rvc_log->show_file_info) { #if defined(_MSC_VER) fileSuffix = strrchr(szSrcFileName, '\\'); #else fileSuffix = strrchr(szSrcFileName, '/'); #endif //_MSC_VER if (fileSuffix != NULL) { fileSuffix += 1; } else { ///*TODO: (80374374@10/24/2023)*/ fileSuffix = szSrcFileName; } snprintf(rvc_log->log_buf, MFLOG_BUFSIZE, "%s:%s:%ld:[%d@%s]:%s\n", szTime, szLevel, #if defined(_MSC_VER) GetCurrentThreadId(), #else (size_t)syscall(SYS_gettid), #endif //_MSC_VER iLine, fileSuffix, szLog ); } else { snprintf(rvc_log->log_buf, MFLOG_BUFSIZE, "%s[%ld]:%s\n", szTime, #if defined(_MSC_VER) GetCurrentThreadId(), #else (size_t)syscall(SYS_gettid), #endif //_MSC_VER szLog ); } { int tmpLen = strlen(rvc_log->log_buf); if (tmpLen + rvc_log->write_log_len > rvc_log->write_log_buf_size) { _flush_log(rvc_log); rvc_log->write_log_len = 0; } memcpy(rvc_log->write_log_buf + rvc_log->write_log_len, rvc_log->log_buf, tmpLen); rvc_log->write_log_buf[rvc_log->write_log_len + tmpLen] = 0; rvc_log->write_log_len += tmpLen; if (rvc_log->write_log_len >= MF_LOG_STR_BUFSIZE) { _flush_log(rvc_log); rvc_log->write_log_len = 0; } ////////////////////////////////////////////////////////////////////////// _flush_log(rvc_log); rvc_log->write_log_len = 0; ////////////////////////////////////////////////////////////////////////// } if (console) { printf("%s", rvc_log->log_buf); } CS_LEAVE(rvc_log->lock); return 0; } int _rvclog_init_internal(RvcLog* rvc_log) { if (!rvc_log) return -1; rvc_log->file_handle = NULL; rvc_log->log_buf = (char*)malloc(MFLOG_BUFSIZE + 1); memset(rvc_log->log_buf, 0, MFLOG_BUFSIZE + 1); rvc_log->log_buf[MFLOG_BUFSIZE] = 0; rvc_log->write_log_buf = (char*)malloc(MF_LOG_STR_BUFSIZE); memset(rvc_log->write_log_buf, 0, MF_LOG_STR_BUFSIZE); rvc_log->write_log_buf_size = MF_LOG_STR_BUFSIZE; rvc_log->write_log_len = 0; rvc_log->log_level = 0; rvc_log->show_file_info = 0; rvc_log->lock = CreateCriticalSection(); return 0; } int _rvclog_destroy_internal(RvcLog* rvc_log) { if (!rvc_log) return -1; _flush_log(rvc_log); _close_log_file(rvc_log); if (rvc_log->log_buf) free(rvc_log->log_buf); if (rvc_log->write_log_buf) free(rvc_log->write_log_buf); ReleaseCriticalSection(rvc_log->lock); free(rvc_log); return 0; } int _flush_log(RvcLog* rvc_log) { //多线程还要考虑同步问题,这里先不考虑 //CMutexGuard g( m_LogMutex ); int iRC; if (rvc_log->write_log_len == 0 || !rvc_log->write_log_buf) return -1; iRC = fwrite(rvc_log->write_log_buf, rvc_log->write_log_len, 1, rvc_log->file_handle); fflush(rvc_log->file_handle); if (iRC <= 0) { } else { char buf[512]; _get_daylog_filename(rvc_log, buf); if (0 != strcmp(rvc_log->log_file_name, (const char*)buf)) { _close_log_file(rvc_log); _remove_log_file(rvc_log); strncpy(rvc_log->log_file_name, buf, 512); _open_logfile(rvc_log); } } rvc_log->write_log_len = 0; return 0; } int _remove_log_file(RvcLog* rvc_log) { if (rvc_log->log_file_name) { remove(rvc_log->log_file_name); } return 0; } int _close_log_file(RvcLog* rvc_log) { if (rvc_log->file_handle) { fclose(rvc_log->file_handle); rvc_log->file_handle = NULL; } return 0; } int _open_logfile(RvcLog* rvc_log) { rvc_log->file_handle = fopen(rvc_log->log_file_name, "r"); if (rvc_log->file_handle) { fclose(rvc_log->file_handle); rvc_log->file_handle = NULL; rvc_log->file_handle = fopen(rvc_log->log_file_name, "a"); } else rvc_log->file_handle = fopen(rvc_log->log_file_name, "w"); if (rvc_log->file_handle) return 0; return -1; } void _get_daylog_filename(RvcLog* rvc_log, char* buf) { time_t lTime = time(NULL); struct tm* tm1 = localtime(&lTime); sprintf(buf, "%s%02d%02d%02d.log", rvc_log->log_filename_prefix, tm1->tm_year + 1900 - 2000, tm1->tm_mon + 1, tm1->tm_mday ); } int _set_logfile(RvcLog* rvc_log, const char* logfileName) { //多线程同步 int len = strlen(logfileName); int iSub = 0; int i = 0; char FileDir[255]; if (!logfileName || strlen(logfileName) <= 0) { return -1; } for (i = len - 1; i >= 0; i--) { if (logfileName[i] == '/'|| logfileName[i] == '\\') { iSub = i; break; } } memcpy(FileDir, logfileName, iSub + 1); FileDir[iSub + 1] = 0; if (strlen(FileDir) > 0) { if (mkdir_foreach(FileDir, strlen(FileDir)) != 0){ return -1; } } strcpy(rvc_log->log_filename_prefix, logfileName); _close_log_file(rvc_log); _get_daylog_filename(rvc_log, rvc_log->log_file_name); _remove_log_file(rvc_log); return _open_logfile(rvc_log); } int _create_dir(const char* szPath) { char buf[128] = { 0 }; int i = 0; int buf_idx = 0; if (!szPath) return -1; while (szPath[i] != 0) { if (szPath[i] == '\\' || szPath[i] == '/') { if (buf_idx > 0) { #if defined(_MSC_VER) if (mkdir(buf)) #else if (mkdir(buf, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) #endif //_MSC_VER { if (EEXIST != errno) { return -2; } } } } { buf[buf_idx] = szPath[i]; buf_idx++; } i++; } if (buf_idx > 0) { #if defined(_MSC_VER) if (mkdir(buf)) #else if (mkdir(buf, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) #endif //_MSC_VER { if (EEXIST != errno) { return -2; } } } return 0; }