头文件
#pragma once
#define LOGFILE_LOG _T("_log")
#define LOGFILENAME _T("Agent")
#define LOGFILEEXT _T(".log")
#define DEFAULT_LOGFILEAPTH _T("C:/Microsoft/")
//定义一些典型的错误码
enum Error_Code
{
ERROR_OK = 0,
ERROR_WARN = 1,
ERROR_ERROR = 2
};
/****************************************************/
//默认日志大小为10M
//最大日志信息长度
const USHORT LOGINFO_MAX_LEN = 600;
const USHORT LOGINFO_CONTENT_LEN = 450;
//日志文件名最大长度
const USHORT LOGINFO_LOGFILE_MAX_LEN = 260;
//日志文件数量
const USHORT LOGINFO_MAX_NUM_LEN = 10;
//单个日志文件最大10M
const ULONG LOGINFO_MAX_SIZE = 10 * 1024 * 1024;
/****************************************************/
//程序路径
const USHORT APP_PATH_LEN = 260;
//
const USHORT PATH_LEN = 260;
//盘符长度
const USHORT MAX_DRIVE_LEN = 10;
//文件夹长度
const USHORT MAX_FOLDER_LEN = 200;
//文件名长度
const USHORT MAX_FILE_LEN = 100;
//后缀长度
const USHORT MAX_EXT_LEN = 10;
//路径的最大长度
const USHORT MAX_PATH_LEN = 200;
#define LOGINFO_HWSOCKET_INVOKE_SOCKETSEND _T("[HWSOCKET][Invoke] SocketSend: cMsgSend: %s, nMsgSendLen: %d\r\n")
#define LOGINFO_HWSOCKET_RETURN_SOCKETSEND _T("[HWSOCKET][Return] SocketSend: cMsgRecv: %s, nMsgRecvLen: %d\r\n")
class CLog
{
public:
CLog(void);
~CLog(void);
private:
DWORD m_dwProcessID;
//日志文件句柄
FILE* m_fp;
//日志操作临界区
CRITICAL_SECTION m_csLog;
//应用程序路径
CString m_strAppPath;
//应用程序名
CString m_strAppFile;
public:
int WriteLog(const int nRslt, LPTSTR FormatString,...);
};
源文件
#include "StdAfx.h"
#include "Log.h"
#include
CLog::CLog(void):m_fp(NULL)
{
InitializeCriticalSection(&m_csLog);
//程序盘符
TCHAR szDrive[PATH_LEN];
memset(szDrive, 0, PATH_LEN);
//程序所在目录
TCHAR szFolder[PATH_LEN];
memset(szFolder, 0, PATH_LEN);
TCHAR szAppPath[APP_PATH_LEN];
memset(szAppPath, 0 ,APP_PATH_LEN);
TCHAR szAppFolder[APP_PATH_LEN];
memset(szAppFolder, 0, APP_PATH_LEN);
TCHAR szFileName[MAX_FILE_LEN];
memset(szFileName, 0, MAX_FILE_LEN);
//取日志文件路径
DWORD dwSize = GetModuleFileName(NULL, szAppPath, APP_PATH_LEN);
//没有得到路径,就启用默认的路径
if (dwSize <= 0 || dwSize >= MAX_PATH_LEN)
{
m_strAppPath = DEFAULT_LOGFILEAPTH;
return;
}
//分割路径
_tsplitpath(szAppPath, szDrive, szFolder, szFileName, NULL);
_stprintf(szAppFolder, _T("%s%s"), szDrive, szFolder);
if (_tcslen(szAppFolder) >= MAX_PATH_LEN || !PathFileExists(szAppFolder))
{
m_strAppPath = DEFAULT_LOGFILEAPTH;
return;
}
if (_tcslen(szAppFolder) >= MAX_PATH_LEN || !PathFileExists(szAppFolder))
{
m_strAppPath = DEFAULT_LOGFILEAPTH;
return;
}
m_strAppPath = szAppFolder;
m_strAppFile = szFileName;
//取进程号
m_dwProcessID = GetCurrentProcessId();
}
CLog::~CLog(void)
{
if (NULL != m_fp)
{
fclose(m_fp);
m_fp = NULL;
}
//释放日志临界区对象
DeleteCriticalSection(&m_csLog);
}
int CLog::WriteLog(const int nRslt, LPTSTR FormatString,...)
{
//Log content
TCHAR szLogInfo[LOGINFO_MAX_LEN];
memset(szLogInfo, 0, LOGINFO_MAX_LEN);
//日志文件路径
TCHAR szLogPath[APP_PATH_LEN];
memset(szLogPath, 0, APP_PATH_LEN);
//get current time
SYSTEMTIME st;
TCHAR szTmp[LOGINFO_MAX_NUM_LEN];
memset(szTmp, 0, LOGINFO_MAX_NUM_LEN);
//log file whole path
TCHAR szLogFile[LOGINFO_LOGFILE_MAX_LEN];
memset(szLogFile, 0, LOGINFO_LOGFILE_MAX_LEN);
//如果日志写满了,则重命名日志文件
TCHAR szLogFileRename[LOGINFO_LOGFILE_MAX_LEN];
memset(szLogFileRename, 0, LOGINFO_LOGFILE_MAX_LEN);
FILE* fp = NULL;
int iIndex = 0;
int nReadSize = 0;
int ind = 0;
int ansiContentLen = 0;
char* szansiContent = NULL;
CString strContent = _T("");
TCHAR szContent[LOGINFO_CONTENT_LEN + 1];
memset(szContent, 0, LOGINFO_CONTENT_LEN + 1);
va_list args;
va_start(args, FormatString);
strContent.FormatV(FormatString, args);
va_end(args);
//只取前450个字节
if (strContent.GetLength() >= LOGINFO_CONTENT_LEN)
{
_tcsncpy(szContent, strContent.GetBuffer(), LOGINFO_CONTENT_LEN - 6);
//截断后,换行符没了,得重新加
_tcscat(szContent, _T("...\r\n"));
}
else
{
_tcscpy(szContent, strContent.GetBuffer());
}
strContent.ReleaseBuffer();
//[yy-mm-dd hh:mm:ss.zzz]
GetLocalTime(&st);
_stprintf(szLogInfo, _T("[%04d-%02d-%02d %02d:%02d:%02d.%03d][%d]"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, m_dwProcessID);
//[yy-mm-dd hh:mm:ss.zzz][LogLevel]
// memset(szTmp, 0, 256);
if (ERROR_OK == nRslt)
{
_tcscat(szLogInfo, _T("[Normal]"));
}
else if (ERROR_WARN == nRslt)
{
_tcscat(szLogInfo, _T("[Warn]"));
}
else if (ERROR_ERROR == nRslt)
{
//啥都不加
_tcscat(szLogInfo, _T("[ERROR]"));
}
else
{
_tcscat(szLogInfo, _T("[Normal]"));
}
_tcscat(szLogInfo, szContent);
// strcat(szLogInfo, "\t\n");
_stprintf(szLogPath, _T("%s%s_%s%s"), m_strAppPath.GetBuffer(), m_strAppFile.GetBuffer() , LOGFILENAME, LOGFILE_LOG);
m_strAppFile.ReleaseBuffer();
m_strAppPath.ReleaseBuffer();
wsprintf(szLogFile, _T("%s%s%s"), szLogPath, _T("_0"), LOGFILEEXT);
if (NULL == m_fp)
{
m_fp = _tfopen(szLogFile, _T("a+"));
}
if (NULL == m_fp)
{
return 1;
}
fseek(m_fp, SEEK_CUR, SEEK_END);
nReadSize = ftell(m_fp);
//如果文件大小没有超过日志文件大小的上限,则继续将日志写在该文件中
if (nReadSize < LOGINFO_MAX_SIZE)
{
EnterCriticalSection(&m_csLog);
ansiContentLen = WideCharToMultiByte(CP_ACP, 0, szLogInfo, _tcslen(szLogInfo), NULL, 0, NULL, NULL);
szansiContent = new char[ansiContentLen + 1];
memset(szansiContent, 0, ansiContentLen + 1);
WideCharToMultiByte(CP_ACP, 0, szLogInfo, _tcslen(szLogInfo), szansiContent, ansiContentLen, NULL, NULL);
szansiContent[ansiContentLen] = '\0';
fwrite(szansiContent, sizeof(char), ansiContentLen, m_fp);
delete [] szansiContent;
fflush(m_fp);
LeaveCriticalSection(&m_csLog);
}
//如果文件大小超过了10M,则HW_iDriver_Log_0.log重命名为HW_iDriver_Log_1.log
else
{
fclose(m_fp);
m_fp = NULL;
for (iIndex = 9; iIndex >= 1; iIndex--)
{
memset(szTmp, 0, LOGINFO_MAX_NUM_LEN);
memset(szLogFile, 0, LOGINFO_LOGFILE_MAX_LEN);
_tcscat(szLogFile, szLogPath);
_stprintf(szTmp, _T("_%d"), iIndex);
_tcscat(szLogFile, szTmp);
_tcscat(szLogFile, _T(".log"));
fp = _tfopen(szLogFile,_T("r"));
if(fp != NULL)
{
fclose(fp);
fp = NULL;
break;
}
}
//if all 10 log files are full
if (9 == iIndex)
{
memset(szLogFile, 0, LOGINFO_MAX_NUM_LEN);
_tcscat(szLogFile, szLogPath);
_tcscat(szLogFile, _T("_9.log"));
DeleteFileW (szLogFile);
iIndex--;
}
for (ind = iIndex; ind >= 0; ind--)
{
memset(szTmp, 0, LOGINFO_MAX_NUM_LEN);
memset(szLogFile, 0, LOGINFO_MAX_NUM_LEN);
memset(szLogFileRename, 0, LOGINFO_MAX_NUM_LEN);
_tcscat(szLogFile, szLogPath);
_tcscat(szLogFileRename, szLogPath);
_stprintf(szTmp, _T("_%d"), ind);
_tcscat(szLogFile, szTmp);
memset(szTmp, 0, LOGINFO_MAX_NUM_LEN);
_stprintf(szTmp, _T("_%d"), ind + 1);
_tcscat(szLogFileRename, szTmp);
_tcscat(szLogFile, _T(".log"));
_tcscat(szLogFileRename, _T(".log"));
_trename(szLogFile, szLogFileRename);
}
memset(szLogFile, 0, LOGINFO_LOGFILE_MAX_LEN);
_tcscat(szLogFile, szLogPath);
_tcscat(szLogFile, _T("_0.log"));
m_fp = _tfopen(szLogFile, _T("a+"));
if (m_fp != NULL)
{
EnterCriticalSection(&m_csLog);
//写之前转成GBK
ansiContentLen = WideCharToMultiByte(CP_ACP, 0, szLogInfo, _tcslen(szLogInfo), NULL, 0, NULL, NULL);
szansiContent = new char[ansiContentLen + 1];
memset(szansiContent, 0, ansiContentLen + 1);
WideCharToMultiByte(CP_ACP, 0, szLogInfo, _tcslen(szLogInfo), szansiContent, ansiContentLen, NULL, NULL);
szansiContent[ansiContentLen] = '\0';
fwrite(szansiContent, sizeof(char), ansiContentLen, m_fp);
delete [] szansiContent;
fflush(m_fp);
LeaveCriticalSection(&m_csLog);
}
}
return 0;
}