Linux下Log4cpp封裝全過程

這幾天開始封裝日子,打算採用Log4cpp提供的日誌功能來寫日子。爲了方便產品內的調用,提議做了一部分封裝,將log4cpp的靜態庫 log4cpp.a 靜態鏈接到我開發的logLibrary.so內並提供了C調用接口。

1.提供LogWrapper.h提供對外的long方法


 

#ifndef __FRAMEWORK_LOGWRAPPER_H__
#define __FRAMEWORK_LOGWRAPPER_H__
/******************************************************************************
 *  日誌包裝類用於調用log4cpp日誌對象寫入日誌
 *
 *
 * 創建日期: 2011-06-28
 * 作者:     代紅偉
 * 修改歷史:
 * revision  日期  修改者  描述
 *
 *****************************************************************************/
#include "LogLibrary.h"
#include "LogUtils.h"
#ifdef _WIN32_OS
#pragma comment(lib,"log4cppD.lib")
__declspec(dllexport)
#endif
FRAMEWORK_LOGWRAPPER_NS_BEGIN
class LogWrapper
{
public:
  /**************************************************************************
  * 析構函數
  * 
  * 輸入參數:   無。  
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
  ~LogWrapper(void); 
  
  
  /**************************************************************************
  * 構造函數
  * 
  * 輸入參數:   moduleName 模塊名稱  
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
  LogWrapper(const char* moduleName);
  /**************************************************************************
  * 該方法用於輸出Info級別的日誌信息
  * 
  * 輸入參數:   stringFormat 日誌信息   
  * 輸出參數: 無。
  * 返回值:  輸出設施枚舉
  *************************************************************************/
  void info(const char* stringFormat,...) ;   
  
  /**************************************************************************
  * 該方法用於輸出Debug級別的日誌信息
  * 
  * 輸入參數:   func 函數名稱
                    file 文件名稱
     line 代碼行
     errid 錯誤號
     msg 日誌信息  
  * 輸出參數: 無。
  * 返回值:  輸出設施枚舉
  *************************************************************************/
  void debug(const char* func,const char* file,const long line,int errorId,const char* stringFormat,...);
  
  /**************************************************************************
  * 該方法用於輸出Debug級別的日誌信息
  * 
  * 輸入參數:   func 函數名稱
                    file 文件名稱
     line 代碼行
     stringForamt 日誌信息  
  * 輸出參數: 無。
  * 返回值:  輸出設施枚舉
  *************************************************************************/
  void debug2(const char* func,const char* file,const long line,const char* stringFormat,...); 
  
  /**************************************************************************
  * 該方法用於輸出Error級別的日誌信息
  * 
  * 輸入參數:   func 函數名稱
                    file 文件名稱
     line 代碼行
     errorId 錯誤號
     stringForamt 日誌信息   
  * 輸出參數: 無。
  * 返回值:  輸出設施枚舉
  *************************************************************************/  
  void error(const char* func,const char* file,const long line,int errorId,const char* stringFormat,...); 
  
  /**************************************************************************
  * 該方法用於輸出Error級別的日誌信息
  * 
  * 輸入參數:   func 函數名稱
                    file 文件名稱
     line 代碼行
     stringForamt 日誌信息   
  * 輸出參數: 無。
  * 返回值:  輸出設施枚舉
  *************************************************************************/
  void error2(const char* func,const char* file,const long line,const char* stringFormat,...);
  
