一个简单又高效的日志系统
2009-05-18 20:06:14 来源:WEB开发网 //创建共享文件。
m_hMapLogFile = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,1024, _T("SuperLogShareMem"));
if (m_hMapLogFile != NULL)
{
//拷贝数据到共享文件里。
m_psMapAddr = (LPTSTR)MapViewOfFile(m_hMapLogFile,FILE_MAP_ALL_ACCESS, 0,0,0);
if (m_psMapAddr != NULL)
{
_tcscpy_s(m_psMapAddr, 1024, g_pszLogLevel[m_iLogLevel]);
FlushViewOfFile(m_psMapAddr, _tcslen(g_pszLogLevel[m_iLogLevel]));
WriteLog(_T("设置默认日志级别到共享内存中成功。"), ENUM_LOG_LEVEL_RUN);
}
}
在线程中定时去检查这个日志级别有否有变化,有变化则立即调整当前的级别设置。
三、日志文件空间使用安全性问题
对于长期运行的商品程序来说,一定会要考虑到文件系统安全性的问题。如果程序不停的打印垃圾信息,用不了多太,日志文件可能会变得很大。如果把用户空间占满了,那有可能会引起更严重的问题。所以一定要限制日志文件的大小。程序中考虑到日志文件更换,采用了三个文件轮换写,写满一个时,更换一个文件再写,不用考虑到日志文件会耗尽磁盘。
CSuperLog::enLogStatus CSuperLog::OpenLogFile(void)
{
EnterCriticalSection(&m_csWriteLog);
for (int iRunCount = 0; iRunCount < MAX_LOG_FILE_COUNT; iRunCount++)
{
if (m_pFile == NULL)
{
m_pFile = new CStdioFile;
if (m_pFile == NULL)
{
LeaveCriticalSection(&m_csWriteLog);
return m_enStatus = ENUM_LOG_INVALID;
}
BOOL bRet = m_pFile->Open(
g_pszLogFileName[(m_iCurLogFileSeq++)%MAX_LOG_FILE_COUNT],
CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyNone | CFile::modeNoTruncate);
if (bRet)
{
WriteUnicodeHeadToFile(m_pFile);
}
else
{
delete m_pFile;
m_pFile = NULL;
LeaveCriticalSection(&m_csWriteLog);
return m_enStatus = ENUM_LOG_INVALID;
}
}
if (m_pFile->GetLength() > MAX_LOG_FILE_LEN)
{
m_pFile->Close();
BOOL bRet = FALSE;
// 上一个文件是最大的那个文件或是写过一遍了的。
if (m_iCurLogFileSeq >= MAX_LOG_FILE_COUNT)
{
// 所有文件都是写满了,则强制从第一个文件开始写,同时先清空文件
bRet = m_pFile->Open(
g_pszLogFileName[(m_iCurLogFileSeq++)%MAX_LOG_FILE_COUNT],
CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyNone);
}
else
{
// 打开第二个文件,再检查是否过了最大值
bRet = m_pFile->Open(
g_pszLogFileName[(m_iCurLogFileSeq++)%MAX_LOG_FILE_COUNT],
CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyNone | CFile::modeNoTruncate);
}
if (bRet)
{
WriteUnicodeHeadToFile(m_pFile);
}
else
{
delete m_pFile;
m_pFile = NULL;
LeaveCriticalSection(&m_csWriteLog);
return m_enStatus = ENUM_LOG_INVALID;
}
}
else
{
break;
}
}
m_pFile->SeekToEnd();
LeaveCriticalSection(&m_csWriteLog);
return m_enStatus = ENUM_LOG_RUN;
}
更多精彩
赞助商链接