C++は簡単な異常ログ記録クラスを実現する

7786 ワード

 
   
#pragma once
/////////////////////////////////////////////////////////////////////////////////
//       

#include <string>
#ifdef UNICODE
#define tstring std::wstring
#else
#define tstring std::string
#endif

//         
typedef struct _EXCEPTION_INFO
{
	tstring tstrExceptionInfo;//       
	int     nExceptionLine;	//        
}EXCEPTION_INFO,LPEXCEPTION_INFO;

//       
inline EXCEPTION_INFO FillExceptionInfo(TCHAR* pInfo,int nLine)
{
	EXCEPTION_INFO ei;
	ei.tstrExceptionInfo.append(pInfo);
	ei.nExceptionLine=nLine;
	return ei;
}

class _declspec(dllexport) CErrorLog
{
public:
	CErrorLog(TCHAR* pModuleName);
	virtual~ CErrorLog();
	//    ,        、    、   
	bool WriteErrorLog(tstring& tstrFuncName,int nLine,tstring& tstrErrorMsg=tstring(_T("")),tstring& tstrModuleName=tstring(_T("")));
	bool WriteErrorLog(TCHAR* pFuncName,int nLine,TCHAR* pErrorMsg=NULL,TCHAR* pModuleName=NULL);
protected:
	/********************        **********************/
	//      
	bool WriteOwerErrorLog( tstring& tstrFunName, tstring& tstrErrMsg,int nLine);
	bool WriteOwerErrorLog(TCHAR* strFuncName,TCHAR* pErrorMsg,int nLine);
	//       
	inline std::string FormatTime();
	//        
	inline std::string FormatLastError();
private:
	//         
	tstring m_strModuleName;
};

インプリメンテーション
#include "stdafx.h"
#include "CodeConvert.h"
#include "ErrorLog.h"
#include <time.h>
#include <assert.h>

CErrorLog::CErrorLog(TCHAR* pModuleName)
{
	assert(pModuleName);
	m_strModuleName.append(pModuleName);
}
CErrorLog::~CErrorLog()
{

}
bool CErrorLog::WriteOwerErrorLog(TCHAR* pFuncName,TCHAR* pErrorMsg,int nLine)
{
	return WriteErrorLog(pFuncName,nLine,pErrorMsg,_T("CErrorLog"));
}

bool CErrorLog::WriteOwerErrorLog(tstring& tstrFunName, tstring& tstrErrMsg,int nLine )
{
	return WriteErrorLog(tstrFunName,nLine,tstrErrMsg,tstring(_T("CErrorLog")));
}

bool CErrorLog::WriteErrorLog(TCHAR* pFuncName,int nLine,TCHAR* pErrorMsg,TCHAR* pModuleName)
{
	bool bRet=true;
	try
	{
		assert(pFuncName);
		if(NULL!=pErrorMsg)
		{
			std::string strExcep;
			std::string strFuncName;
#ifdef UNICODE
			strFuncName.append(CCodeCovert::WcharToChar(pFuncName));
			strExcep.append(CCodeCovert::WcharToChar(pErrorMsg));
#else
			strFuncName.append(pFuncName);
			strExcep.append(pErrorMsg);
#endif
			TCHAR szPath[MAX_PATH+1]={0};
			GetModuleFileName(NULL,szPath,MAX_PATH);
			int nDes=-1;
			for(size_t i=0;i<_tcslen(szPath);++i)
			{
                if('\\'==szPath[i])
					nDes=i;
			}
			szPath[nDes+1]='\0';
			_tcscat(szPath,_T("ErrorLogs\\"));
			::CreateDirectory(szPath,NULL);
			if(NULL!=pModuleName)
			{
				_tcscat(szPath,pModuleName);
				_tcscat(szPath,_T(".log"));
			}
			else
			{
				tstring strTemp=m_strModuleName;
				strTemp.append(_T(".log"));
				_tcscat(szPath,strTemp.c_str());
			}
			FILE* fp=_tfopen(szPath,_T("a+"));
			char* pBuffer="*************************************************************************
"; int nRet=fwrite(pBuffer,strlen(pBuffer),1,fp); pBuffer=" :"; fwrite(pBuffer,strlen(pBuffer),1,fp); std::string strTime=FormatTime(); //strTime.append("
"); fwrite(strTime.c_str(),strTime.size(),1,fp); pBuffer=" :"; fwrite(pBuffer,strlen(pBuffer),1,fp); char szSourcePath[MAX_PATH+2]={0}; sprintf(szSourcePath,"%s
",__FILE__); fwrite(szSourcePath,strlen(szSourcePath),1,fp); pBuffer=" :"; fwrite(pBuffer,strlen(pBuffer),1,fp); char szLine[7]={0}; sprintf(szLine,"%d\r
",nLine); fwrite(szLine,strlen(szLine),1,fp); pBuffer=" :"; fwrite(pBuffer,strlen(pBuffer),1,fp); strFuncName.append("
"); fwrite(strFuncName.c_str(),strFuncName.size(),1,fp); pBuffer=" :"; fwrite(pBuffer,strlen(pBuffer),1,fp); strExcep.append("
"); fwrite(strExcep.c_str(),strExcep.size(),1,fp); std::string strSyserror=FormatLastError(); fwrite(strSyserror.c_str(),strSyserror.size(),1,fp); fclose(fp); } } catch(EXCEPTION_INFO& except) { bRet=false; WriteOwerErrorLog(tstring(_T("WriteErrorLog")),except.tstrExceptionInfo,except.nExceptionLine); } return bRet; } bool CErrorLog::WriteErrorLog( tstring& tstrFuncName,int nLine,tstring& tstrErrorMsg/*=tstring(_T(""))*/,tstring& tstrModuleName/*=tstring(_T(""))*/ ) { return WriteErrorLog((TCHAR*)tstrFuncName.c_str(),nLine,(TCHAR*)tstrErrorMsg.c_str(),\ (TCHAR*)tstrModuleName.c_str()); } std::string CErrorLog::FormatLastError() { std::string strRet(" :"); try { LPVOID lpErrorMsg=NULL; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&lpErrorMsg, 0, NULL ); tstring tstrError((LPTSTR)lpErrorMsg); #ifdef UNICODE std::string strError=CCodeCovert::WstringToString(tstrError); strRet+=strError; #else strRet+=tstrError; #endif ::LocalFree(lpErrorMsg); } catch(TCHAR* pError) { WriteOwerErrorLog(_T("FormatLastError"),pError,__LINE__); } return strRet; } std::string CErrorLog::FormatTime() { std::string strRet; try { tm* st; time_t time64=time(NULL); st=localtime(&time64); strRet.append(asctime(st)); } catch(TCHAR* pError) { WriteOwerErrorLog(_T("FormatTime"),pError,__LINE__); strRet.clear(); } return strRet; }

このクラスは基本的なファイル操作,エラー情報取得,システム時間取得などをカプセル化し,使用する場合も簡単である.
テスト:
#include "stdafx.h"
#include <iostream>
#include "ErrorLog.h"
class CarBase:public CErrorLog
{
public:
	CarBase()
		:CErrorLog(_T("CarBase"))
	{



		 if(1)
			 WriteErrorLog(_T("CarBase"),__LINE__-1,_T("    !!!!"));
	}
public:
	void Init()
	{
		CarBase();
	}
};
class Car:public CarBase
{

};
int _tmain(int argc, _TCHAR* argv[])
{
	CarBase cb;
	int nlen=0;
	nlen=sizeof(CarBase);
	std::cout<<" CarBase    :"<<nlen<<std::endl;
	for(int i=0;i<100;++i)
		cb.WriteErrorLog(_T("MAIN"),__LINE__,_T("      "),_T("  "));
	return 0;
/*	_onexit()*/
}

能力が限られているので,批判と指導を歓迎する.