返回大旺国际登录网站

基于VC的日志文件类库实现教程

时间:2011-08-25 01:40来源:大旺国际登录网站www.zhixing123.cn 编辑:麦田守望者

日志文件应具备基本功能
Log4j据说是最闻名的日志文件类库,有针对于C++或者.NET的移植版本。一直不明白日志文件有什么特殊之处,也没有研究其功能强大在何处。

理想中的日志文件类库功能应该具备:一个中心、两项基本功能、三个补充要求!
一个中心点: 使用简单
就是使用的时候可以感觉日志功能是随插随用,不用在代码层次上做太多前期的步骤。
两个基本功能:日志类型管理、日志文件管理
日志类型管理包括:格式化输出、日期时间标记等。前者可以考虑为日志分类,后者带上时间标记便于跟踪调试分析。
日志文件管理包括:日志文件的大小约定、按时间段整理等
三点补充要求:多种类型信息输出、多个进程输出到同一个日志文件、多进程线程同时输出时互斥操作
以下是根据在实际过程中的运用,封装一个简单的日志文件功能模块。麻雀虽小,但是却满足以上所有要求。其中,对于日志文件管理这块简单点约定输出到指定文件名。

由于采用CString,因此仅适用于MFC!但是可以方便的改造为纯C|C++。

//===============================================================// LOG::简单的日志工具// 日志功能包应该包括以下两块功能:// 1. 每个日志文本串// 目前日志文本串包括 [prefix][datetime][type][info...]// a.多个进程输出到同一个日志文件,可通过prefix来区分每个进程; 可以忽略// b.datetime可以用来测试时间// c.类型可以设定[error|warn|debug],// 由使用者任意使用,并不做明确标记; 也可以忽略// d.info,可以根据实际情况任意格式化输出,类似printf// 2. 日志文件// a. 可将日志串保存到文本,或者自己处理// b. 支撑并发写操作// c. 日志文件的管理//===============================================================

--------------------------------------------------------------------------------

