|
最近写了一个日志类Clog,在实际系统中应用检验过了,效果不错,贴出来和大家交流交流,看还有没有需要改进的地方。
现对Clog类做部分说明:
这个类用到MFC的CFileFind,如果不用MFC,CFileFind实现的查找文件夹功能可用PathFileExists实现,当然,CString类型也需要转换。我已对写日志函数加锁,因此是线程安全的。
程序在当前目录下生成日志文件夹(如果该文件夹存在,则不生成),每天的日志放在一个以当天日期命名的文件夹中。
MAX_ROW 定义一个日志文件的最大行数,一个日志文件达到这个行数后即关闭,并创建一个新文件。
void Disable(); 关闭日志功能
void Enable(); 打开日志功能
int NewLogFile(); 创建新日志文件
BOOL IsChangeDay(); 判断是否跨天(凌晨0点)
CString GetCurntTime(); 获得当前时间字符串,格式为 2006-06-21-11-50
void WriteLogFile(const char* fmt, ... ); 写日志函数
头文件 LogFile.h
#include <sys/stat.h> #include <fcntl.h> #include <io.h> #include <afxmt.h>
#define MAX_ROW 5000
class CLog { public: void Disable(); void Enable(); CLog(); ~CLog(); void WriteLogFile(const char* fmt, ... ); protected: int NewLogFile(); BOOL IsChangeDay(); CString GetCurntTime(); private: int m_filehandle; int m_row; int m_dirnum; int m_filenum; BOOL m_needlog; char m_sContent[1024*1024]; CString m_strContent;
CString m_sCurtTime; CString m_sYestady; CString m_sToday; CString m_sCurtDir; CString m_sLogDir; CString m_sLogDayDir;
CCriticalSection m_cs; };
实现代码 LogFile.cpp
#include "stdafx.h" #include "LogFile.h"
#include <direct.h>
static char log_directory[]="ivr_log";
CLog::CLog() { m_row = 0; m_filehandle = 0; m_dirnum = 0; m_filenum = 0; m_sCurtTime = _T(""); m_sToday = _T(""); m_sYestady = _T(""); m_sCurtDir = _T(""); m_sLogDir = _T(""); m_needlog = FALSE;
GetCurrentDirectory(_MAX_PATH,m_sCurtDir.GetBuffer(_MAX_PATH)); m_sCurtDir.ReleaseBuffer();
CString sDirName; CFileFind f; BOOL bHasLogDir = FALSE; BOOL bFind = f.FindFile(m_sCurtDir + "\\*.*");
while (bFind) { bFind = f.FindNextFile(); if (f.IsDots()) continue; if (f.IsDirectory()) { sDirName = f.GetFileName(); sDirName.MakeLower(); if (sDirName == (CString)log_directory) { bHasLogDir = TRUE; break; } } } m_sLogDir = m_sCurtDir + (CString)"\\" + (CString)log_directory; if (!bHasLogDir) { _mkdir(m_sLogDir); }
CString strTime = GetCurntTime ();
m_sToday = strTime.Mid(0,10); }
CLog::~CLog() { _close(m_filehandle); }
int CLog::NewLogFile() { CString strLogfileName;
if (m_filenum > 0) { _close(m_filehandle); } strLogfileName = m_sLogDayDir + (CString)"\\" + m_sCurtTime + (CString)".txt"; if((m_filehandle=_open(strLogfileName,_O_WRONLY| _O_CREAT|O_TRUNC, _S_IREAD | _S_IWRITE)) == -1) { printf("cannot create log file:%s\n",strLogfileName); return -1; } m_filenum++; return 0; }
BOOL CLog::IsChangeDay() { m_sCurtTime = GetCurntTime(); m_sToday = m_sCurtTime.Mid(0,10); if (m_sToday != m_sYestady) { m_sYestady = m_sToday; m_sLogDayDir = m_sLogDir + (CString)"\\" + m_sToday; _mkdir(m_sLogDayDir); return TRUE; } return FALSE; }
void CLog::WriteLogFile(const char* fmt, ... ) { if (m_needlog) { m_cs.Lock();
if (m_row >= MAX_ROW || IsChangeDay()) { if (NewLogFile() == -1) { m_cs.Unlock(); return; } m_row = 0; } va_list v_args; va_start(v_args,fmt); vsprintf( m_sContent, fmt, v_args ); va_end( v_args ); CString strTime; CTime cTime = CTime::GetCurrentTime(); strTime = _T("20") + cTime.Format("%y-%m-%d %H:%M:%S"); /* char sTime[32]; time_t now = time(NULL); tm *tm_time = localtime(&now); //注意,localtime非线程安全 strftime(sTime,sizeof(sTime),"20%y-%m-%d %H:%M:%S",tm_time); */ m_strContent = (CString)"[" + strTime + (CString)"]" + (CString)m_sContent + "\n";
_write(m_filehandle,m_strContent,m_strContent.GetLength()); m_row++;
m_cs.Unlock(); } }
CString CLog::GetCurntTime() { CString strTime;
CTime cTime = CTime::GetCurrentTime(); strTime = _T("20") + cTime.Format("%y-%m-%d-%H-%M-%S");
return strTime; }
void CLog::Enable() { m_needlog = TRUE; }
void CLog::Disable() { m_needlog = FALSE; }
|