PV1_Comm/log/log.c

1119 lines
31 KiB
C

/** @file log.c
@brief 系统日志接口文件
@version 1.0.0
*/
#include <sys/time.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <uthash/utlist.h>
#include <uv.h>
#include <uthash/utstring.h>
#include <uthash/utringbuffer.h>
#include <linux/mii.h>
#include <linux/sockios.h>
#include <sys/ioctl.h>
#include <net/if.h>
#ifdef PLATFORM_R16
#include <cutils/cpu_info.h>
#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, "<html><body>\r\n"
"<p><span style=\"font-size:24px;\"><strong>Summary information</strong></span><span style=\"font-size:24px;\">:</span></p>"
"<p><br /></p>"
"<p><table style=\"width:35%%;\" cellpadding=\"2\" cellspacing=\"0\" border=\"1\" bordercolor=\"#000000\">"
"<tbody>"
"<tr><td><b>Items</b><br /></td><td>%u<br /></td></tr>"
"<tr><td><b>Process PID</b><br /></td><td>%d<br /></td></tr>"
"<tr><td><b>Process Name</b><br /></td><td>%s<br /></td></tr>"
"<tr><td><b>CPU ID</b><br /></td><td>%s<br /></td></tr>"
"<tr><td><b>Serial</b><br /></td><td>%s<br /></td></tr>"
"<tr><td><b>Mac Address</b><br /></td><td>%s<br /></td></tr>"
"<tr><td><b>File Checksum</b><br /></td><td>%s<br /></td></tr>"
"<tr><td><b>Log Level</b><br /></td><td>0x%08X<br /></td></tr>"
"<tr><td><b>Datetime</b><br /></td><td>%s<br /></td></tr>"
"</tbody>"
"</table>"
"</p>"
"</body></html>\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";
}