MBCS下日志打印(1)

概述

日志文件最大10M,文件名可以根据序号修改并且自动命名,最新的日志是序号为0的日志,如“日志_AgentRest_log_0.log”。当日志累计到10个时,程序将会删除最旧的一个。

头文件

#pragma once
//定义一些典型的错误码
enum Error_Code
{
	ERROR_OK = 0,
	ERROR_PARAM_ERROR,					//参数错误
	ERROR_INITIALED,					//已经初始化过了
	ERROR_UNINITIAL,					//未初始化
	ERROR_NOT_SIGNIN,					//未签入
	ERROR_SIGNINED,						//已经签入,必须先签出
	ERROR_HTTP_FAIL,					//HTTP请求失败
	ERROR_SIGNINMEDIASERVER_FAIL,
	ERROR_ANALYZE_FAIL,					//HTTP报文解析失败
	ERROR_UNKNOWN,
	ERROR_ALLOC_MEMORY,					//分配内存失败
	ERROR_DEBUG_NORMAL = 400,
	ERROR_DEBUG_ERROR = 401,
	ERROR_SYSTEM = 500,
	ERROR_EVENT = 501,
	ERROR_BOOLEN = 502,
	ERROR_WARN = 999
};

/****************************************************************************/
//默认日志大小为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;				//日志文件数量
const ULONG LOGINFO_MAX_SIZE = 10 * 1024 * 1024;	//单个日志文件最大10M
//程序路径相关
const USHORT APP_PATH_LEN  =  260;					//程序路径
const USHORT MAX_PATH_LEN = 200;					//路径的最大长度
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;						//后缀长度

#define LOGFILEEXT    ".log"						//日志文件后缀
#define LOGFILE_LOG   "_log"
#define LOGFILENAME "AgentRest"   
#define DEFAULT_LOGFILEAPTH "C:/agentrest/"
/****************************************************************************/

class CLog
{
public:
	CLog(void);
	~CLog(void);

private:
	CString m_strAppPath;							//应用程序路径
	CString m_strAppFile;							//应用程序名

	DWORD m_dwProcessID;
	
	FILE* m_fp;										//日志文件句柄
	CRITICAL_SECTION  m_csLog;						//日志操作临界区

public:
	int WriteLog(const int nRslt, LPCSTR FormatString, ...);
};


源文件

#include "StdAfx.h"
#include "Log.h"
#include <Shlwapi.h>


CLog::CLog(void):m_dwProcessID(0), m_fp(NULL) 
{
	m_dwProcessID = GetCurrentProcessId();							//取进程号

	InitializeCriticalSection(&m_csLog);

	/*****************************取日志文件路径********************************/
	char szFolder[PATH_LEN];										//程序所在目录
	memset(szFolder, 0, PATH_LEN);
	char szAppPath[APP_PATH_LEN];
	memset(szAppPath, 0 ,APP_PATH_LEN);
	char szAppFolder[APP_PATH_LEN];
	memset(szAppFolder, 0, APP_PATH_LEN);
	char szDrive[PATH_LEN];											//程序盘符 
	memset(szDrive, 0, PATH_LEN);
	char 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;
	}
	_splitpath(szAppPath, szDrive, szFolder, szFileName, NULL);		//分割路径      
	sprintf_s(szAppFolder, "%s%s", szDrive, szFolder);

	//程序所在目录
	if (strlen(szAppFolder) >= MAX_PATH_LEN || !PathFileExists(szAppFolder))
	{
		m_strAppPath = DEFAULT_LOGFILEAPTH;
		return;
	}

	m_strAppPath = szAppFolder;   
	m_strAppFile = szFileName;
	/****************************************************************************/

}

CLog::~CLog(void)
{
	if (NULL != m_fp)
	{
		fclose(m_fp);
		m_fp = NULL;
	}

	//释放日志临界区对象
	DeleteCriticalSection(&m_csLog);
}

