You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iec104/src/HTLogger.cpp

292 lines
12 KiB
C++

/****************************************************************************
** File name : FLTLogger.cpp
** Description : logger function define
** Create date : 2018.09.01
** Auther by : Liuyx
** Version info : V1.0.01
** Copyright (C) 2002-2018 xi'an huatek, Inc Co., Ltd
** Update record:
** DATE AUTHER DESC
** -------------------------------------------------------------------------
** 2018.09.01 Liuyx first build
****************************************************************************
++++++++++ 关于64位整数的打印说明 ++++++++++
(1) windows os
printf("int_64 = %I64d\n", int64); -- 打印有符号64位整数
printf("int_64 = %I64u\n", int64); -- 打印无符号64位整数
(2) Linux os
printf("int_64 = %lld\n", int64); -- 打印有符号64位整数
printf("int_64 = %llu\n", int64); -- 打印无符号64位整数
****************************************************************************/
//#include "StdAfx.h"
#include "HTGlobal.h"
#include "HTPublic.h"
#include "HTLogger.h"
static const char *_FILE_="HTLogger.cpp";
static char g_logger_time[15] ; // 日志文件名称时间(YYYYMMDD)
#ifdef _WIN32
static const char *DEF_LOG_PATH_NAME = "..\\log"; //日志文件目录名
static const char *DEF_RUN_INFO_PATH = "..\\run"; // 服务运行状态日志目录
#else
const char *DEF_LOG_PATH_NAME = "../log"; //日志文件目录名
const char *DEF_RUN_INFO_PATH = "../run"; // 服务运行状态日志目录
#endif
/* mutex define */
static mutex mutex_Debug ; //跟踪日志
static FILE *g_fp;
/****************************************************************
** Description : 初始化日志文件句柄锁
** param in : None
** :
** param out : None
** return code : None
****************************************************************/
void vInitLogMutex(void)
{
char szFile[DEF_BUFFER_256];
mutex_create(mutex_Debug);
// 创建日志文件并打开文件
memset(szFile, 0x00, sizeof(szFile)) ;
memset(g_logger_time, 0x00, sizeof(g_logger_time)); // 记录当前日志文件的时间(YYYYMMDD)
vGetHostTime(g_logger_time) ;
#ifdef _WIN32
sprintf(szFile,"%s\\debug%.8s.log", DEF_LOG_PATH_NAME,g_logger_time) ;
#else
sprintf(szFile,"%s/debug%.8s.log",DEF_LOG_PATH_NAME, g_logger_time) ;
#endif
if(iDirOrFileExist(DEF_LOG_PATH_NAME) != 0) {
//文件或目录不存在时, 创建文件或目录
if(iBuildDirent(DEF_LOG_PATH_NAME) != 0) {
printf("line:%d file:%s Create Directory:[%s] failed.\n",__LINE__,_FILE_, DEF_LOG_PATH_NAME);
return;
}
}
g_fp = fopen((const char*)szFile, (const char*)"a+");
if(NULL == g_fp) {
printf("line:%d file:%s Can't open file:[%s] failed.\n",__LINE__,_FILE_, szFile);
return;
}
if(iDirOrFileExist(DEF_RUN_INFO_PATH) != 0) {
//文件或目录不存在时, 创建文件或目录
if((iBuildDirent(DEF_RUN_INFO_PATH)) != 0) {
vPrtLogMsg(LOG_ERROR, errno, "Create Directory:[%s] failed,%s.", DEF_RUN_INFO_PATH,strerror(errno));
return;
}
}
}
/****************************************************************
** Description : 释放日志文件句柄锁
** param in : None
** :
** param out : None
** return code : None
****************************************************************/
void vFreeLogMutex(void)
{
mutex_close(mutex_Debug);
if(g_fp) fclose(g_fp);
}
/**********************************************************************
** Description : 打印错误日志
** param in : iLine -- 行号
** : *szFileName -- 文件名
** : *szErrMsg -- 错误信息
** : iCode -- 报文代码 或 错误码
** param out : None
** return code :
** : None
** : None
**********************************************************************/
void vPrtLogMsg(int line, const char *pszFileName, char logLevel, int iCode, /* const char *pszMsg,*/ ...)
{
char szTime[30],szFile[DEF_BUFFER_128]; // 128
char *p=NULL, szBuf[DEF_BUFFER_2K+1];
va_list vl ;
if(logLevel == __LOG_DEBUG ) {
if(g_TConfig.isLogDebug() == 0x00 /*&& g_TConfig.isLogConsole() == 0x00 && g_TConfig.isLogMessage() == 0x00 */) return;
}
else if(logLevel == __LOG_WARNG) {
if(g_TConfig.isLogWarning() == 0x00 /*&& g_TConfig.isLogConsole() == 0x00 && g_TConfig.isLogMessage() == 0x00 */) return;
}
else if(logLevel == __LOG_ERROR) {
if(g_TConfig.isLogError() == 0x00 /*&& g_TConfig.isLogConsole() == 0x00 && g_TConfig.isLogMessage() == 0x00 */) return;
}
if(g_fp == NULL) return ;
mutex_lock(mutex_Debug); //lock
//fseek(g_fp, 0l, SEEK_END) ;
vGetHostTime(szTime) ;
// if( ftell(g_fp) >= DEF_LOG_FILESZIE) { // 日志大小已经制定字节数时备份文件,并重新打开新文件
if( memcmp(szTime, g_logger_time, 8) != 0x00 ) { // 检查日志文件的时间是否为同一天,不是同一天时,重新产生新一天的日志文件名称
fclose(g_fp) ;
char szNFile[DEF_BUFFER_256];
memset(szNFile, 0x00, sizeof(szNFile)) ;
#ifdef _WIN32
sprintf(szNFile, "%s\\debug%.12s.bak", DEF_LOG_PATH_NAME,szTime) ;
sprintf(szFile, "%s\\debug%.8s.log", DEF_LOG_PATH_NAME,szTime) ;
#else
sprintf(szNFile, "%s/debug%.12s.bak", DEF_LOG_PATH_NAME,szTime) ;
sprintf(szFile, "%s/debug%.8s.log",DEF_LOG_PATH_NAME, szTime) ;
#endif
rename(szFile, szNFile) ;
if((g_fp = fopen(szFile,"a+")) == NULL) {
mutex_unlock(mutex_Debug); //unlock
printf("line:%d file:%s Can't open file:[%s] failed.\n",__LINE__,_FILE_, szFile);
return ;
}
strncpy(g_logger_time, szTime, 14); // 记录最近一次变更过的时间(YYYYMMDD)
}
memset(szTime,0,sizeof(szTime)) ;
memset(szBuf, 0x00, sizeof(szBuf));
vGetHostTimeFmt(szTime);
if(logLevel == __LOG_DEBUG) { // 跟踪日志
//if(g_TConfig.isLogConsole() == 0x00)
fprintf(g_fp,"[%s] [DEBUG]-%ld Line:%d %s --> RetCode:%d ",szTime, GETTID(),line, pszFileName, iCode);
sprintf(szBuf,"[%s] [DEBUG]-%ld Line:%d %s --> RetCode:%d ",szTime, GETTID(),line, pszFileName, iCode);
}
else if(logLevel == __LOG_WARNG) { // 告警日志
//if(g_TConfig.isLogConsole() == 0x00)
fprintf(g_fp,"[%s] [WARNING]-%ld Line:%d %s --> RetCode:%d ",szTime, GETTID(),line, pszFileName, iCode);
sprintf(szBuf,"[%s] [WARNING]-%ld Line:%d %s --> RetCode:%d ",szTime, GETTID(),line, pszFileName, iCode);
}
else if(logLevel == __LOG_ERROR) { // 错误日志
//if(g_TConfig.isLogConsole() == 0x00)
fprintf(g_fp,"[%s] [ERROR]-%ld Line:%d %s --> RetCode:%d ",szTime, GETTID(),line, pszFileName, iCode);
sprintf(szBuf,"[%s] [ERROR]-%ld Line:%d %s --> RetCode:%d ",szTime, GETTID(),line, pszFileName, iCode);
}
if(g_TConfig.isLogConsole() == 0x01) { // 屏幕输出
printf("%s ", szBuf) ;
}
va_start(vl, iCode);
while((p = va_arg(vl, char *))) {
#ifdef _WIN32
_vsnprintf(szBuf, sizeof(szBuf), p, vl);
#else
vsnprintf(szBuf, sizeof(szBuf), p, vl);
#endif
break;
}
va_end(vl);
if(g_TConfig.isLogConsole() == 0x01) { // 屏幕输出
printf("%s\n", szBuf) ;
}
fprintf(g_fp,"%s\n",szBuf);
fflush(g_fp);
mutex_unlock(mutex_Debug); //unlock
}
/*************************************************************************
** Description : 打印日志文件(16进制数据报文的打印)
** param in : iLine -- 打印的出处,行号
** : *szFileName -- 文件名
** : *pszTitle -- 主题提示信息
** : *pusMsg -- 报文数据
** : uiMsgLen -- 报文长度
** param out : None
** return code : None
************************************************************************/
void vPrtLogHex(int line, const char *pszFileName,char logLevel, int sockid, /* unsigned short msg_id, */
const char pszMsgType, unsigned char *pusMsg,int uiMsgLen)
{
int i, j;
char szBuf1[80+1], szBuf2[80+1];
char szTime[20+1], szHex[3+1];
char szFile[DEF_BUFFER_256];
char szTitle[1024]={0};
if(g_TConfig.isLogPack() == 0x00) return ;
if(g_fp == NULL) return ;
mutex_lock(mutex_Debug); //lock
//fseek(g_fp, 0l, SEEK_END) ;
vGetHostTime(szTime) ;
if( memcmp(szTime, g_logger_time, 8) != 0x00) { // 检查日志文件的时间是否为同一天,不是同一天时,重新产生新一天的日志文件名称
// if(ftell(g_fp) >= DEF_LOG_FILESZIE) {
fclose(g_fp) ;
char szNFile[DEF_BUFFER_256];
memset(szNFile, 0x00, sizeof(szNFile)) ;
#ifdef _WIN32
sprintf(szNFile, "%s\\debug%.12s.bak", DEF_LOG_PATH_NAME,szTime) ;
sprintf(szFile, "%s\\debug%.8s.log",DEF_LOG_PATH_NAME, szTime) ;
#else
sprintf(szNFile, "%s/debug%.12s.bak", DEF_LOG_PATH_NAME,szTime) ;
sprintf(szFile, "%s/debug%.8s.log",DEF_LOG_PATH_NAME, szTime) ;
#endif
rename(szFile, szNFile) ;
if((g_fp = fopen(szFile,"a+")) == NULL) {
mutex_unlock(mutex_Debug); //unlock
printf("line:%d file:%s Can't open file:[%s] failed.\n",__LINE__, _FILE_, szFile);
return ;
}
strncpy(g_logger_time, szTime,14); // 记录最近一次变更过的时间(YYYYMMDD)
}
vGetHostTimeFmt( szTime ) ; /* 获取系统时间 */
if(pszMsgType == PRT_PACK_SEND) {
fprintf(g_fp, "[%s] [DEBUG]-%ld Line:%d %s --> [SendData] sockid:%d length:%d\n",szTime, GETTID(),line,pszFileName,sockid,uiMsgLen);
sprintf(szTitle, "[%s] [DEBUG]-%ld Line:%d %s --> [SendData] sockid:%d length:%d\n",szTime, GETTID(),line,pszFileName,sockid,uiMsgLen);
}
else if(pszMsgType == PRT_PACK_RECV) {
fprintf(g_fp, "[%s] [DEBUG]-%ld Line:%d %s --> [RecvData] sockid:%d length:%d\n",szTime, GETTID(),line,pszFileName,sockid,uiMsgLen);
sprintf(szTitle, "[%s] [DEBUG]-%ld Line:%d %s --> [RecvData] sockid:%d length:%d\n",szTime, GETTID(),line,pszFileName,sockid,uiMsgLen);
}
else {
fprintf(g_fp, "[%s] [DEBUG]-%ld Line:%d %s --> [PrntData] sockid:%d length:%d\n",szTime, GETTID(),line,pszFileName,sockid,uiMsgLen);
sprintf(szTitle, "[%s] [DEBUG]-%ld Line:%d %s --> [PrntData] sockid:%d length:%d\n",szTime, GETTID(),line,pszFileName,sockid,uiMsgLen);
}
if(g_TConfig.isLogConsole() == 0x01) { // 屏幕输出
printf("%s", szTitle);
}
sprintf(szTitle, "[%s] [DEBUG]-%ld Line:%d %s", szTime,GETTID(),line,pszFileName) ;
for(i=0; i<uiMsgLen; i+=16, pusMsg+=16)
{
memset(szBuf1, 0, sizeof(szBuf1));
sprintf(szBuf1, "%04XH ",i);
memset(szBuf2, 0, sizeof(szBuf2));
for(j=0; j<16; j++)
{
if( (uiMsgLen-i) < 16 && j >= (uiMsgLen%16) )
break;
sprintf(szHex, "%02X ", pusMsg[j]&0xFF);
strcat(szBuf1, szHex);
if(j==7)
strcat(szBuf1, " ");
if(pusMsg[j]>0x20 && pusMsg[j]<0x0ff)
szBuf2[j] = pusMsg[j];
else
szBuf2[j] = '_';
}
for(; j<16; j++)
{
if(j==7)
strcat(szBuf1, " ");
strcat(szBuf1, " ");
}
fprintf(g_fp, "%s --> %s %s\n", szTitle, szBuf1, szBuf2);
if(g_TConfig.isLogConsole() == 0x01) { // 屏幕输出
printf("%s --> %s %s\n", szTitle, szBuf1, szBuf2);
}
}
fflush(g_fp); // 写入文件
mutex_unlock(mutex_Debug); //unlock
}