  /**************************************************************************
  * 該方法用於輸出Fatal級別的日誌信息
  * 
  * 輸入參數:   func 函數名稱
                    file 文件名稱
     line 代碼行
     errorId 錯誤號
     stringForamt 日誌信息
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
  void fatal(const char* func,const char* file,const long line,int errorId,const char* stringFormat,...);
  
  /**************************************************************************
  * 該方法用於輸出Fatal級別的日誌信息
  * 
  * 輸入參數:   func 函數名稱
     *              file 文件名稱
  *    line 代碼行     
  *    stringForamt 日誌信息   
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
  void fatal2(const char* func,const char* file,const long line,const char* stringFormat,...) ;  
  
  /**************************************************************************
  * 該方法用於獲取當前日誌的模塊名稱
  * 
  * 輸入參數:   無。
  * 輸出參數: 無。
  * 返回值:  模塊名稱
  *************************************************************************/
  inline std::string ModuleName() const 
  {
   return _moduleName;
  }
  
private:
 LogWrapper(const LogWrapper& other){};
 LogWrapper& operator= (const LogWrapper& other){ return *this; }; 
 std::string _moduleName;
 LogUtils logger; 
};
FRAMEWORK_LOGWRAPPER_NS_END
#endif /*__FRAMEWORK_LOGWRAPPER_H__*/
 
2.提供配置文件讀取與log4cpp調用類LogUtils.h
#ifndef __FRAMEWORK_LOGWRAPPER_LOGUTILS_H__
#define __FRAMEWORK_LOGWRAPPER_LOGUTILS_H__
/******************************************************************************
 *  日誌類的基礎單元,用於讀取配置文件執行配置的信息,並調用log4cpp安配置
 *  標準輸出日誌信息。
 *
 * 創建日期: 2011-06-28
 * 作者:     代紅偉
 * 修改歷史:
 * revision  日期  修改者  描述
 *
 *****************************************************************************/
#ifndef TYPELOG4CPP
#define TYPELOG4CPP
#endif
#include "LogLibrary.h"
#include "ConfigureException.h"
#include "LogProperties.h"
#if defined(TYPELOG4CPP)
// appenders
#include <log4cpp/Appender.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/RollingFileAppender.hh>
#include <log4cpp/AbortAppender.hh>
#include <log4cpp/StringQueueAppender.hh>
#ifdef _WIN32_OS
#include <log4cpp/Win32DebugAppender.hh>
#include <log4cpp/NTEventLogAppender.hh>
#endif
#include <log4cpp/RemoteSyslogAppender.hh>
#ifdef LOG4CPP_HAVE_LIBIDSA
#include <log4cpp/IdsaAppender.hh>
#endif    // LOG4CPP_HAVE_LIBIDSA
#ifdef LOG4CPP_HAVE_SYSLOG
#include <log4cpp/SyslogAppender.hh>
#endif
// layouts
#include <log4cpp/Layout.hh>
#include <log4cpp/BasicLayout.hh>
#include <log4cpp/SimpleLayout.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/Priority.hh>
#include <log4cpp/Category.hh>
#endif
#define _MAXPATH 512
#define _MAXLENS 4096
FRAMEWORK_LOGWRAPPER_NS_BEGIN
class LogUtils
{
public:
/*日誌輸出的級別定義。*/
typedef enum level{
   FATAL  = 0,
   ALERT  = 100,
   CRIT   = 200,
   ERROR  = 300, 
   WARN   = 400,
   NOTICE = 500,
   INFO   = 600,
   DEBUG  = 700,
   NOTSET = 800
        
}LOGPRIORITY;

/*日誌輸出的方式定定義。*/
typedef enum output{
 FileAppender  = 1,        
 RollingFileAppender,      
 OstreamAppender,          
 StringQueueAppender,     
 Win32DebugAppender,       
 NTEventLogAppender,       
 SyslogAppender,     
 RemoteSyslogAppender 
}LOGAPPENDER;

/*日誌輸出的RemoteSysLog的輸出設備定義。*/
typedef enum facility{
   LOGKERN = 0,
   LOGUSER = 8,
   LOGMAIL = 16,
   LOGDAEMON = 24,
   LOGAUTH = 32,
   LOGSYSLOG = 40,
   LOGLPR = 48,
   LOGNEWS = 56,
   LOGUUCP = 64,
   LOGCRON = 72,
   LOGAUTHPRIV = 80,
   LOGFTP = 88
}SyslogFacility;
public:
 /**************************************************************************
 * 構造函數。
 * 
 * 輸入參數: 無。
 * 輸出參數: 無。
 * 返回值:  無。
 *************************************************************************/
 LogUtils();
 /**************************************************************************
  * 析構函數。
  * 
  * 輸入參數: 無。
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
 virtual ~LogUtils();
 /**************************************************************************
  * 該方法用於根據配置文件信息配置log4cpp的分類以及佈局信息。
  * 
  * 輸入參數: moduleName 模塊名稱
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
 void InitializeLog4Cpp(const char* moduleName);
 /**************************************************************************
  * 該方法用於釋放log4cpp的調用對象。
  * 
  * 輸入參數: moduleName 模塊名稱
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
 void ReleaseLog4cpp(); 
 /**************************************************************************
  * 該方法用於生成日誌信息前綴,包括函數名,文件名,代碼行已經線程ID信息。
  * 
  * 輸入參數: func 函數名稱
     file 文件名
     line 代碼行
     source 要輸出的字符數組
  * 輸出參數: 格式化後的前綴字符
  * 返回值:  格式化後的前綴字符
  *************************************************************************/
 char* makeLogPrefix(const char* func,const char* file,int line,char* source);
 /**************************************************************************
  * 該方法用於根據級別寫日誌信息。
  * 
  * 輸入參數:   level 日誌的輸出級別
     message 日誌的輸出信息     
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
 void writeLog(int level,const char* message);
 /**************************************************************************
  * 該方法用於將整形數據轉化成字符數據
  * 
  * 輸入參數:   integer 整形數據
     dest 轉換的字符數據    
  * 輸出參數: 轉換的字符數據 
  * 返回值:  轉換的字符數據
  *************************************************************************/
 char* IntToStr(int integer,char* dest);
private:
 /**************************************************************************
  * 該方法用於獲取當前系統時間並格式化輸出
  * "yyyy-mm-dd hh:mm:ss.ms"
  * 輸入參數:   currentTime  格式化後的字符串    
  * 輸出參數: 無。
  * 返回值:  格式化的時間字符串
  *************************************************************************/
 char* getCurrentDateTimeForamtStr(char* currentTime);
 
