/** @file log.c @brief 系统日志接口文件 @version 1.0.0 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PLATFORM_R16 #include #endif #include "log.h" #include "smart_sound.h" #include "inet_api.h" #include "crypto.h" #include "libuv_dbus.h" #include "server_addr.h" #define SHOW_CONSOLE_RED ("\033[31;48m\033[1m%s\033[0m%c") #define SHOW_CONSOLE_YELLOW ("\033[33;48m\033[1m%s\033[0m%c") #define SHOW_CONSOLE_GREEN ("\033[32;48m\033[1m%s\033[0m%c") #define SHOW_CONSOLE_BLUE ("\033[34;48m\033[1m%s\033[0m%c") #ifdef PLATFORM_CPU #define LOG_FILE_BASEDIR (".") #else #define LOG_FILE_BASEDIR ("/tmp") #endif #ifdef PLATFORM_R16 #define NIC_NAME ("wlan0") #else #define NIC_NAME ("enp3s0") #endif #define MAX_LOG_ITEM (1000) #define MAX_LOG_FILE_SIZE (1024 * 1024) #define LOG_PRE_SIZE (512) #if 0 #define LOG_MAIL_USERNAME ("pv1_es2@hotmail.com") #define LOG_MAIL_PASSWORD ("netEase163") #define LOG_MAIL_SERVER ("smtp://smtp-mail.outlook.com") #define LOG_MAIL_PORT (587) #else #define LOG_MAIL_USERNAME ("pv1_es2@163.com") #define LOG_MAIL_LOGPASSWD ("netEase163") #define LOG_MAIL_PASSWORD ("pv1Dev163") #define LOG_MAIL_SERVER ("smtp.163.com") #define LOG_MAIL_PORT (25) #endif #define LOG_MAIL_RECEIVER ("pv1_es2@163.com") #define SYS_POINT_UPLOAD_TIME (600) typedef struct { char* pDeviceId; char savePath[MAX_PATH]; int iMaxCacheSize; int iEveryUploadTime; time_t lastPostTime; time_t lastMarkTime; FILE* pMarkFile; uv_rwlock_t uvRwLock; uv_thread_t uvIOThread; } SYSPOINT_INFO, *PSYSPOINT_INFO; typedef struct SYSPOINT_ITEM { char* pContent; struct SYSPOINT_ITEM *next, *prev; } *PSYSPOINT_ITEM; typedef struct LOG_ITEM { LOG_LEVEL level; int isPrinted; int isAddTags; struct timeval timestamp; char *pLogContent; struct LOG_ITEM *next, *prev; }*PLOG_ITEM; typedef struct LOG_BACKUP { time_t timestamp; char *plogFilePath; char *pGzFilePath; unsigned int sendTimes; unsigned int tolLogs; struct LOG_BACKUP *next, *prev; } *PLOG_BACKUP; typedef struct { pid_t pid; char* pChipId; char* pChipSerial; char exeName[MAX_PATH]; char logFilePath[MAX_PATH]; FILE *pLogFile; } LOG_PROCESS_INFO, *PLOG_PROCESS_INFO; static int g_bEnableLog = FALSE; // 是否启用 Log 功能 static int g_bEnMailBackup = FALSE; static char* g_pEmailBox = NULL; static int g_bEnLogToFile = TRUE; static int g_bEnLogToServer = TRUE; static char g_strLogTag[32]; // Log 标志 static unsigned int g_LogRdPos = 0; static pthread_t g_logThreadId; static pthread_t g_backupThreadId; static LOG_PROCESS_INFO g_LogProcessInfo; static uv_rwlock_t g_uvLogLock; static uv_rwlock_t g_uvLogBackLock; static PLOG_ITEM g_pLogItemList = NULL; static PLOG_BACKUP g_pLogBackupList = NULL; static int g_logSock = -1; struct sockaddr_in g_logAddr; static SYSPOINT_INFO g_SysPonitInfo; static PSYSPOINT_ITEM g_pSysPointArray = NULL; static PHTTP_POST_ATTACH g_pLogParamsArray = NULL; static int g_iMinLevel = LOG_Fatal | LOG_Error | LOG_Warn | LOG_Debug | LOG_Info | LOG_Step; /** * @brief Log 调试等级转字符串 * @param level 调试等级 * @return 调试等级对应的字符串 */ const char* LogLevelToStr(LOG_LEVEL level) { switch(level) { case LOG_Test: return "T"; case LOG_Info: return "I"; case LOG_Call: return "C"; case LOG_Debug: return "D"; case LOG_Warn: return "W"; case LOG_Error: return "E"; case LOG_Fatal: return "F"; case LOG_Step: return "S"; case LOG_Devp: return "V"; case LOG_Unknown: return "U"; case LOG_All: return "A"; default: return "?"; } return "U"; } #pragma pack (push) #pragma pack (1) typedef struct { unsigned short logSeq; unsigned int pid; unsigned int timeStamp; unsigned int nanotime; unsigned int logLevel; char logContent[0]; } LOG_PROTO_CONTENT, *PLOG_PROTO_CONTENT; #pragma pack (pop) static struct HTTP_POST_ATTACH g_PostLogParams[] = { {"CPUID", "", NULL, NULL}, {"MAC", "", NULL, NULL}, {"Version", "", NULL, NULL}, {"BuildTime", "", NULL, NULL}, {"SerialNumber", "", NULL, NULL}, {"Datetime", "", NULL, NULL}, {"content", "", NULL, NULL}, }; static void __initPostLogParams(void) { char *pMacAddr = NULL; struct tm localTime; time_t timeStamp = time((time_t*)NULL); GetShellExecResult("ifconfig wlan0 | grep HWaddr | awk \'{print $5}\'", &pMacAddr); localtime_r(&timeStamp, &localTime); strncpy(g_PostLogParams[0].keyValue, g_LogProcessInfo.pChipId, MAX_HTTP_POST_SIZE); strncpy(g_PostLogParams[1].keyValue, (pMacAddr && strlen(pMacAddr) > 0) ? pMacAddr : "00:00:00:00:00:00", MAX_HTTP_POST_SIZE); strncpy(g_PostLogParams[2].keyValue, GetCurrentVersion(), MAX_HTTP_POST_SIZE); sprintf(g_PostLogParams[3].keyValue, "Build: %s %s", __DATE__, __TIME__); strncpy(g_PostLogParams[4].keyValue, g_LogProcessInfo.pChipSerial, MAX_HTTP_POST_SIZE); for(int i = 0; i < sizeof(g_PostLogParams) / sizeof(g_PostLogParams[0]); i++) { LL_APPEND(g_pLogParamsArray, &g_PostLogParams[i]); } if(pMacAddr) { free(pMacAddr); } } int HttpPostLogFile(char* pSession) { int ret; struct tm localTime; const char* pFileName = "/tmp/backuplog.tar.gz"; const char* pLastFile = "/mnt/UDISK/backuplog_nand.tar.gz"; char* pLogServerURL = GetCurServerAddr(LOG_MODULE); time_t timeStamp = time((time_t*)NULL); ret = system(" /usr/sbin/backuplocalfiles.sh"); if(access(pFileName, F_OK) != 0 && access(pLastFile, F_OK) != 0) { return -ERR_FILE_NOT_EXISTS; } localtime_r(&timeStamp, &localTime); memset(g_PostLogParams[5].keyValue, 0, MAX_HTTP_POST_SIZE); sprintf(g_PostLogParams[5].keyValue, "%04u-%02u-%02u %02u:%02u:%02u", localTime.tm_year + 1900, localTime.tm_mon + 1, localTime.tm_mday, localTime.tm_hour, localTime.tm_min, localTime.tm_sec); memset(g_PostLogParams[6].keyValue, 0, MAX_HTTP_POST_SIZE); if(pSession && strlen(pSession) >= 2) { strncpy(g_PostLogParams[6].keyValue, pSession, MAX_HTTP_POST_SIZE); } else { strncpy(g_PostLogParams[6].keyValue, "{}", MAX_HTTP_POST_SIZE); } if(access(pFileName, F_OK) == 0) { ret = InetHttpUploadFileSync(pLogServerURL, pFileName, g_pLogParamsArray); if(ret == 0) { LOG_EX(LOG_Debug, "Upload Log Data [%s] To Server [%s]\n", pFileName, pLogServerURL); unlink(pFileName); } else { LOG_EX(LOG_Error, "Upload Log Data [%s] To Server [%s]\n", pFileName, pLogServerURL); } } if(access(pLastFile, F_OK) == 0) { ret = InetHttpUploadFileSync(pLogServerURL, pLastFile, g_pLogParamsArray); if(ret == 0) { LOG_EX(LOG_Debug, "Upload Log Data [%s] To Server [%s]\n", pLastFile, pLogServerURL); unlink(pLastFile); } else { LOG_EX(LOG_Error, "Upload Log Data [%s] To Server [%s]\n", pLastFile, pLogServerURL); } } //fprintf(stdout, "Upload Log Data [%s] To Server [%s], size = %d\n", pFileName, UPL_HTTP_URL, fileSize); return ret; } static int __logNetworkSend(PLOG_ITEM pItem) { PLOG_PROTO_CONTENT pLogInfo; unsigned char *pBuf; int ret, totalSize = 0; static unsigned short sendSeq = 0; if(pItem == NULL || pItem->pLogContent == NULL || strlen(pItem->pLogContent) == 0) { return (-ERR_INPUT_PARAMS); } totalSize = sizeof(LOG_PROTO_CONTENT) + strlen(pItem->pLogContent); pBuf = (unsigned char *)malloc(totalSize); if(pBuf == NULL) { return (-ERR_MALLOC_MEMORY); } memset(pBuf, 0, totalSize); pLogInfo = (PLOG_PROTO_CONTENT)pBuf; pLogInfo->logSeq = htons(sendSeq++); pLogInfo->timeStamp = htonl(pItem->timestamp.tv_sec); pLogInfo->nanotime = htonl(pItem->timestamp.tv_usec); pLogInfo->pid = htonl(g_LogProcessInfo.pid); pLogInfo->logLevel = htonl(pItem->level); memcpy(pLogInfo->logContent, pItem->pLogContent, strlen(pItem->pLogContent)); ret = sendto(g_logSock, pBuf, totalSize, 0, (struct sockaddr *)&g_logAddr, sizeof(g_logAddr)); if(ret == totalSize) { return (0); } else { //LOG_EX(LOG_Error, "Send %d bytes, need %d bytes\n", ret, totalSize); return (-ERR_NETWORK_SEND); } } static void __cleanupBackupItem(PLOG_BACKUP pItem) { if(pItem) { LL_DELETE(g_pLogBackupList, pItem); if(pItem->plogFilePath) { if(access(pItem->plogFilePath, F_OK) == 0) { unlink(pItem->plogFilePath); } free(pItem->plogFilePath); } if(pItem->pGzFilePath) { if(access(pItem->pGzFilePath, F_OK) == 0) { unlink(pItem->pGzFilePath); } free(pItem->pGzFilePath); } free(pItem); } } static void* __uvLogBackupProc(void *pParams) { SMTP_MAIL_CONFIG smtpCfg; char gzLogPath[MAX_PATH]; struct tm localTime; const char *pFrom = LOG_MAIL_USERNAME; const char *pTo[] = {g_pEmailBox, NULL}; char *pMacAddr = NULL; //const char *pCc[] = {"xajhuang@qq.com", "xajhuang@163.com", NULL}; memset(&smtpCfg, 0, sizeof(SMTP_MAIL_CONFIG)); smtpCfg.pUserName = LOG_MAIL_USERNAME; smtpCfg.pPassword = LOG_MAIL_PASSWORD; smtpCfg.pSmtpServer = LOG_MAIL_SERVER; smtpCfg.smtpPort = LOG_MAIL_PORT; #ifdef PLATFORM_CPU GetShellExecResult("ifconfig enp3s0 | grep HWaddr | awk \'{print $5}\'", &pMacAddr); #else GetShellExecResult("ifconfig wlan0 | grep HWaddr | awk \'{print $5}\'", &pMacAddr); #endif if(pMacAddr == NULL || strlen(pMacAddr) == 0) { pMacAddr = strdup("00:00:00:00:00:00"); } while(TRUE) { PLOG_BACKUP pItem = NULL, pTmp = NULL; time_t timeStamp = time((time_t*)NULL); localtime_r(&timeStamp, &localTime); uv_rwlock_wrlock(&g_uvLogBackLock); LL_FOREACH_SAFE(g_pLogBackupList, pItem, pTmp) { const char *pAttact[2]; UT_string *pTitle, *pMessage, *pDatetime; char* pMD5Val; pAttact[1] = NULL; if(pItem->plogFilePath == NULL || strlen(pItem->plogFilePath) == 0) { __cleanupBackupItem(pItem); continue; } if(timeStamp - pItem->timestamp >= 3600) { __cleanupBackupItem(pItem); continue; } if(pItem->sendTimes >= 3) { __cleanupBackupItem(pItem); continue; } #if 0 if(g_bEnLogToServer) { __logHttpPostFile(pItem->plogFilePath); //InetHttpUploadFileSync(UPL_HTTP_URL, pItem->pGzFilePath, NULL); } #endif if(pItem->pGzFilePath == NULL) { memset(gzLogPath, 0, MAX_PATH); sprintf(gzLogPath, "%s/%d_%s_%u.log.gz", LOG_FILE_BASEDIR, g_LogProcessInfo.pid, g_LogProcessInfo.exeName, pItem->tolLogs); if(GZipFileCompress(pItem->plogFilePath, gzLogPath) != 0) { LOG_EX(LOG_Error, "Create Gzip File Error: %s\n", gzLogPath); continue; } else { pItem->pGzFilePath = strdup(gzLogPath); } } pMD5Val = (char*)EvpMD5HashFile(pItem->pGzFilePath); utstring_new(pTitle); utstring_new(pMessage); utstring_new(pDatetime); utstring_printf(pDatetime, "%04u-%02u-%02u %02u:%02u:%02u", localTime.tm_year + 1900, localTime.tm_mon + 1, localTime.tm_mday, localTime.tm_hour, localTime.tm_min, localTime.tm_sec); utstring_printf(pTitle, "Log [%s]-[%s]-[%s]", g_LogProcessInfo.exeName, g_LogProcessInfo.pChipSerial, utstring_body(pDatetime)); utstring_printf(pMessage, "\r\n" "

