在一个项目的开发中,经常会需要写一些运行的log啊,debug信息啊.正好我正在学习GP 相关的东西,就写了这个东西,希望能抛砖引玉了.
/*@$*************************************************************************** * File Name : MjLog.h * * COPYRIGHT Chen Mingjie 2001 [email protected] *******************************************************************************/ #ifndef _MjTools_CMjLog_ #define _MjTools_CMjLog_ namespace MjTools //Namespace defination for my tools { class GeneralLogControl //Base class of any specific log control class,providing basic controls { protected: bool m_bEnabled; public: GeneralLogControl(const std::string ControlStr):m_bEnabled(true){};//log is enabled by default GeneralLogControl():m_bEnabled(true){}; virtual ~GeneralLogControl(){}; virtual void Pause(){m_bEnabled=false;} virtual void Resume(){m_bEnabled=true;} virtual bool CanAdd(std::string& LogStr){return m_bEnabled;} }; #ifdef WIN32 //RegistryLogControl only valid in Windows system class RegistryLogControl:public GeneralLogControl { protected: std::string m_ControlReg; bool CheckReg(const std::string& reg); public: RegistryLogControl(const std::string ControlStr) :m_ControlReg(ControlStr){m_bEnabled=CheckReg(ControlStr);} void Resume(){m_bEnabled=CheckReg(m_ControlReg);} virtual ~RegistryLogControl(){}; }; #endif class FileLogImpl //class that implements file logging ability { protected: std::string m_LogFileName; public: FileLogImpl(const std::string FileName):m_LogFileName(FileName) { if(m_LogFileName=="")m_LogFileName="log.txt"; //default file name }; virtual void AddTimeStamp(std::string& LogStr); //you may want to override this method to provide your time stamp style virtual ~FileLogImpl(){}; virtual bool AddLog(std::string& LogStr); //you may want to override this method to provide your log style virtual void Clear(); //clear log file content }; template<class ImplT, class ControlT> class CMjLog { protected: ControlT m_Control; //log control class ImplT m_Impl; //log implementation class public: CMjLog(const std::string ImplStr="",const std::string ControlStr="") :m_Control(ControlStr),m_Impl(ImplStr){}; virtual ~CMjLog(){}; bool AddLog(const std::string& LogStr) //Add one piece of log message { return AddLog(LogStr.c_str()); } bool AddLog(const char* pLogStr) //Add one piece of log message { std::string log=pLogStr; if(m_Control.CanAdd(log)) return m_Impl.AddLog(log); else return false; } void Pause() //Pause log process { m_Control.Pause(); } void Resume() //Resume log process { m_Control.Resume(); } void Clear() //Clear log content { m_Impl.Clear(); }
}; /*--------------CFileLog definition------------------*/ typedef CMjLog<FileLogImpl,GeneralLogControl> CFileLog; /*------------CFileLog Usage------------------------- MjTools::CFileLog log("C:\\test.log"); //Construct a new logfile or open a existing log file log.Clear(); //Delete previous logs. log.AddLog("This is a test line"); //Add one log message ---------------------------------------------------*/
#ifdef WIN32 //RegistryLogControl only valid in Windows system /*--------------CRegFileLog definition------------------*/ typedef CMjLog<FileLogImpl,RegistryLogControl> CRegFileLog; /*------------CRegFileLog Usage------------------------- MjTools::CRegFileLog log("C:\\test.log","HKEY_LOCAL_MACHINE\\Software\\YourLogControlKey"); //Construct a new logfile or open a existing log file log.Clear(); //Delete previous logs. log.AddLog("This is a test line"); //Add one log message ---------------------------------------------------*/ #endif } #endif
/*@$*************************************************************************** * File Name : MjLog.cpp * * COPYRIGHT Chen Mingjie 2001 [email protected] *******************************************************************************/
#include <sstream> #include <fstream> #include <string> #include "MjLog.h" #include "time.h" #ifdef WIN32 #include <windows.h> #include <Winreg.h> #endif namespace MjTools { void FileLogImpl::AddTimeStamp(std::string& LogStr) { time_t long_time; time( &long_time ); struct tm *pt = localtime( &long_time ); if(pt) { std::ostringstream stream; stream<<"AT:"<<pt->tm_hour<<':'<<pt->tm_min<<':'<<pt->tm_sec<<','<<pt->tm_year+1900<<'/'<<pt->tm_mon+1<<'/'<<pt->tm_mday<<"-------->"; LogStr=stream.str()+LogStr; } } bool FileLogImpl::AddLog(std::string& LogStr) { AddTimeStamp(LogStr); std::ofstream os(m_LogFileName.c_str(),std::ios::app); os<<LogStr; os<<std::endl; os.flush(); os.close(); return true; } void FileLogImpl::Clear() //clear file content { std::ofstream os(m_LogFileName.c_str(),std::ios::out); os.flush(); os.close(); } #ifdef WIN32 //RegistryLogControl only valid in Windows system bool RegistryLogControl::CheckReg(const std::string& reg) //Check if required reg key exists { HKEY hKey; HKEY hKeyRoot; bool ret=true; if(m_ControlReg!="") //if no control_reg_key provided,it means "no reg_key control" { int nPos=m_ControlReg.find('\\'); if(nPos==-1)ret=false; else { std::string root=m_ControlReg.substr(0,nPos); std::string rest=m_ControlReg.substr(nPos+1); if(root=="HKEY_LOCAL_MACHINE")hKeyRoot=HKEY_LOCAL_MACHINE; if(root=="HKEY_CLASSES_ROOT")hKeyRoot=HKEY_CLASSES_ROOT; if(root=="HKEY_CURRENT_CONFIG")hKeyRoot=HKEY_CURRENT_CONFIG; if(root=="HKEY_CURRENT_USER")hKeyRoot=HKEY_CURRENT_USER; if(root=="HKEY_USERS")hKeyRoot=HKEY_USERS; if(root=="HKEY_PERFORMANCE_DATA")hKeyRoot=HKEY_PERFORMANCE_DATA; if(root=="HKEY_DYN_DATA")hKeyRoot=HKEY_DYN_DATA ; ret=(::RegOpenKey (hKeyRoot,rest.c_str(),&hKey)==ERROR_SUCCESS); ::RegCloseKey(hKey); } } return ret; }; #endif } #ifdef _TEST_ int main() { MjTools::CFileLog m_Log("test.log"); std::string a="aaa"; m_Log.Clear(); m_Log.AddLog("Abc"); m_Log.AddLog(a); MjTools::CFileLog m_Log1=m_Log; m_Log1.AddLog("From Log1"); #ifdef WIN32 //RegistryLogControl only valid in Windows system //construct a registry key controled log object. If the specified registry key is found,the log is enabled MjTools::CRegFileLog m_regLog("reglog.log","HKEY_LOCAL_MACHINE\\Software\\YourLogControlKey"); m_regLog.AddLog("reglog"); m_regLog.Pause(); m_regLog.AddLog("reglog1"); m_regLog.Resume(); m_regLog.AddLog("reglog2"); #endif return 0; } #endif
如何编译 这两个文件本身就可以在不同的os下编译,比如
VC++: cl /D"_TEST_" MjLog.cpp /用命令行link会有个错,我也不知为什么,建一个空win32 console project再加入这两个文件就没有错了(别忘了predefine _TEST_)
BC++: BCC32 /D_TEST_ MjLog.cpp
g++: g++ /D_TEST MjLog.cpp
如何扩展
只要建立(或者继承)自己的control class 或者 impl class就可以用于各种用途,但对用户的接口是不变的

|