UNICODE下日志打印(2)

头文件

#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;
}



 

你可能感兴趣的:(C/C++)