//======================================================================================================
// 函 数 名:WriteLog
// 功能描述:打印日志
// 输入参数:szLog    : 日志内容   
//           usLevel  : 日志级别,缺省值为 4 一般信息
//                       1:错误日志  
//                       2:警告信息 
//                       3:一般信息日志 
//           nLogSize : 日志文件大小,缺省大小为10M          
// 输出参数:无
// 返回参数:0:成功
//           1:失败
//           2:日志级别小于系统设定的打印级别
// 创建日期:
// 修改日期:
// 作      者:
// 附加说明:日志文件名为HWIDriver.log,
//           当日志文件超过设置值后,备份日志文件为AgentRest_n.log(n>=1 && n<=10)
//			 n超过10,则删除AgentBarOCX_10.log
//========================================================================================================
int CLog::WriteLog(const int nRslt, LPCSTR FormatString, ...)
{
	//Log content
	char szLogInfo[LOGINFO_MAX_LEN];
	memset(szLogInfo, 0, LOGINFO_MAX_LEN);

	//日志文件路径
	char szLogPath[APP_PATH_LEN];
	memset(szLogPath, 0, APP_PATH_LEN);

	//get current time
	SYSTEMTIME st;

	char szTmp[LOGINFO_MAX_NUM_LEN];
	memset(szTmp, 0, LOGINFO_MAX_NUM_LEN);

	//log file whole path
	char szLogFile[LOGINFO_LOGFILE_MAX_LEN];
	memset(szLogFile, 0, LOGINFO_LOGFILE_MAX_LEN);

	//如果日志写满了,则重命名日志文件
	char szLogFileRename[LOGINFO_LOGFILE_MAX_LEN];
	memset(szLogFileRename, 0, LOGINFO_LOGFILE_MAX_LEN);

	FILE* fp = NULL;

	int iIndex = 0;
	int nReadSize = 0;
	int ind = 0;

	CString strContent = "";

	char 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)
	{
		strncpy_s(szContent, strContent.GetBuffer(), LOGINFO_CONTENT_LEN - 6);
		//截断后,换行符没了,得重新加
		strcat_s(szContent, "...\r\n");
	}
	else
	{
		strcpy_s(szContent, strContent.GetBuffer());
	}
	strContent.ReleaseBuffer();

	//[yy-mm-dd hh:mm:ss.zzz]
	//[2012-11-19 11:30:27.762][4704]
	GetLocalTime(&st);
	sprintf_s(szLogInfo, "[%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)
	{
		strcat_s(szLogInfo, "[Normal]");
	}
	else if (ERROR_WARN == nRslt)
	{
		strcat_s(szLogInfo, "[Warn]");
	}
	else if (ERROR_SYSTEM == nRslt)
	{
		//啥都不加
	}
	else if (ERROR_EVENT == nRslt)
	{
		//不加
	}
	else if (ERROR_DEBUG_NORMAL == nRslt)
	{
		strcat_s(szLogInfo, "[Debug][Normal]");
	}
	else if (ERROR_DEBUG_ERROR == nRslt)
	{
		strcat_s(szLogInfo, "[Debug][Error]");
	}
	else
	{
		if (nRslt-100 >= 0)
		{
			if (0 == (nRslt - 100) || 1 == (nRslt - 100))
			{
				strcat_s(szLogInfo, "[Normal]");
			}   
			else
			{
				strcat_s(szLogInfo, "[Fail]"); 
			}
		}
		else
		{
			strcat_s(szLogInfo, "[Fail]");  
		}
	}
	
	strcat_s(szLogInfo, szContent);

	sprintf_s(szLogPath, "%s%s_%s%s", m_strAppPath.GetBuffer(), m_strAppFile.GetBuffer() , LOGFILENAME, LOGFILE_LOG);
	m_strAppFile.ReleaseBuffer();
	m_strAppPath.ReleaseBuffer();

	sprintf_s(szLogFile, "%s%s%s", szLogPath, "_0", LOGFILEEXT);

	if (NULL == m_fp)
	{
		m_fp = fopen(szLogFile, "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);
		fwrite(szLogInfo, sizeof(char), strlen(szLogInfo), m_fp);
		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);
			strcat_s(szLogFile, szLogPath);
			sprintf_s(szTmp, "_%d", iIndex);


			strcat_s(szLogFile, szTmp);
			strcat_s(szLogFile, ".log");

			fp = fopen(szLogFile,"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);
			strcat_s(szLogFile, szLogPath);
			strcat_s(szLogFile, "_9.log");
			DeleteFile(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);

			strcat_s(szLogFile, szLogPath);
			strcat_s(szLogFileRename, szLogPath);

			sprintf_s(szTmp, "_%d", ind);
			strcat_s(szLogFile, szTmp);

			memset(szTmp, 0, LOGINFO_MAX_NUM_LEN);
			sprintf_s(szTmp, "_%d", ind + 1);
			strcat_s(szLogFileRename, szTmp);

			strcat_s(szLogFile, ".log");
			strcat_s(szLogFileRename, ".log");

			rename(szLogFile, szLogFileRename);
		}

		memset(szLogFile, 0, LOGINFO_LOGFILE_MAX_LEN);
		strcat_s(szLogFile, szLogPath);
		strcat_s(szLogFile, "_0.log");

		m_fp = fopen(szLogFile, "a+");

		if (m_fp != NULL)
		{
			EnterCriticalSection(&m_csLog);
			fwrite(szLogInfo, sizeof(char), strlen(szLogInfo), m_fp);
			fflush(m_fp);
			LeaveCriticalSection(&m_csLog);
		}   
	}
	return 0;
}


 使用:

 

//[2012-11-19 11:38:16.297][5820][Normal][Method return] QueryWaitCallInfo: lSkillID: 0 Rslt: 0
	CLog log;
	log.WriteLog(0, LOGINFO_METHOD_RETURN_QUERYWAITCALLINFO, 0, 0 );


你可能感兴趣的:(MBCS下日志打印(1))