您的位置:首页 > 编程语言 > C语言/C++

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

2014-04-03 09:30 316 查看
头文件
#pragmaonce
/////////////////////////////////////////////////////////////////////////////////
//异常信息记录类

#include<string>
#ifdefUNICODE
#definetstringstd::wstring
#else
#definetstringstd::string
#endif

//定义异常信息结构体
typedefstruct_EXCEPTION_INFO
{
tstringtstrExceptionInfo;//异常信息字符串
intnExceptionLine;//出现异常的代码行
}EXCEPTION_INFO,LPEXCEPTION_INFO;

//填充异常结构体
inlineEXCEPTION_INFOFillExceptionInfo(TCHAR*pInfo,intnLine)
{
EXCEPTION_INFOei;
ei.tstrExceptionInfo.append(pInfo);
ei.nExceptionLine=nLine;
returnei;
}

class_declspec(dllexport)CErrorLog
{
public:
CErrorLog(TCHAR*pModuleName);
virtual~CErrorLog();
//记录异常,参数依次为函数名、错误信息、模块名
boolWriteErrorLog(tstring&tstrFuncName,intnLine,tstring&tstrErrorMsg=tstring(_T("")),tstring&tstrModuleName=tstring(_T("")));
boolWriteErrorLog(TCHAR*pFuncName,intnLine,TCHAR*pErrorMsg=NULL,TCHAR*pModuleName=NULL);
protected:
/********************受保护的成员函数**********************/
//记录自身异常
boolWriteOwerErrorLog(tstring&tstrFunName,tstring&tstrErrMsg,intnLine);
boolWriteOwerErrorLog(TCHAR*strFuncName,TCHAR*pErrorMsg,intnLine);
//格式化当前时间
inlinestd::stringFormatTime();
//获取系统错误信息
inlinestd::stringFormatLastError();
private:
//保存当前模块的名称
tstringm_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()
{

}
boolCErrorLog::WriteOwerErrorLog(TCHAR*pFuncName,TCHAR*pErrorMsg,intnLine)
{
returnWriteErrorLog(pFuncName,nLine,pErrorMsg,_T("CErrorLog"));
}

boolCErrorLog::WriteOwerErrorLog(tstring&tstrFunName,tstring&tstrErrMsg,intnLine)
{
returnWriteErrorLog(tstrFunName,nLine,tstrErrMsg,tstring(_T("CErrorLog")));
}

boolCErrorLog::WriteErrorLog(TCHAR*pFuncName,intnLine,TCHAR*pErrorMsg,TCHAR*pModuleName)
{
boolbRet=true;
try
{
assert(pFuncName);
if(NULL!=pErrorMsg)
{
std::stringstrExcep;
std::stringstrFuncName;
#ifdefUNICODE
strFuncName.append(CCodeCovert::WcharToChar(pFuncName));
strExcep.append(CCodeCovert::WcharToChar(pErrorMsg));
#else
strFuncName.append(pFuncName);
strExcep.append(pErrorMsg);
#endif
TCHARszPath[MAX_PATH+1]={0};
GetModuleFileName(NULL,szPath,MAX_PATH);
intnDes=-1;
for(size_ti=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
{
tstringstrTemp=m_strModuleName;
strTemp.append(_T(".log"));
_tcscat(szPath,strTemp.c_str());
}
FILE*fp=_tfopen(szPath,_T("a+"));
char*pBuffer="*************************************************************************\n";
intnRet=fwrite(pBuffer,strlen(pBuffer),1,fp);
pBuffer="系统时间:";
fwrite(pBuffer,strlen(pBuffer),1,fp);
std::stringstrTime=FormatTime();
//strTime.append("\n");
fwrite(strTime.c_str(),strTime.size(),1,fp);
pBuffer="文件路径:";
fwrite(pBuffer,strlen(pBuffer),1,fp);
charszSourcePath[MAX_PATH+2]={0};
sprintf(szSourcePath,"%s\n",__FILE__);
fwrite(szSourcePath,strlen(szSourcePath),1,fp);
pBuffer="异常行数:";
fwrite(pBuffer,strlen(pBuffer),1,fp);
charszLine[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::stringstrSyserror=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);
}
returnbRet;
}

boolCErrorLog::WriteErrorLog(tstring&tstrFuncName,intnLine,tstring&tstrErrorMsg/*=tstring(_T(""))*/,tstring&tstrModuleName/*=tstring(_T(""))*/)
{
returnWriteErrorLog((TCHAR*)tstrFuncName.c_str(),nLine,(TCHAR*)tstrErrorMsg.c_str(),\
(TCHAR*)tstrModuleName.c_str());
}

std::stringCErrorLog::FormatLastError()
{
std::stringstrRet("系统错误:");
try
{
LPVOIDlpErrorMsg=NULL;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER|
FORMAT_MESSAGE_FROM_SYSTEM|
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),//Defaultlanguage
(LPTSTR)&lpErrorMsg,
0,
NULL
);
tstringtstrError((LPTSTR)lpErrorMsg);
#ifdefUNICODE
std::stringstrError=CCodeCovert::WstringToString(tstrError);
strRet+=strError;
#else
strRet+=tstrError;
#endif
::LocalFree(lpErrorMsg);
}
catch(TCHAR*pError)
{
WriteOwerErrorLog(_T("FormatLastError"),pError,__LINE__);
}
returnstrRet;
}
std::stringCErrorLog::FormatTime()
{
std::stringstrRet;
try
{
tm*st;
time_ttime64=time(NULL);
st=localtime(&time64);
strRet.append(asctime(st));
}
catch(TCHAR*pError)
{

WriteOwerErrorLog(_T("FormatTime"),pError,__LINE__);
strRet.clear();
}
returnstrRet;
}

该类对基本的文件操作,错误信息获取,系统时间获取等进行了封装,使用的时候也是很简单的。
测试:

#include"stdafx.h"
#include<iostream>
#include"ErrorLog.h"
classCarBase:publicCErrorLog
{
public:
CarBase()
:CErrorLog(_T("CarBase"))
{

if(1)
WriteErrorLog(_T("CarBase"),__LINE__-1,_T("测试错误!!!!"));
}
public:
voidInit()
{
CarBase();
}
};
classCar:publicCarBase
{

};
int_tmain(intargc,_TCHAR*argv[])
{
CarBasecb;
intnlen=0;
nlen=sizeof(CarBase);
std::cout<<"类CarBase的大小为:"<<nlen<<std::endl;
for(inti=0;i<100;++i)
cb.WriteErrorLog(_T("MAIN"),__LINE__,_T("不知道的问题"),_T("模块"));
return0;
/*_onexit()*/
}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: