读书人

C++实现一个简单的错误日志记录类

发布时间: 2013-03-06 16:20:31 作者: rapoo

C++实现一个简单的异常日志记录类

 
头文件
#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 UNICODEstrFuncName.append(CCodeCovert::WcharToChar(pFuncName));strExcep.append(CCodeCovert::WcharToChar(pErrorMsg));#elsestrFuncName.append(pFuncName);strExcep.append(pErrorMsg);#endifTCHAR 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 UNICODEstd::string strError=CCodeCovert::WstringToString(tstrError);strRet+=strError;#elsestrRet+=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()*/}

由于能力有限,欢迎批评指教。

读书人网 >C++

热点推荐