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 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()*/
}

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

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值