头文件
#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="*************************************************************************\n"; int nRet=fwrite(pBuffer,strlen(pBuffer),1,fp); pBuffer="系统时间:"; fwrite(pBuffer,strlen(pBuffer),1,fp); std::string strTime=FormatTime(); //strTime.append("\n"); fwrite(strTime.c_str(),strTime.size(),1,fp); pBuffer="文件路径:"; fwrite(pBuffer,strlen(pBuffer),1,fp); char szSourcePath[MAX_PATH+2]={0}; sprintf(szSourcePath,"%s\n",__FILE__); fwrite(szSourcePath,strlen(szSourcePath),1,fp); pBuffer="异常行数:"; fwrite(pBuffer,strlen(pBuffer),1,fp); char szLine[7]={0}; sprintf(szLine,"%d\r\n",nLine); fwrite(szLine,strlen(szLine),1,fp); pBuffer="异常函数:"; fwrite(pBuffer,strlen(pBuffer),1,fp); strFuncName.append("\n"); fwrite(strFuncName.c_str(),strFuncName.size(),1,fp); pBuffer="异常信息:"; fwrite(pBuffer,strlen(pBuffer),1,fp); strExcep.append("\n"); 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()*/ }