.h文件
class LOG{public:LOG();virtual ~LOG(); public://-日志文件-//----如果没有指定,则为exe所在路径下的log.log文件----static CString GetLogFile();static short SetLogFile(LPCTSTR strPath);static short ViewLogFile(); //-前缀-//----如果多个进程往同一个文件输出日志,可以为每个进程设置一个前缀----//----前缀出现在日期时间之前----static short SetPrefix(LPCTSTR strPrefix); //-日志信息-//-获取日志字符串,可以另外-static CString sOutV(LPCTSTR strType, LPCTSTR strFormat = NULL, va_list valist = NULL);static CString sOut0(LPCTSTR strType, LPCTSTR strFormat = NULL,...);static CString sOut ( LPCTSTR strFormat = NULL,...); //-将日志信息输出到文件-static short OutV(LPCTSTR strType, LPCTSTR strFormat = NULL, va_list valist = NULL);static short Out0(LPCTSTR strType, LPCTSTR strFormat = NULL,...);static short Out (LPCTSTR strFormat = NULL,...); protected:static CString s_strLogFile;static CString s_strLogPrefix;static HANDLE s_hWriteEvent;};

--------------------------------------------------------------------------------

.cpp文件
// 得到可实行程序所在目录// BOOL bIncludeSep -- 是否包含最后的分隔符"\"CString GetExePath(BOOL bIncludeSep){// 得到当前的文件名CString strFileName;GetModuleFileName(AfxGetInstanceHandle(),strFileName.GetBuffer(_MAX_PATH),_MAX_PATH);strFileName.ReleaseBuffer();// 得到当前目录strFileName=strFileName.Left(strFileName.ReverseFind(_T('\\'))+1); if(bIncludeSep)return strFileName;elsereturn strFileName.Left(strFileName.GetLength()-1);} //-获取最后的文件名 如果给定文件不是全路径,就是相对于exe-CString GetFileForExePath(LPCTSTR strCurFileName){CString strPath = strCurFileName;if(!strPath.IsEmpty()){//-相对路径-if(strPath.Find(_T(":"))<=0) { strPath.Format(_T("%s%s"), GetExePath(FALSE), strCurFileName); } } return strPath; } #define LOG_EVENT _T("ChyLogWrite") CString LOG::s_strLogFile = _T(""); CString LOG::s_strLogPrefix = _T(""); HANDLE LOG::s_hWriteEvent = NULL; LOG::LOG() {} LOG::~LOG() {} short LOG::SetLogFile(LPCTSTR strPath){if(strPath==NULL || strPath[0]==0)s_strLogFile = GetFileForExePath("log.log");elses_strLogFile = GetFileForExePath(strPath); return 1;} CString LOG::GetLogFile(){return s_strLogFile;} short LOG::ViewLogFile(){CString strLogFile = GetLogFile();ShellExecute(NULL, _T("open"), strLogFile, NULL, NULL, SW_SHOW);return strLogFile.IsEmpty()?0:1;} short LOG::SetPrefix(LPCTSTR strPrefix){if(strPrefix && strPrefix[0]){s_strLogPrefix = strPrefix;} return 1;} CString LOG::sOutV(LPCTSTR strType, LPCTSTR strFormat, va_list valist){ CString strPart_Prefix;if(!s_strLogPrefix.IsEmpty()){strPart_Prefix.Format(_T("[%s]"), s_strLogPrefix);} CString strPart_Time;{SYSTEMTIME sysTime = {0};GetLocalTime(&sysTime);strPart_Time.Format(_T("[%2d-%2d %2d:%2d:%2d_%3d]"), sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds); } CString strPart_Type;if(strType && strType[0]){strPart_Type.Format(_T("[%s]"), strType);} CString strPart_Info;{ strPart_Info.FormatV(strFormat, valist);} CString str = strPart_Prefix + strPart_Time + strPart_Type+ strPart_Info; return str;} CString LOG::sOut0(LPCTSTR strType, LPCTSTR strFormat,...){va_list valist;va_start(valist, strFormat); CString strInfo = sOutV(strType, strFormat, valist);va_end(valist); return strInfo;} CString LOG::sOut(LPCTSTR strFormat,...){va_list valist;va_start(valist, strFormat);CString strInfo = sOutV(NULL, strFormat, valist);va_end(valist); return strInfo;} short LOG::OutV(LPCTSTR strType, LPCTSTR strFormat, va_list valist){//--if(s_hWriteEvent==NULL){s_hWriteEvent = OpenEvent(0, FALSE,LOG_EVENT);if(s_hWriteEvent==NULL)s_hWriteEvent = CreateEvent(NULL, FALSE, TRUE, LOG_EVENT); } WaitForSingleObject(s_hWriteEvent, INFINITE); //-打开关闭文件-if(s_strLogFile.IsEmpty())SetLogFile(NULL);CStdioFile file;if(file.Open(s_strLogFile, CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite)){CString strPart_NewLine = _T("\n");CString strInfo = sOutV(strType, strFormat, valist); CString str = strPart_NewLine + strInfo; file.SeekToEnd();file.WriteString(str);file.Close();} SetEvent(s_hWriteEvent); return 1;} short LOG::Out0(LPCTSTR strType, LPCTSTR strFormat,...){va_list valist;va_start(valist, strFormat); short rtn = OutV(strType, strFormat, valist);va_end(valist); return rtn;} short LOG::Out(LPCTSTR strFormat,...){va_list valist;va_start(valist, strFormat);short rtn = OutV(NULL, strFormat, valist);va_end(valist); return rtn;}

--------------------------------------------------------------------------------

使用说明
//-设定日志文件,建议在Exe初始化时设定-//-设置相对路径则表示exe所在路径下-//-如果不设定则为exe所在路径下的log.log文件-LOG::SetLogFile("bbb.log"); //-获取日志文本串,可以自行处理,例如输出到界面-CString str;str = LOG::sOut0("debug", "hello");str = LOG::sOut0("warn5", "hello %d", 25);str = LOG::sOut0("warn3", "hello %s, you have %d apples!", "libai", 10);str = LOG::sOut ("hello %s, you have %d apples!", "libai", 10); //-输出到文件-LOG::Out0("debug", "hello");LOG::Out0("warn5", "hello %d", 25);LOG::Out0("warn3", "hello %s, you have %d apples!", "libai", 10);LOG::Out ("hello %s, you have %d apples!", "libai", 10); //-查看日志文件-LOG::ViewLogFile();

--------------------------------------------------------------------------------

输出效果
[ 7-28 17:23:59_ 31][debug]hello[ 7-28 17:24: 0_ 93][warn5]hello 25[ 7-28 17:24: 0_343][warn3]hello libai, you have 10 apples![ 7-28 17:24: 0_593]hello libai, you have 10 apples!
 

------分隔线----------------------------
标签(Tag):C# C#实例教程 c#基础教程 C#源代码 c#技巧
------分隔线----------------------------
推荐内容
猜你感兴趣
XML 地图 | Sitemap 地图