一个简单又高效的日志系统
2009-05-18 20:06:14 来源:WEB开发网四、其它部分
程序中使用了CStdioFile来处理文件写入,在实现中如果使用text模式打开文件写入,会发现无法写入中文字符的问题。查找了一些资料,发现是字符编码的问题。有一种解决方法是用二进制方式打开,在文件的开头处写入unicode头部标识。
int CSuperLog::WriteUnicodeHeadToFile(CFile * pFile)
{
if (pFile == NULL)
{
return -1;
}
try
{
if (pFile->GetLength() == 0)
{
m_pFile->Write("\377\376", 2); // 就是FF FE
if (m_enStatus == ENUM_LOG_RUN)
{
m_pFile->WriteString(WELCOME_LOG_INFO);
}
m_pFile->Flush();
}
}
catch (...)
{
return -1;
}
return 0;
}
为了保证调用者尽可能的简单,程序把类接口都实现为静态方法,调用都可以直接使用。
#define WRITE_LOG CSuperLog::WriteLog
#define LOG_LEVEL_DEBUG CSuperLog::ENUM_LOG_LEVEL_DEBUG
#define LOG_LEVEL_RUN CSuperLog::ENUM_LOG_LEVEL_RUN
#define LOG_LEVEL_ERROR CSuperLog::ENUM_LOG_LEVEL_ERROR
调用者使用如下:
// 包含头文件
#include "common/SuperLog.h"
WRITE_LOG(_T("短信发送失败,重试一次。"), LOG_LEVEL_ERROR);
日志线程是在全局变量的析构函数中通知退出的。这时有可能还要会打印日志。为了保证性能,在取得当前时间的字符串时使用了两个静态局部变量
CString& CSuperLog::GetCurTimeStr()
{
static CTime g_tmCurTime;
g_tmCurTime = CTime::GetCurrentTime();// time(NULL);
CString g_strTime;
g_strTime = g_tmCurTime.Format(_T("%Y-%m-%d %H:%M:%S "));
return g_strTime;
}
在使用中发现,每次退出时,如果还有日志打印,程序总会异常。后来分析发现,静态全局变量每次都会先于全局变量析构,导致strTime析构后无效访问。只好把这个变量变成了全局变量规避。
CString& CSuperLog::GetCurTimeStr()
{
g_tmCurTime = CTime::GetCurrentTime();// time(NULL);
g_strTime = g_tmCurTime.Format(_T("%Y-%m-%d %H:%M:%S "));
return g_strTime;
}
四、结束语
程序实现仓促,基本的功能都调试完毕,但目前还有带参数的写日志接口没有写,二进制内容日志信息的接口也没有实现。后续作者会及时完成。有兴趣的同不学可以发邮件联系。Email:y63508@vip.qq.com
更多精彩
赞助商链接