 /**************************************************************************
  * 該方法用於獲取當前系統時間並格式化輸出
  * "yyyy-mm-dd"
  * 輸入參數:   currentTime  格式化後的字符串    
  * 輸出參數: 無。
  * 返回值:  格式化的時間字符串
  *************************************************************************/
 char* getCurrentDayFormatStr(char* currentDay);
 /**************************************************************************
  * 該方法用於獲取當前運行的線程ID號
  * 
  * 輸入參數:   無   
  * 輸出參數: 無。
  * 返回值:  線程ID
  *************************************************************************/
 #ifdef _WIN32_OS
 u_long getCurrentThreadId();
 #else
 pthread_t getCurrentThreadId();
 #endif 
 /**************************************************************************
  * 該方法用於按照配置日期刪除日誌文件
  * 
  * 輸入參數:   dir_name 日誌文件所在目錄
     keepdays 日誌保留天數  
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
 int removeOldLogFiles(const char *dir_name,int keepdays);
 /**************************************************************************
  * 該方法用於讀取配置文件,並獲取日誌的輸出級別
  * 
  * 輸入參數:   initFileName 日誌配置文件   
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
 virtual int getLogLevelFromFile(const std::string& initFileName)throw(ConfigureException);
 /**************************************************************************
  * 該方法用於讀取配置文件,並獲取日誌的輸出方式
  * 
  * 輸入參數:   initFileName 日誌配置文件   
  * 輸出參數: 無。
  * 返回值:  輸出方式
  *************************************************************************/
 virtual int getLogAppenderFromFile(const std::string& initFileName)throw(ConfigureException);
 /**************************************************************************
  * 該方法用於讀取配置文件,並獲取日誌的輸出目錄
  * 
  * 輸入參數:   initFileName 日誌配置文件   
  * 輸出參數: 無。
  * 返回值:  輸出目錄
  *************************************************************************/
 virtual std::string getLogFilePath(const std::string& initFileName)throw(ConfigureException); 
 /**************************************************************************
  * 該方法用於讀取配置文件,並獲取日誌的回捲文件的最大值
  * 
  * 輸入參數:   initFileName 日誌配置文件   
  * 輸出參數: 無。
  * 返回值:  回捲文件的最大值
  *************************************************************************/
 virtual int getRollingFileMaxSize(const std::string& initFileName)throw(ConfigureException);
 /**************************************************************************
  * 該方法用於讀取配置文件,並獲取日誌Syslog名稱
  * 
  * 輸入參數:   initFileName 日誌配置文件   
  * 輸出參數: 無。
  * 返回值:  Syslog名稱
  *************************************************************************/
 virtual std::string getLocalSyslogName(const std::string& initFileName)throw(ConfigureException);
 /**************************************************************************
  * 該方法用於讀取配置文件,並獲取日誌的RemoteSyslog名稱
  * 
  * 輸入參數:   initFileName 日誌配置文件   
  * 輸出參數: 無。
  * 返回值:  RemoteSyslog名稱
  *************************************************************************/
 virtual std::string getRemoteSyslogName(const std::string& initFileName)throw(ConfigureException);
 /**************************************************************************
  * 該方法用於讀取配置文件,並獲取日誌的RemoteSyslog輸出的主機地址
  * 
  * 輸入參數:   initFileName 日誌配置文件   
  * 輸出參數: 無。
  * 返回值:  ip地址或主機名稱
  *************************************************************************/
 virtual std::string getRemoteSyslogHost(const std::string& initFileName)throw(ConfigureException);
 /**************************************************************************
  * 該方法用於讀取配置文件,並獲取日誌的RemoteSyslog輸出設施
  * 
  * 輸入參數:   initFileName 日誌配置文件   
  * 輸出參數: 無。
  * 返回值:  輸出設施枚舉
  *************************************************************************/
 virtual int getRemoteSyslogFacility(const std::string& initFileName)throw(ConfigureException);
 /**************************************************************************
  * 該方法用於讀取配置文件,並獲取日誌的RemoteSyslog輸出端口號
  * 
  * 輸入參數:   initFileName 日誌配置文件   
  * 輸出參數: 無。
  * 返回值:  端口號
  *************************************************************************/
 virtual int getRemoteSyslogPortNumber(const std::string& initFileName)throw(ConfigureException);
 /**************************************************************************
  * 該方法用於讀取配置文件,並獲取日誌的保留天數
  * 
  * 輸入參數:   initFileName 日誌配置文件   
  * 輸出參數: 無。
  * 返回值:  端口號
  *************************************************************************/
 virtual int getLogKeepDays(const std::string& initFileName)throw(ConfigureException);
private:
 void*  _logCategory;
 Properties _properties; 
 pthread_mutex_t logMutex;
};
FRAMEWORK_LOGWRAPPER_NS_END

