一些写log文件的类
最近由于调试程序,所以写了些关于log的类。主要功能为输出调试信息到log文件,该类能按照一定的缩进格式输出程序运行轨迹,在VC6下调试通过,代码如下:
.h文件
class NElapseTime
{
public:
NElapseTime(bool bStart = true)
{
m_begin = 0;
m_end = 0;
if (bStart) Start();
}
~NElapseTime(){}
public:
void Start()
{
m_begin = clock();
m_end = m_begin;
}
void Stop()
{
m_end = clock();
}
long GetTime()
{
return (long)(m_end-m_begin);
}
private:
clock_t m_begin;
clock_t m_end;
};
class NLogFile
{
public:
NLogFile();
NLogFile(const char * strFileName, int nMaxChar = 1024, bool bInitFile = false);
virtual ~NLogFile();
void Initialize(const char * strFileName, int nMaxChar = 1024, bool bInitFile = false);
bool Print(const char * strFormat, ...);
bool vPrint(const char * strFormat, va_list vl);
void Indent();
void UnIndent();
protected:
inline bool Create();
inline bool Open();
inline bool Close();
inline void Destory();
protected:
int m_hFile;
CRITICAL_SECTION m_CritivalSection;
char m_strFileName[_MAX_PATH];
char* m_strContent;
int m_nMaxChar;
bool m_bReady;
static unsigned int m_nIndent;
};
class NGlobalLogFile : public NLogFile
{
public:
virtual ~NGlobalLogFile(){}
static NGlobalLogFile* instance()
{
static NGlobalLogFile logfile;
return &logfile;
}
protected:
NGlobalLogFile(){}
};
class NFunctionLog
{
public:
NFunctionLog(const char * strFunName);
NFunctionLog(NLogFile* pLogFile,const char * strFunName);
virtual ~NFunctionLog();
void Mark(const char* strFormat,...);
protected:
void Init(NLogFile* pLogFile,const char * strFunName);
protected:
NElapseTime m_elapseTime;
char m_strFunName[_MAX_PATH];
NLogFile * m_pLogFile;
};
.cpp文件
#include <fcntl.h>
#include <sys/stat.h>
#include <io.h>
#include <share.h>
#include <stdio.h>
unsigned int NLogFile::m_nIndent = 0;
NLogFile::NLogFile()
:m_hFile(-1),m_bReady(false),m_strContent(NULL)
{
InitializeCriticalSection(&m_CritivalSection);
}
NLogFile::NLogFile(const char * strFileName, int nMaxChar/* = 1024*/, bool bInitFile/* = false*/)
:m_hFile(-1),m_bReady(false),m_strContent(NULL)
{
InitializeCriticalSection(&m_CritivalSection);
}
NLogFile::~NLogFile()
{
EnterCriticalSection(&m_CritivalSection);
Close();
LeaveCriticalSection(&m_CritivalSection);
DeleteCriticalSection(&m_CritivalSection);
delete []m_strContent;
}
void NLogFile::Initialize(const char * strFileName, int nMaxChar/* = 1024*/, bool bInitFile/* = false*/)
{
ASSERT(strFileName && nMaxChar > 0);
EnterCriticalSection(&m_CritivalSection);
Destory();
m_strContent = new char[nMaxChar];
m_nMaxChar = nMaxChar;
strcpy(m_strFileName,strFileName);
if(bInitFile)
{
char str[_MAX_PATH] = { 0 };
sprintf(str,"del %s",strFileName);
system(str);
}
m_bReady = true;
LeaveCriticalSection(&m_CritivalSection);
}
inline void NLogFile::Destory()
{
if (NULL != m_strContent)
{
delete []m_strContent;
m_strContent = NULL;
}
m_hFile = -1;
m_nMaxChar = 0;
m_bReady = false;
memset(m_strFileName,0,_MAX_PATH);
}
inline bool NLogFile::Create()
{
if (!m_bReady)
return false;
Close();
m_hFile = _sopen(m_strFileName, _O_TEXT | _O_RDWR | _O_APPEND | _O_CREAT, _SH_DENYNO, _S_IREAD | _S_IWRITE);
return (m_hFile != -1);
}
inline bool NLogFile::Open()
{
if (!m_bReady)
return false;
Close();
m_hFile = _sopen(m_strFileName, _O_TEXT | _O_RDWR | _O_APPEND, _SH_DENYNO, _S_IREAD | _S_IWRITE);
if (m_hFile == -1)
{
return Create();
}
return true;
}
inline bool NLogFile::Close()
{
if (!m_bReady)
return false;
bool bRet = true;
if (m_hFile != -1)
{
bRet = (_close(m_hFile) == 0);
m_hFile = -1;
}
return bRet;
}
bool NLogFile::Print(const char * strFormat, ...)
{
if (!m_bReady)
return false;
bool bRet = false;
va_list v;
va_start(v, strFormat);
bRet = vPrint(strFormat,v);
va_end(v);
return bRet;
}
bool NLogFile::vPrint(const char * strFormat, va_list vl)
{
if (!m_bReady)
return false;
bool bRet = false;
EnterCriticalSection(&m_CritivalSection);
memset(m_strContent,0,m_nMaxChar);
sprintf(m_strContent,"%*s",4*m_nIndent,"");
vsprintf(m_strContent+strlen(m_strContent),strFormat,vl);
if (Open())
{
bRet = (0 ==
_write(m_hFile,(const void*)m_strContent,strlen(m_strContent)));
Close();
}
LeaveCriticalSection(&m_CritivalSection);
return bRet;
}
void NLogFile::Indent()
{
m_nIndent++;
}
void NLogFile::UnIndent()
{
if(m_nIndent > 0) m_nIndent--;
}
NFunctionLog::NFunctionLog(const char * strFunName)
:m_pLogFile(NULL)
{
NLogFile* pLogFile = static_cast<NLogFile*>(NGlobalLogFile::instance());
Init(pLogFile,strFunName);
}
NFunctionLog::NFunctionLog(NLogFile* pLogFile,const char * strFunName)
:m_pLogFile(NULL)
{
Init(pLogFile,strFunName);
}
NFunctionLog::~NFunctionLog()
{
m_elapseTime.Stop();
m_pLogFile->UnIndent();
m_pLogFile->Print("<-- %s : %d (ms)\n",m_strFunName,m_elapseTime.GetTime());
}
void NFunctionLog::Init(NLogFile* pLogFile,const char * strFunName)
{
ASSERT(pLogFile && strFunName);
m_pLogFile = pLogFile;
strcpy(m_strFunName,strFunName);
m_elapseTime.Start();
m_pLogFile->Print("--> %s\n",m_strFunName);
m_pLogFile->Indent();
}
void NFunctionLog::Mark(const char* strFormat,...)
{
va_list v;
va_start(v, strFormat);
m_pLogFile->vPrint(strFormat,v);
va_end(v);
}
用法:
1.可以用NGlobalLogFile类,全局只有一个!
NGlobalLogFile::instance()Initialize("c:\\globallogfile.txt");
void fun()
{
NFunctionLog fl("fun");
fl.Mark("test\n");
}
输出文件格式为
--> fun
test
<-- fun : 0 (ms)
2.可以用NLogFile类
NLogFile log("c:\\logfile.txt");
void fun()
{
NFunctionLog fl(&log,"fun");
fl.Mark("test\n");
}