// Logger.cpp : 定义 DLL 应用程序的导出函数。 // #include "stdafx.h" #include "Logger.h" #include "BuffManager.h" #include "FileManager.h" #include "localConfig.h" #include "CircleBuff.h" #include "common_api.h" #include "LogFileSaveThread.h" #include "CDInterface.h" #include #include bool g_SystemInit = false; Logger *g_pProcLogger = NULL; Logger *g_pBusLogger = NULL; void UpdateLogger(Logger &log) { Logger_Pattern Pattern; log.GetLogPattern(Pattern); ResDataObject res; if (GetLogPatternResource(res)) { try { Pattern.m_Level = (LOG_LEVEL)((int)res["LEVEL"]); Pattern.MaxFileSize = res["MAXFILESIZE"]; Pattern.MaxBackupCount = res["MAXBACKUPCOUNT"]; Pattern.MaxTimePeriod = res["MAXTIMEPERIOD"]; //debug info Pattern.PrintFileName = res["FILENAME"]; Pattern.PrintFunctionName = res["FUNCTIONNAME"]; Pattern.PrintLine = res["LINE"]; //date Pattern.PrintDate = res["DATE"]; //Proc Pattern.PrintProcId = res["PROC"]; //Thread Pattern.PrintThreadId = res["THREAD"]; Pattern.Cachable = res["CACHE"]; log.SetLogPattern(Pattern); } catch (...) { } } }; class Logger_Monitor { public: Logger_Monitor() { string FullFileName = GetProcessDirectory() + string("\\logs\\General.log"); Logger* p = (new Logger()); UpdateLogger(*p); if (p) { p->SetLogFilepath(FullFileName.c_str()); g_pProcLogger = p; } FullFileName = GetProcessDirectory() + string("\\logs\\eBus.log"); p = (new Logger()); UpdateLogger(*p); if (p) { p->SetLogFilepath(FullFileName.c_str()); g_pBusLogger = p; } }; ~Logger_Monitor() { if (g_pProcLogger) { delete (g_pProcLogger); g_pProcLogger = NULL; } if (g_pBusLogger) { delete (g_pBusLogger); g_pBusLogger = NULL; } }; }; Logger_Monitor g_Logger_Monitor; Logger_Pattern::Logger_Pattern(void) { m_Level = LOG_LEVEL_INIT; MaxFileSize = 1024*1024*10;//log file size limit.def:10M MaxBackupCount = 1;//log file count limit.def:0 MaxTimePeriod = 0;//use less PrintFileName = true; PrintFunctionName = false; PrintLine = true; //date PrintDate = false; //Proc PrintProcId = false; //Thread PrintThreadId = false; Cachable = true; } Logger_Pattern::~Logger_Pattern(void) { } bool Logger_Pattern::SetLevel(LONG Level) { if (Level < LOG_LEVEL_INIT || Level >= LOG_LEVEL_MAX) { return false; } m_Level = (LOG_LEVEL)Level; return true; } Logger::Logger(Logger &obj) { (*m_pFullLogFileName) = (*obj.m_pFullLogFileName); (*m_pPattern) = (*obj.m_pPattern); } Logger::Logger() { m_pFullLogFileName = new string(); m_pErrFullLogFileName = new string(); m_pPattern = new Logger_Pattern(); m_FileId = 0; } Logger::~Logger() { Thread_Lock(7000); delete m_pFullLogFileName; delete m_pErrFullLogFileName; delete m_pPattern; Thread_UnLock(); } Logger& Logger::operator = (const Logger &tValue) { Thread_Lock(); if (this != &tValue) { (*m_pFullLogFileName) = (*tValue.m_pFullLogFileName); (*m_pPattern) = (*tValue.m_pPattern); } Thread_UnLock(); return (*this); } void Logger::SetLogPattern(Logger_Pattern &Pattern) { Thread_Lock(); (*m_pPattern) = Pattern; Thread_UnLock(); } void Logger::GetLogPattern(Logger_Pattern &Pattern) { Thread_Lock(); Pattern = (*m_pPattern); Thread_UnLock(); } void Logger::SetLogFilepath(const char *pPath) { Thread_Lock(); //create id if (pPath && strlen(pPath) > 0) { m_FileId = g_BlockMap.CreateLogFile(pPath); (*m_pFullLogFileName) = pPath; } Thread_UnLock(); } bool Logger::IsLogFilePathExist() { bool ret = false; Thread_Lock(); if (m_pFullLogFileName->size() > 0) { ret = true; } Thread_UnLock(); return ret; } const char* Logger::GetErrLogFilePath() { bool ret = false; Thread_Lock(); if (m_pFullLogFileName->size() > 0) { (*m_pErrFullLogFileName) = ReplaceFileTitle((*m_pFullLogFileName), string("err")); ret = true; } Thread_UnLock(); if (ret) { return m_pErrFullLogFileName->c_str(); } return NULL; } bool Logger::ChangeLoggerFileTitle(Logger* p, const char *pTitle) { bool ret = false; if (p == NULL || pTitle == NULL) { return ret; } string FilePath = GetFileDirectory((*m_pFullLogFileName)); FilePath += string("\\") + string(pTitle); Thread_Lock(); ret = g_BlockMap.ChangeFilePath(m_FileId, FilePath.c_str()); Thread_UnLock(); return ret; } DWORD Logger::GetLogFileId() { return m_FileId; } int Logger::GetLogLevel() { return m_pPattern->m_Level; } LOGGER_C_API Logger* GetBusLogger() { return g_pBusLogger; } LOGGER_C_API Logger* GetGlobalLogger() { return g_pProcLogger; } LOGGER_C_API Logger* GetThreadLogger() { PVOID pLogger = NULL; //#ifndef TEMP_COMP //CDInterface *p = CDInterface::GetCDI(); //if (p) //{ // p->GetThreadsLogger(GetCurrentThreadId(), pLogger); //} //#endif return (Logger*)pLogger; } LOGGER_C_API Logger* CreateLogger() { Logger* p = (new Logger()); UpdateLogger(*p); return p; } LOGGER_C_API void ReleseLogger(Logger* p) { if ((g_pProcLogger == p) || (g_pBusLogger == p)) { return; } delete p; } LOGGER_C_API void ExitLoggerModule() { printf("Logger:StopThread Entry\n"); if (g_LogThread.StopThread() == false) { printf("Logger:StopThread Used Terminate!!!!!!!!!!!!!!!\n"); } printf("Logger:StopThread Exit\n"); } size_t GetHeadFormat(LOG_LEVEL Level, const char* file, int line, const char* function, Logger_Pattern &Pattern, BuffNode* pNode) { if (Level < Pattern.m_Level) { return 0; } int copiedcount = 0; size_t Idx = strlen(&(pNode->m_Buff[0])); SYSTEMTIME st; GetLocalTime(&st); //return code char szRet[] = "\n"; if (strncpy_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, szRet, _TRUNCATE) == 0) { Idx += strlen(szRet); } else { return PAGE - 1; } //DATE if (Pattern.PrintDate) { copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "[%04d:%02d:%02d] ", st.wYear, st.wMonth, st.wDay); if (copiedcount > 0) { Idx += copiedcount; } else { return PAGE - 1; } } //TIME copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "[%02d:%02d:%02d:%03d] ", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); if (copiedcount > 0) { Idx += copiedcount; } else { return PAGE - 1; } //LEVEL switch (Level) { case LOG_LEVEL_TRACE: copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "[%-7s] ", "TRACE"); break; case LOG_LEVEL_DEBUG: copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "[%-7s] ", "DEBUG"); break; case LOG_LEVEL_INFO: copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "[%-7s] ", "INFO"); break; case LOG_LEVEL_WARNING: copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "[%-7s] ", "WARNING"); break; case LOG_LEVEL_ERROR: copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "[%-7s] ", "ERROR"); break; case LOG_LEVEL_FATAL: copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "[%-7s] ", "FATAL"); break; default: copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "[%-7s] ", "UNKNOWN"); break; } if (copiedcount > 0) { Idx += copiedcount; } else { return PAGE - 1; } //PID if (Pattern.PrintProcId) { copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "[P:%08X] ", GetCurrentProcessId()); if (copiedcount > 0) { Idx += copiedcount; } else { return PAGE - 1; } } //TID if (Pattern.PrintThreadId) { copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "[T:%08X] ", GetCurrentThreadId()); if (copiedcount > 0) { Idx += copiedcount; } else { return PAGE - 1; } } //file name if (Pattern.PrintFileName) { copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "[%s", file); if (copiedcount > 0) { Idx += copiedcount; } else { return PAGE - 1; } } //line num if (Pattern.PrintLine) { copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "(%d)", line); if (copiedcount > 0) { Idx += copiedcount; } else { return PAGE - 1; } } //func name if (Pattern.PrintFunctionName) { copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "(%s)", function); if (copiedcount > 0) { Idx += copiedcount; } else { return PAGE - 1; } } char szLast[] = "] :"; //last one if (strncpy_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, szLast, _TRUNCATE) == 0) { Idx += strlen(szLast); return Idx; } return PAGE - 1; } void SaveTheLog(Logger_Pattern &Pattern, Logger *pLog, const char *pContext, size_t ContextSize, int Level) { LOGFILESTATUS status; status.InitStatus = true; status.MaxBackupCount = Pattern.MaxBackupCount; status.MaxFileSize = Pattern.MaxFileSize; status.MaxTimePeriod = Pattern.MaxTimePeriod; if (g_SystemInit == false && Pattern.Cachable != 0) { g_SystemInit = g_LogThread.StartThread(); } if (Level >= LOG_LEVEL_ERROR) { const char *pFileName = pLog->GetErrLogFilePath(); if (pFileName) { bool ret = g_Filemanager.PrepLogFile(status, pFileName); //filename + Context + ContextLen if (ret) { ret &= g_Filemanager.SaveContextToFile(pFileName, pContext, ContextSize); } if (ret == false) { for (DWORD i = 0; i < 10; i++) { printf("ERROR:----can't save error information\n"); printf("ERROR:%s\n", pContext); } } } } else { g_BlockMap.WriteLogFile(pLog->GetLogFileId(), status, pContext, (DWORD)ContextSize); if (Pattern.Cachable == 0) { g_LogThread.DoSaveProcedure(); } } //g_Filemanager.SaveLogFile(Pattern, pFileName, pContext, ContextSize); } LOGGER_C_API void __G_DebugPrintA( int Level, const char* file, int line, const char* function, const char* fmt, ...) { Logger *plog = GetGlobalLogger(); Logger_Pattern Pattern; if (plog == NULL) { return; } if (plog->GetLogFileId() == 0) { return; } plog->Thread_Lock(); (*plog).GetLogPattern(Pattern); if (Pattern.m_Level == LOG_LEVEL_INIT) { UpdateLogger((*plog)); (*plog).GetLogPattern(Pattern); } if ((Pattern.m_Level > LOG_LEVEL_INIT) && (Pattern.m_Level <= Level)) { //good to go if ((*plog).IsLogFilePathExist()) { //the whole pattern like below line /* //full log line [ date ] [ time ] [LEVEL] [ PID ][ TID ] [ FileName Line Func ] [2016:11:07] [14:03:35:0231] [DEBUG] [PID:0023][TID:00137] [FileName (Line) (Function)] : context........... //minimum log line [14:03:35:0231] [DEBUG]: context...... */ //head format BuffNode *pNode = g_BuffManager.GetBuff(); if (pNode) { size_t Idx = GetHeadFormat((LOG_LEVEL)Level, file, line, function, Pattern, pNode); if (NULL != fmt && Idx < PAGE - 1) { va_list marker = NULL; va_start(marker, fmt); //size_t nLength = _vscprintf(fmt, marker) + 1; int copiedcount = vsnprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, fmt, marker); if (copiedcount > 0) { Idx += copiedcount; } else { Idx = PAGE - 1; } //save to the file ,Len = Idx,buff = pNode,FileName = pFilepath SaveTheLog(Pattern, plog, &(pNode->m_Buff[0]), Idx, Level); va_end(marker); } g_BuffManager.ReleaseBuff(pNode); } } } plog->Thread_UnLock(); } LOGGER_C_API void __T_DebugPrintA( int Level, const char* file, int line, const char* function, const char* fmt, ...) { Logger *plog = GetThreadLogger(); Logger_Pattern Pattern; if (plog == NULL) { return; } if (plog->GetLogFileId() == 0) { return; } plog->Thread_Lock(); (*plog).GetLogPattern(Pattern); if (Pattern.m_Level == LOG_LEVEL_INIT) { UpdateLogger((*plog)); (*plog).GetLogPattern(Pattern); } if ((Pattern.m_Level > LOG_LEVEL_INIT) && (Pattern.m_Level <= Level)) { //good to go if ((*plog).IsLogFilePathExist()) { //the whole pattern like below line /* //full log line [ date ] [ time ] [LEVEL] [ PID ][ TID ] [ FileName Line Func ] [2016:11:07] [14:03:35:0231] [DEBUG] [PID:0023][TID:00137] [FileName (Line) (Function)] : context........... //minimum log line [14:03:35:0231] [DEBUG]: context...... */ //head format BuffNode *pNode = g_BuffManager.GetBuff(); if (pNode) { size_t Idx = GetHeadFormat((LOG_LEVEL)Level, file, line, function, Pattern, pNode); if (NULL != fmt && Idx < PAGE - 1) { va_list marker = NULL; va_start(marker, fmt); //size_t nLength = _vscprintf(fmt, marker) + 1; int copiedcount = vsnprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, fmt, marker); if (copiedcount > 0) { Idx += copiedcount; } else { Idx = PAGE - 1; } //save to the file ,Len = Idx,buff = pNode,FileName = pFilepath SaveTheLog(Pattern, plog, &(pNode->m_Buff[0]), Idx, Level); va_end(marker); } g_BuffManager.ReleaseBuff(pNode); } } } plog->Thread_UnLock(); } LOGGER_C_API void PrintA_IOLOG(Logger*& plog, int Level, const char* pszContext, size_t ContextSize) { Logger_Pattern Pattern; if (plog == NULL) { return; } if (plog->GetLogFileId() == 0) { return; } plog->Thread_Lock(); (*plog).GetLogPattern(Pattern); if (Pattern.m_Level == LOG_LEVEL_INIT) { UpdateLogger((*plog)); (*plog).GetLogPattern(Pattern); } if ((Pattern.m_Level > LOG_LEVEL_INIT) && (Pattern.m_Level <= Level)) { //good to go if ((*plog).IsLogFilePathExist()) { //Context is made by io level.just save SaveTheLog(Pattern, plog, pszContext, ContextSize, Level); } } plog->Thread_UnLock(); } static string CurrentDateTime() { std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); char buf[100] = { 0 }; std::strftime(buf, sizeof(buf), " %Y-%m-%d %H:%M:%S ", std::localtime(&now)); return buf; } LOGGER_C_API void __DebugPrintA(Logger* &plog, int Level, const char* file, int line, const char* function, const char* fmt, ...) { Logger_Pattern Pattern; if (plog == NULL) { char szMsg[512]; va_list marker = NULL; va_start(marker, fmt); //size_t nLength = _vscprintf(fmt, marker) + 1; int copiedcount = vsnprintf_s(szMsg, sizeof(szMsg), sizeof(szMsg)-1, fmt, marker); if (copiedcount > 0) { //printf("++++!!!! TID [%d] [%s] fuc : [%s] %s \n",GetCurrentThreadId(), CurrentDateTime().c_str(), function, szMsg); } va_end(marker); return; } if (plog->GetLogFileId() == 0) { return; } plog->Thread_Lock(); (*plog).GetLogPattern(Pattern); if (Pattern.m_Level == LOG_LEVEL_INIT) { UpdateLogger((*plog)); (*plog).GetLogPattern(Pattern); } if ((Pattern.m_Level > LOG_LEVEL_INIT) && (Pattern.m_Level <= Level)) { //good to go if ((*plog).IsLogFilePathExist()) { //the whole pattern like below line /* //full log line [ date ] [ time ] [LEVEL] [ PID ][ TID ] [ FileName Line Func ] [2016:11:07] [14:03:35:0231] [DEBUG] [PID:0023][TID:00137] [FileName (Line) (Function)] : context........... //minimum log line [14:03:35:0231] [DEBUG]: context...... */ //head format BuffNode *pNode = g_BuffManager.GetBuff(); if (pNode) { size_t Idx = GetHeadFormat((LOG_LEVEL)Level, file, line, function, Pattern, pNode); if (NULL != fmt && Idx < PAGE - 1) { va_list marker = NULL; va_start(marker, fmt); //size_t nLength = _vscprintf(fmt, marker) + 1; int copiedcount = vsnprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, fmt, marker); if (copiedcount > 0) { Idx += copiedcount; } else { Idx = PAGE - 1; } //save to the file ,Len = Idx,buff = pNode,FileName = pFilepath SaveTheLog(Pattern, plog, &(pNode->m_Buff[0]), Idx, Level); va_end(marker); } g_BuffManager.ReleaseBuff(pNode); } } } plog->Thread_UnLock(); } LOGGER_C_API void __Res_DebugPrintA( Logger* &plog, ResDataObject &obj, int Level, const char* file, int line, const char* function, const char* fmt, ...) { Logger_Pattern Pattern; if (plog == NULL) { return; } if (plog->GetLogFileId() == 0) { return; } plog->Thread_Lock(); (*plog).GetLogPattern(Pattern); if (Pattern.m_Level == LOG_LEVEL_INIT) { UpdateLogger((*plog)); (*plog).GetLogPattern(Pattern); } if ((Pattern.m_Level > LOG_LEVEL_INIT) && (Pattern.m_Level <= Level)) { //good to go if ((*plog).IsLogFilePathExist()) { //the whole pattern like below line /* //full log line [ date ] [ time ] [LEVEL] [ PID ][ TID ] [ FileName Line Func ] [2016:11:07] [14:03:35:0231] [DEBUG] [PID:0023][TID:00137] [FileName (Line) (Function)] : context........... //minimum log line [14:03:35:0231] [DEBUG]: context...... */ //head format BuffNode *pNode = g_BuffManager.GetBuff(); if (pNode) { size_t Idx = GetHeadFormat((LOG_LEVEL)Level, file, line, function, Pattern, pNode); if (NULL != fmt && Idx < PAGE - 1) { va_list marker = NULL; va_start(marker, fmt); //size_t nLength = _vscprintf(fmt, marker) + 1; int copiedcount = vsnprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, fmt, marker); if (copiedcount > 0) { Idx += copiedcount; //add ResDataObject if (Idx < PAGE - 1) { copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "%s", obj.encode()); if (copiedcount > 0) { Idx += copiedcount; } else { Idx = PAGE - 1; } } } else { Idx = PAGE - 1; } //save to the file ,Len = Idx,buff = pNode,FileName = pFilepath SaveTheLog(Pattern, plog, &(pNode->m_Buff[0]), Idx, Level); va_end(marker); } g_BuffManager.ReleaseBuff(pNode); } } } plog->Thread_UnLock(); } LOGGER_C_API void __Res_T_DebugPrintA( ResDataObject &obj, int Level, const char* file, int line, const char* function, const char* fmt, ...) { Logger *plog = GetThreadLogger(); Logger_Pattern Pattern; if (plog == NULL) { return; } if (plog->GetLogFileId() == 0) { return; } plog->Thread_Lock(); (*plog).GetLogPattern(Pattern); if (Pattern.m_Level == LOG_LEVEL_INIT) { UpdateLogger((*plog)); (*plog).GetLogPattern(Pattern); } if ((Pattern.m_Level > LOG_LEVEL_INIT) && (Pattern.m_Level <= Level)) { //good to go if ((*plog).IsLogFilePathExist()) { //the whole pattern like below line /* //full log line [ date ] [ time ] [LEVEL] [ PID ][ TID ] [ FileName Line Func ] [2016:11:07] [14:03:35:0231] [DEBUG] [PID:0023][TID:00137] [FileName (Line) (Function)] : context........... //minimum log line [14:03:35:0231] [DEBUG]: context...... */ //head format BuffNode *pNode = g_BuffManager.GetBuff(); if (pNode) { size_t Idx = GetHeadFormat((LOG_LEVEL)Level, file, line, function, Pattern, pNode); if (NULL != fmt && Idx < PAGE - 1) { va_list marker = NULL; va_start(marker, fmt); //size_t nLength = _vscprintf(fmt, marker) + 1; int copiedcount = vsnprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, fmt, marker); if (copiedcount > 0) { Idx += copiedcount; //add ResDataObject if (Idx < PAGE - 1) { copiedcount = _snprintf_s(&(pNode->m_Buff[Idx]), pNode->m_Buff.size() - Idx, _TRUNCATE, "%s", obj.encode()); if (copiedcount > 0) { Idx += copiedcount; } else { Idx = PAGE - 1; } } } else { Idx = PAGE - 1; } //save to the file ,Len = Idx,buff = pNode,FileName = pFilepath SaveTheLog(Pattern, plog, &(pNode->m_Buff[0]), Idx, Level); va_end(marker); } g_BuffManager.ReleaseBuff(pNode); } } } plog->Thread_UnLock(); }