#endif /* __FRAMEWORK_LOGWRAPPER_LOGUTILS_H__ */
3.字符串操作類StirngUtils.h
#ifndef __FRAMEWORK_LOGWRAPPER_STRINGUTIL_H__
#define __FRAMEWORK_LOGWRAPPER_STRINGUTIL_H__
/******************************************************************************
 *  字符串操作類,用於字符串的格式化,去除空格,字符分割等操作。
 *
 * 創建日期: 2011-06-28
 * 作者:     代紅偉
 * 修改歷史:
 * revision  日期  修改者  描述
 *
 *****************************************************************************/
 
#include "LogLibrary.h"
#include <string>
#include <vector>
#include <climits>
#include <stdarg.h>
FRAMEWORK_LOGWRAPPER_NS_BEGIN
class StringUtil 
{
public:       
  /**************************************************************************
  * 模擬vprintf(3),通過va_list格式化輸出字符串信息
  * 
  * 輸入參數: format 格式化字符
            args  va_list參數。
  * 輸出參數: 無。
  * 返回值:  格式化後的字符串
  *************************************************************************/
        static std::string vform(const char* format, va_list args);
        /**************************************************************************
  * 去字符空格
  * 
  * 輸入參數: s  要去空格的字符串。            
  * 輸出參數: 無。
  * 返回值:  去除空格後的字符串
  *************************************************************************/
        static std::string trim(const std::string& s);
     /**************************************************************************
  * 根據分割字符進行字符串分割到vector容器內
  * 
  * 輸入參數: v 存放分隔後的字符容器
      s 預分隔的字符
      delimiter 分隔符
  * 輸出參數: 無。
  * 返回值:  分隔後的字符段數量
  *************************************************************************/
  
