這幾天開始封裝日子,打算採用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__*/