Summary information:

" "


" "

" "" "" "" "" "" "" "" "" "" "" "" "
Items
%u
Process PID
%d
Process Name
%s
CPU ID
%s
Serial
%s
Mac Address
%s
File Checksum
%s
Log Level
0x%08X
Datetime
%s
" "

" "\r\n", pItem->tolLogs, g_LogProcessInfo.pid, g_LogProcessInfo.exeName, g_LogProcessInfo.pChipId, g_LogProcessInfo.pChipSerial, pMacAddr, SAFE_STRING_VALUE(pMD5Val), g_iMinLevel, utstring_body(pDatetime)); pAttact[0] = pItem->pGzFilePath; #if 0 if(g_bEnMailBackup && InetSmtpSendEmail(pFrom, pTo, NULL, utstring_body(pTitle), utstring_body(pMessage), pAttact, &smtpCfg) == 0) { __cleanupBackupItem(pItem); } else { LOG_EX(LOG_Error, "Send email error: %s\n", pItem->pGzFilePath); } #endif pItem->sendTimes++; if(pMD5Val) { free(pMD5Val); } utstring_free(pTitle); utstring_free(pMessage); utstring_free(pDatetime); } uv_rwlock_wrunlock(&g_uvLogBackLock); sleep(1); } free(pMacAddr); pthread_detach(pthread_self()); return (NULL); } static void __logColorOutput(const char* pColFmt, UT_string* pLog) { if(pLog == NULL) { return; } if(pColFmt == NULL) { print("%s", utstring_body(pLog)); } else { if(utstring_find(pLog, -1, "\n", 1) == utstring_len(pLog) - 1) { char* pLogArray = utstring_body(pLog); pLogArray[utstring_len(pLog) - 1] = 0; print(pColFmt, pLogArray, '\n'); strcat(pLogArray, "\n"); } else { print(pColFmt, utstring_body(pLog), '\0'); } } } static void* __logOutputThread(void *p) { while(TRUE) { int isWriteLog = FALSE; PLOG_ITEM pItem = NULL, pTmp = NULL; uv_rwlock_wrlock(&g_uvLogLock); LL_FOREACH_SAFE(g_pLogItemList, pItem, pTmp) { UT_string *pLogStr; struct tm lTime; int logFileSize = 0; if(++g_LogRdPos % 100 == 0) { GET_FILE_SIZE(g_LogProcessInfo.logFilePath, logFileSize); } localtime_r(&(pItem->timestamp.tv_sec), &lTime); utstring_new(pLogStr); if(pItem->isAddTags) { utstring_printf(pLogStr, "[%04d-%02d-%02d %02d:%02d:%02d.%03ld] [%s] %s", lTime.tm_year + 1900, lTime.tm_mon + 1, lTime.tm_mday, lTime.tm_hour, lTime.tm_min, lTime.tm_sec, pItem->timestamp.tv_usec / 1000, LogLevelToStr(pItem->level), pItem->pLogContent); } else { utstring_printf(pLogStr, "%s", pItem->pLogContent); } if(pItem->isPrinted == FALSE) { if(pItem->level & LOG_Error || pItem->level & LOG_Fatal) { __logColorOutput(SHOW_CONSOLE_RED, pLogStr); } else if(pItem->level & LOG_Warn || pItem->level & LOG_Unknown) { __logColorOutput(SHOW_CONSOLE_YELLOW, pLogStr); } else if(pItem->level & LOG_Test || pItem->level & LOG_Call) { __logColorOutput(SHOW_CONSOLE_BLUE, pLogStr); } else if(pItem->level & LOG_Devp) { __logColorOutput(SHOW_CONSOLE_GREEN, pLogStr); } else { print("%s", utstring_body(pLogStr)); } pItem->isPrinted = TRUE; } if(g_logSock != -1 && GetCurrWIFIConnStatus() == WIFI_CONNECTED) { __logNetworkSend(pItem); } if(g_LogProcessInfo.pLogFile != NULL && g_bEnLogToFile) { if(logFileSize >= MAX_LOG_FILE_SIZE) { fflush(g_LogProcessInfo.pLogFile); fclose(g_LogProcessInfo.pLogFile); #if 0 if(g_bEnMailBackup) { PLOG_BACKUP pBackup = (PLOG_BACKUP)malloc(sizeof(struct LOG_BACKUP)); char path[MAX_PATH]; memset(path, 0, MAX_PATH); sprintf(path, "%s/%s.bak_%u.log", LOG_FILE_BASEDIR, basename_v2(g_LogProcessInfo.logFilePath), g_LogRdPos); rename(g_LogProcessInfo.logFilePath, path); if(pBackup) { memset(pBackup, 0, sizeof(struct LOG_BACKUP)); pBackup->timestamp = time(NULL); pBackup->plogFilePath = strdup(path); pBackup->sendTimes = 0; pBackup->tolLogs = g_LogRdPos - 1; uv_rwlock_wrlock(&g_uvLogBackLock); LL_APPEND(g_pLogBackupList, pBackup); uv_rwlock_wrunlock(&g_uvLogBackLock); } } #endif g_LogProcessInfo.pLogFile = fopen(g_LogProcessInfo.logFilePath, "w+"); } if(g_LogProcessInfo.pLogFile) { fwrite(utstring_body(pLogStr), 1, utstring_len(pLogStr), g_LogProcessInfo.pLogFile); } isWriteLog = TRUE; } LL_DELETE(g_pLogItemList, pItem); utstring_free(pLogStr); free(pItem->pLogContent); free(pItem); if(g_LogRdPos % 100 == 0) { break; } } uv_rwlock_wrunlock(&g_uvLogLock); usleep(1000); if(g_LogProcessInfo.pLogFile != NULL && isWriteLog) { fflush(g_LogProcessInfo.pLogFile); } } pthread_detach(pthread_self()); return (NULL); } /** * @brief 设置调试等级 * @param level 调试等级 * @param iEnable 1 打开调试等级, 0 关闭调试等级 */ void IHW_EnableLogLevel(LOG_LEVEL level, int iEnable) { if(iEnable > 0) { g_iMinLevel |= level; } else { g_iMinLevel &= ~(level); } } static int __getCfgFromCfgFile(void) { int ret = 0; g_bEnableLog = CfgGetBoolValue("Global.Log.Enable", g_bEnableLog); g_iMinLevel = CfgGetIntValue("Global.Log.Level", g_iMinLevel); g_bEnMailBackup = CfgGetBoolValue("Global.Log.LogToEMail.Enable", g_bEnMailBackup); g_pEmailBox = CfgGetStringValue("Global.Log.LogToEMail.EMail", LOG_MAIL_RECEIVER); g_bEnLogToFile = CfgGetBoolValue("Global.Log.LogToFile", g_bEnLogToFile); g_bEnLogToServer = CfgGetBoolValue("Global.Log.LogToServer", g_bEnLogToServer); #if 0 LOG_EX(LOG_Debug, "g_bEnableLog = %d\n", g_bEnableLog); LOG_EX(LOG_Debug, "g_iMinLevel = 0x%X\n", g_iMinLevel); LOG_EX(LOG_Debug, "g_bEnMailBackup = %d\n", g_bEnMailBackup); LOG_EX(LOG_Debug, "g_pEmailBox = %s\n", g_pEmailBox); LOG_EX(LOG_Debug, "g_bEnLogToFile = %d\n", g_bEnLogToFile); LOG_EX(LOG_Debug, "g_bEnLogToServer = %d\n", g_bEnLogToServer); #endif ret = CfgGetBoolValue("Global.Log.LogToUDPServer.Enable", FALSE); if(ret) { char *pIpAddr = NULL; int udpPortBase = CfgGetBoolValue("Global.Log.LogToUDPServer.UdpBasePort", 10000); int port = udpPortBase + DBusLibGetModName(); if(g_logSock != -1) { close(g_logSock); g_logSock = -1; } pIpAddr = CfgGetStringValue("Global.Log.LogToUDPServer.UdpServerIp", NULL); LOG_EX(LOG_Debug, "UDP Ipaddr = %s, port = %d\n", pIpAddr, port); if(pIpAddr) { memset(&g_logAddr, 0, sizeof(g_logAddr)); g_logAddr.sin_family = AF_INET; g_logAddr.sin_port = htons(port); g_logAddr.sin_addr.s_addr = inet_addr(pIpAddr); g_logSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); } } } /** * @brief 初始化系统日志功能 * @param pLogTag 系统日志标志 * @param pPath 系统日志保存路径 * @param bEnable 打开/关闭调试信息 */ void IHW_InitLOG(const char* pLogTag, const char* pPath, int bEnable) { int ret; char strPath[MAX_PATH]; memset(&g_logAddr, 0, sizeof(g_logAddr)); uv_rwlock_init(&g_uvLogLock); g_LogRdPos = 0; memset(g_strLogTag, 0, 32); memset(&g_LogProcessInfo, 0, sizeof(LOG_PROCESS_INFO)); if(pLogTag == NULL) { strcpy(g_strLogTag, ""); } else { strncpy(g_strLogTag, pLogTag, 31); } memset(strPath, 0, MAX_PATH); g_LogProcessInfo.pid = getpid(); if(readlink("/proc/self/exe", strPath, MAX_PATH) == -1) { strcpy(g_LogProcessInfo.exeName, pLogTag); } else { char *pExeName = strrchr(strPath, '/'); if(pExeName == NULL) { strncpy(g_LogProcessInfo.exeName, strPath, MAX_PATH - 1); } else { strncpy(g_LogProcessInfo.exeName, pExeName + 1, MAX_PATH - 1); } } //fprintf(stdout, "pid = %d, name = %s\n", g_LogProcessInfo.pid, g_LogProcessInfo.exeName); g_LogProcessInfo.pChipId = GetCpuChipId(); g_LogProcessInfo.pChipSerial = GetCpuSerial(); memset(g_LogProcessInfo.logFilePath, 0, MAX_PATH); sprintf(g_LogProcessInfo.logFilePath, "%s/%s_%d.log", LOG_FILE_BASEDIR, g_LogProcessInfo.exeName, g_LogProcessInfo.pid); memset(strPath, 0, MAX_PATH); sprintf(strPath, "rm -f %s/%s_*.log > /dev/zero", LOG_FILE_BASEDIR, g_LogProcessInfo.exeName); ret = system(strPath); g_LogProcessInfo.pLogFile = fopen(g_LogProcessInfo.logFilePath, "w+"); g_bEnableLog = bEnable; __getCfgFromCfgFile(); #if 0 LOG_CFG_PROTOCOL logCfg; memset(&logCfg, 0, sizeof(LOG_CFG_PROTOCOL)); logCfg.cfgCmd = CMD_LOG_NETWORK; logCfg.iParams1 = inet_addr("10.240.84.163"); logCfg.iParams2 = htons(10000); UpgradLogConfigure(&logCfg); #endif __initPostLogParams(); } void IHW_RunLogService(void) { pthread_create(&g_logThreadId, NULL, __logOutputThread, NULL); pthread_create(&g_backupThreadId, NULL, __uvLogBackupProc, NULL); } static void __logTo(LOG_LEVEL level, int isAddTag, char* pMsg, int isPrint) { PLOG_ITEM pLogItem; pLogItem = (PLOG_ITEM)malloc(sizeof(struct LOG_ITEM)); if(pLogItem == NULL) { return; } pLogItem->pLogContent = strdup(pMsg); pLogItem->isPrinted = isPrint ? FALSE : TRUE; pLogItem->level = level; pLogItem->isAddTags = isAddTag ? TRUE : FALSE; gettimeofday(&(pLogItem->timestamp), NULL); uv_rwlock_wrlock(&g_uvLogLock); LL_APPEND(g_pLogItemList, pLogItem); uv_rwlock_wrunlock(&g_uvLogLock); } void IHW_LogStrWithoutPrint(int level, char* pMsg) { __logTo(level, TRUE, pMsg, FALSE); } void IHW_LogRawString(int level, char* pMsg) { __logTo(level, TRUE, pMsg, TRUE); } /** * @brief 输出调试信息 * @param cFlag 调试信息开关 * @param pMsg 调试信息内容 */ void IHW_LOG_UNTAG(LOG_LEVEL level, const char* pMsg, ...) { va_list arg_ptr; UT_string *pLogContent; if(!g_bEnableLog) { return; } // 检查调试等级 if(!(g_iMinLevel & level)) { return; } utstring_new(pLogContent); va_start(arg_ptr, pMsg); utstring_printf_va(pLogContent, pMsg, arg_ptr); va_end(arg_ptr); __logTo(level, FALSE, utstring_body(pLogContent), TRUE); utstring_free(pLogContent); } /** * @brief 输出调试信息 * @param cFlag 调试信息开关 * @param pMsg 调试信息内容 */ void IHW_LOG(LOG_LEVEL level, const char* pMsg, ...) { UT_string* pLogContent = NULL; va_list arg_ptr; if(!g_bEnableLog) { return; } // 检查调试等级 if(!(g_iMinLevel & level)) { return; } utstring_new(pLogContent); va_start(arg_ptr, pMsg); utstring_printf_va(pLogContent, pMsg, arg_ptr); va_end(arg_ptr); __logTo(level, TRUE, utstring_body(pLogContent), TRUE); utstring_free(pLogContent); } void IHW_DisableLogOut(void) { g_bEnableLog = FALSE; } void IHW_EnableLogOut(void) { g_bEnableLog = TRUE; } #if 0 void LogUploadCurLogFile(void) { UT_string *pFn = NULL, *pCmd = NULL; utstring_new(pFn); utstring_new(pCmd); utstring_printf(pFn, "/tmp/%s_%s.bak.log", g_LogProcessInfo.exeName, g_LogProcessInfo.pChipId); utstring_printf(pCmd, "cp %s %s", g_LogProcessInfo.logFilePath, utstring_body(pFn)); __logHttpPostFile(utstring_body(pFn)); //InetHttpUploadFileSync(UPL_HTTP_URL, utstring_body(pFn), NULL); utstring_free(pFn); utstring_free(pCmd); } #endif #if 0 void UploadLogFile(char* pFilePath) { int fileSize = 0; if(pFilePath == NULL || strlen(pFilePath) == 0) { return; } GET_FILE_SIZE(pFilePath, fileSize); if(fileSize <= 0) { LOG_EX(LOG_Warn, "File Size Error: %d\n", fileSize); return; } __logHttpPostFile(pFilePath); } #endif void UpgradLogConfigure(PLOG_CFG_PROTOCOL pCfg) { switch(pCfg->cfgCmd) { case CMD_LOG_ENABLE: g_bEnableLog = pCfg->iParams1; break; case CMD_LOG_FILE: if(pCfg->iParams1 == FALSE) { g_bEnMailBackup = g_bEnLogToFile = FALSE; } else { g_bEnLogToFile = TRUE; } break; case CMD_LOG_MAIL: g_bEnMailBackup = pCfg->iParams1; break; case CMD_LOG_LEVEL: if(pCfg->iParams2 == FALSE) { if(pCfg->iParams1 == 0) { g_iMinLevel = LOG_Fatal | LOG_Error | LOG_Devp; } else { g_iMinLevel &= ~(pCfg->iParams1); } } else { g_iMinLevel |= pCfg->iParams1; } break; case CMD_LOG_NETWORK: if(pCfg->iParams1 == 0) { memset(&g_logAddr, 0, sizeof(g_logAddr)); close(g_logSock); g_logSock = -1; } else { if(g_logSock != -1) { close(g_logSock); } memset(&g_logAddr, 0, sizeof(g_logAddr)); g_logAddr.sin_family = AF_INET; g_logAddr.sin_port = htons((pCfg->iParams2 & 0xFFFF)); g_logAddr.sin_addr.s_addr = (pCfg->iParams1); g_logSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); } break; case CMD_LOG_SERVER: g_bEnLogToServer = pCfg->iParams1; break; default: break; } } const char* LogLeveToString(LOG_LEVEL lv) { switch(lv) { case LOG_Fatal: return "LOG_Fatal"; case LOG_Error: return "LOG_Error"; case LOG_Warn: return "LOG_Warn"; case LOG_Debug: return "LOG_Debug"; case LOG_Info: return "LOG_Info"; case LOG_Test: return "LOG_Test"; case LOG_Call: return "LOG_Call"; case LOG_Devp: return "LOG_Devp"; case LOG_Step: return "LOG_Step"; case LOG_Unknown: return "LOG_Unknown"; case LOG_All: return "LOG_All"; case LOG_Close: return "LOG_Close"; } return "Unknown"; }