        static unsigned int split(std::vector<std::string>& v, 
      const std::string& s, char delimiter,
      unsigned int maxSegments = INT_MAX);
  /**************************************************************************
  * 根據分割字符進行字符串的分割字符串
  * 
  * 輸入參數: output  分隔後的存放容器
                  s 預分隔的字符
      delimiter 分隔符
      maxSegments 最大的分隔段數。            
  * 輸出參數: 無。
  * 返回值:  分隔後的字符段數量
  *************************************************************************/
        template<typename T> static unsigned int split(T& output,
                const std::string& s, char delimiter,
                unsigned int maxSegments = INT_MAX) {
            std::string::size_type left = 0;
            unsigned int i;
            for(i = 1; i < maxSegments; i++) {
                std::string::size_type right = s.find(delimiter, left);
                if (right == std::string::npos) {
                    break;
                }
                *output++ = s.substr(left, right - left);
                left = right + 1;
            }
            
            *output++ = s.substr(left);
            return i;
        }
    };
FRAMEWORK_LOGWRAPPER_NS_END
#endif // __FRAMEWORK_LOGWRAPPER_STRINGUTIL_H__
4.C調用接口
#ifndef __FRAMEWORK_LOGWRAPPER_EXPORT_H__
#define __FRAMEWORK_LOGWRAPPER_EXPORT_H__
/******************************************************************************
 *  日誌類導出接口用於日誌類的創建與釋放
 *
 *
 * 創建日期: 2011-06-28
 * 作者:     代紅偉
 * 修改歷史:
 * revision  日期  修改者  描述
 *
 *****************************************************************************/
#include "LogLibrary.h"
#include "LogWrapper.h"
USE_FRAMEWORK_LOGWRAPPER_NS
#ifdef _WIN32_OS
#define LOGWRAPPER_API __declspec(dllexport)
#else
#define LOGWRAPPER_API 
#endif
#ifdef __cplusplus
extern "C" {
#endif
 /**************************************************************************
  * 該方法會根據模塊名稱創建日誌對象,存入日誌對象管理容器並返回對象給
  * 調用者。
  *
  * 輸入參數: moduleName 模塊名稱
  * 輸出參數: 無。
  * 返回值:   無。
  *************************************************************************/
 LOGWRAPPER_API LogWrapper* LIBRARY_CALL  CreateLogWrapper(const char* moduleName);
 
 /**************************************************************************
  * 該方法會將當前待釋放的日誌對象,交由創建他的日誌對象維護隊列來徹底的釋放。
  *
  * 輸入參數: lw 要釋放的日誌包裝對象
  * 輸出參數: 無。
  * 返回值:   無。
  *************************************************************************/
 LOGWRAPPER_API void LIBRARY_CALL ReleaseLogWrapper(LogWrapper* lw);
#ifdef __cplusplus
}
#endif
#endif /*__FRAMEWORK_LOGWRAPPER_EXPORT_H__*/
5.配置文件異常定義類
#ifndef __FRAMEWORK_LOGWRAPPER_CONFIGUREEXCEPTION_H__
#define __FRAMEWORK_LOGWRAPPER_CONFIGUREEXCEPTION_H__
/******************************************************************************
 *  配置文件讀取異常類型定義類,用於拋出讀取配置文件的異常信息
 *
 * 異常類定義
 *
 * 創建日期: 2011-06-28
 * 作者:     代紅偉
 * 修改歷史:
 * revision  日期  修改者  描述
 *
 *****************************************************************************/
