A, the program log is an essential part of the commodity procedure. In formal commercial programs, there are generally some similar requirements for logs:
Performance requirements
Run-time log level can be adjusted
Log file space usage security issues
The following is an analysis of the program implementation for the above problem.
Second, performance problems.
The client's requirements for the program are of course the higher the better. If you have a normal way to print a log, write a log to the file, so that performance is low. Because of the continuous delivery of the program with the disk, the system impact is very large, it may affect the normal disk IO request.
For this problem, general, is to use the method of batch write to solve. Each write a log, not to write the log immediately into the file, but first write to a buffer. When this buffer reaches a certain amount, it is again written to the file in bulk. See the following code implementation:
if (!strLog.IsEmpty())
{
m_strWriteStrInfo += GetCurTimeStr();
// 增加日志级别信息
if (enLevel == ENUM_LOG_LEVEL_ERROR)
{
m_strWriteStrInfo += _T("Error! ");
}
m_strWriteStrInfo += strLog;
m_strWriteStrInfo += _T("\r\n");
}
if ( bForce
|| m_strWriteStrInfo.GetLength() > MAX_STR_LOG_INFO_LEN
|| m_iWriteBinLogLen > MAX_BIN_LOG_INFO_LEN/10)
{
// write info,达到一定量时才提交到文件中
WriteLogToFile();
}
But this will bring a problem, if the log volume is relatively small, it is likely to be a long time to reach the volume of submissions, which will cause the program to write a log, but the log recorder or write the message in the buffer, the file is not reflected in time. We can use the timing and timing method to output the log. The program periodically forces a flush to the file in the log message in the buffer. In order to embody the simplicity of the program, this function is implemented in the log module, thus calling the log program without considering timing to refresh the file. See the following program implementation:
CSuperLog::CSuperLog(void)
{
// 初始化临界区变量
InitializeCriticalSection(&m_csWriteLog);
// 启动信息
m_strWriteStrInfo = WELCOME_LOG_INFO;
// Create the Logger thread.
m_hThread = (HANDLE)_beginthreadex( NULL, 0, &LogProcStart, NULL, 0, &m_uiThreadID );
}
unsigned __stdcall CSuperLog::LogProcStart( void* pArguments )
{
int nCount = 1;
do
{
Sleep(300);
if (++nCount % 10 == 0 )
{
WriteLog(strTemp, ENUM_LOG_LEVEL_ERROR, true); // 每隔三秒写一次日志
}
} while (m_bRun);
}
A global Log class variable is adopted, the thread is started in the constructor, and the thread refreshes the file every three seconds.