最近写了一个日志类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;
}