#include <string>
#include <stdexcept>
#include "LogLibrary.h"
FRAMEWORK_LOGWRAPPER_NS_BEGIN
    class  ConfigureException : public std::runtime_error {
        public:
        /**
         * Constructor.
         * @param reason String containing the description of the exception.
         */
   /**************************************************************************
   * 構造函數。
   * 
   * 輸入參數: reason  異常描述信息
   * 輸出參數: 無。
   * 返回值:  無。
   *************************************************************************/
        ConfigureException(const std::string& reason);
    };
FRAMEWORK_LOGWRAPPER_NS_END
#endif // __FRAMEWORK_LOGWRAPPER_CONFIGUREEXCEPTION_H__
5.配置文件讀取類
#ifndef __FRAMEWORK_LOGWRAPPER_LOGPROPERTIES_H__
#define __FRAMEWORK_LOGWRAPPER_LOGPROPERTIES_H__
/******************************************************************************
 *  配置文件解析類用於解析properties配置文件
 *
 *
 * 創建日期: 2011-06-28
 * 作者:     代紅偉
 * 修改歷史:
 * revision  日期  修改者  描述
 *
 *****************************************************************************/ 
#include "LogLibrary.h"
#include <string>
#include <iostream>
#include <map>
FRAMEWORK_LOGWRAPPER_NS_BEGIN
class Properties : public std::map<std::string, std::string> 
{
public:
 /**************************************************************************
 * 構造函數。
 * 
 * 輸入參數: 無。
 * 輸出參數: 無。
 * 返回值:  無。
 *************************************************************************/
 Properties();
 /**************************************************************************
  * 析構函數。
  * 
  * 輸入參數: 無。
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
 virtual ~Properties();
 /**************************************************************************
  * 該方法用於配置文件以流的方式讀入,並與用解析。
  * 
  * 輸入參數: in 輸入流
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
 virtual void load(std::istream& in);
 /**************************************************************************
  * 該方法用於配置文件以流方式保存。
  * 
  * 輸入參數: out 輸出流
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
 virtual void save(std::ostream& out);
 /**************************************************************************
  * 該方法從配置文件中讀取整形數據。
  * 
  * 輸入參數: property 要讀取的屬性字段
        defaultValue 默認的返回值,如果沒有讀取到數據的默認值。
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
 virtual int getInt(const std::string& property, int defaultValue);
 /**************************************************************************
  * 該方法從配置文件中讀取布爾型數據。
  * 
  * 輸入參數: property 要讀取的屬性字段
     defaultValue 默認的返回值,如果沒有讀取到數據的默認值。
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
 virtual bool getBool(const std::string& property, bool defaultValue);
 /**************************************************************************
  * 該方法從配置文件中讀取字符型數據。
  * 
  * 輸入參數: property 要讀取的屬性字段
     defaultValue 默認的返回值,如果沒有讀取到數據的默認值。
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
 virtual std::string getString(const std::string& property,
          const char* defaultValue);
protected:
 /**************************************************************************
  * 該方法讀取子項數據,目前沒有這樣的配置所以沒做實現。
  * 
  * 輸入參數: value  子項值
  * 輸出參數: 無。
  * 返回值:  無。
  *************************************************************************/
 virtual void _substituteVariables(std::string& value);
};
FRAMEWORK_LOGWRAPPER_NS_END
#endif /*__FRAMEWORK_LOGWRAPPER_LOGPROPERTIES_H__*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章