生活随笔
收集整理的這篇文章主要介紹了
封装log4cp p
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
log4cpp 是參考 log4j 所寫的 c++ 版本的寫 log 的庫。可以在這里下載 http://log4cpp.sourceforge.net/ 我的使用方法是: 1,定義了一個 _LOG4CPP 宏,用來打開或關閉 log4cpp 的調用,以便在完全不需要 log 的情況下可以運行,例如進行性能測試時;又比如 log4cpp 可能有內存泄露,關閉使用它,可以檢查程序其它地方是否有泄露; 2,在寫 log 時,自動加上函數名,以方便跟蹤運行信息;(在 gcc 可以用可變參數宏定義,vc 中用其它辦法,稍后說明) 3,每一個需要寫 log 的類,都加上一個靜態 log 實例,以方便通過配置,使得相應的 log 可以輸出到指定的地方,有利于跟蹤特定的運行信息; 4,不直接調用 log4cpp ,而是通過宏定義來使用,原因同1,即有利于關閉 log 功能; 基于以上幾點,我寫了幾個函數及宏定義等,以下逐一說明: // InitializeLog4cpp 從指定的 log 配置文件中讀取信息,并初始化 log4cpp,這個函數在進程的入口處調用 void InitializeLog4cpp(const std::string & logfile); // ReleaseLog4cpp 用于釋入 log4cpp ,在進程的結束處調用 void ReleaseLog4cpp(); // 以下宏用于在類中聲明一個靜態變量,變量名為 "log" DECLARE_STATIC_LOG() // 以下宏用于初如化類中的 log 靜態變量 DEFINE_STATIC_LOG(ClassName) // 以下是用來寫 log 信息的幾個宏,嚴重級別分別為 DEBUG, INFO, NOTICE, ERROR LogDebug LogInfo LogNotice LogError 以下先演示一個應用實例: Demo.h 文件主要內容:
?
#include?"LogUtils.h"
namespace dk {
class?Demo { public: ????Demo(); ????virtual?~Demo(); ???? public: ????void?TestIt(int?i,?int?j); private: ????DECLARE_STATIC_LOG(); };
}
?
?
Demo.cpp 文件主要內容:
?
#include?"Demo.h"
namespace dk {
DEFINE_STATIC_LOG(Demo); Demo::Demo() { ????LogInfo(""); } Demo::~Demo() { ????LogInfo(""); } void?Demo::TestIt(int?i,?int?j) { ????LogInfo("i=%d, j=%d",?i,?j); }
}
?
再寫個例子來運行,可以看到類似輸出
[INFO] - Demo::Demo() -? [INFO] - Demo::TestIt() - i=1, j=2 [INFO] - Demo::~Demo() -
最后附上完整的
LogUtils.h
LogUtils.cpp
LogTracer.h (這個文件是因為 vc 不支持可變參數的宏,所以采用的取巧方法,這方法是從網上搜來的,出處忘了,請見諒。)
LogUtils.h
?
?
?
#ifndef?_LOG_UTILS_H_ #define?_LOG_UTILS_H_ #include?<string> #include?"LogTracer.h" #if?defined(_LOG4CPP) #include?<log4cpp/Category.hh> namespace?log4cpp { ????class?Category; }; #endif namespace?dk { void?InitializeLog4cpp(const?std::string?&?logfile); void?ReleaseLog4cpp(); #if?defined?(_LOG4CPP) log4cpp::Category?&?GetLogCategory(const?char?*?categoryName); #endif #if?defined?(_LOG4CPP) #????define?DECLARE_STATIC_LOG()?static?log4cpp::Category?&?log #????define?DEFINE_STATIC_LOG(ClassName)?log4cpp::Category?&?ClassName::log?=GetLogCategory(#ClassName) #else #????define?DECLARE_STATIC_LOG() #????define?DEFINE_STATIC_LOG(ClassName) #endif void?suck(const?char?*?fmt,?...); #if?defined(_LOG4CPP)?&&?defined(WIN32) #?????define?MakePrefix????std::string(__FUNCTION__).append("() - ") #????define?LogDebug ????(LogDebuger(log,?MakePrefix)) #????define?LogInfo????????(LogInfoer(log,?MakePrefix)) #????define?LogNotice ????(LogNoticer(log,?MakePrefix)) #????define?LogError????????(LogErrorer(log,?MakePrefix)) #elif?defined(_LOG4CPP)?&&?!defined(WIN32) #????defineMakePrefix(fmt)????????std::string(__FILE__).append("::").append(__FUNCTION__).append("() - ").append(fmt).c_str() #????define?LogDebug(fmt,?...)????log.debug(MakePrefix(fmt),?##__VA_ARGS__) #????define?LogInfo(fmt,?...)????log.info(MakePrefix(fmt),?##__VA_ARGS__) #????define?LogNotice(fmt,?...)????log.notice(MakePrefix(fmt),?##__VA_ARGS__) #????define?LogError(fmt,?...)????log.error(MakePrefix(fmt),?##__VA_ARGS__) #else #????define?LogDebug ????????suck #????define?LogInfo????????????suck #????define?LogNotice ????????suck #????define?LogError????????????suck #endif } #endif
?
LogUtils.cpp
?
#include?"LogUtils.h" #if?defined(_LOG4CPP) #include?<log4cpp/PropertyConfigurator.hh> // appenders #include?<log4cpp/Appender.hh> #include?<log4cpp/OstreamAppender.hh> #include?<log4cpp/FileAppender.hh> #include?<log4cpp/RollingFileAppender.hh> #include?<log4cpp/AbortAppender.hh> #ifdef?WIN32 #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> #endif namespace?dk { ???? void?InitializeLog4cpp(const?std::string?&?logfile) { #if?defined(_LOG4CPP) ????try ????{? ????????log4cpp::PropertyConfigurator::configure(logfile); ????} ????catch?(log4cpp::ConfigureFailure?&?f) ????{ ????????std::cerr?<<?"Configure Problem "?<<?f.what()?<<?std::endl; ???????????? //#if defined(WIN32) //????????log4cpp::Appender * appender = new log4cpp::Win32DebugAppender("console");???? //#else ????????log4cpp::Appender?*?appender?=?new?log4cpp::OstreamAppender("console",?&std::cout); //#endif ???????????? ????????log4cpp::PatternLayout?*?patternLayout?=?new?log4cpp::PatternLayout(); ????????patternLayout->setConversionPattern("%d [%t] %p - %m%n"); ????????appender->setLayout(patternLayout); ???????????? ????????log4cpp::Category?&?root?=?log4cpp::Category::getRoot(); ????????root.addAppender(appender); ????????root.setPriority(log4cpp::Priority::DEBUG); ????} #endif } void?ReleaseLog4cpp() { #if?defined(_LOG4CPP) ????log4cpp::Category::shutdown(); #endif } #if?defined(_LOG4CPP) log4cpp::Category?&?GetLogCategory(const?char?*?categoryName) { ????std::string?name?=?"dk."; ????name.append(categoryName); ????return?log4cpp::Category::getInstance(name); } #endif void?suck(const?char?*?fmt,?...) { ????if?(fmt)?{} } }
?
LogTracer.h
?
?
#ifndef?_LOG_TRACER_H_ #define?_LOG_TRACER_H_ #if?defined(_LOG4CPP)?&&?defined(WIN32) #include?<log4cpp/Category.hh> namespace?log4cpp { ????class?Category; }; namespace?dk { #include?<stdarg.h> #include?<stdio.h> class?LogTracer { public: ????LogTracer(log4cpp::Category?&?log,?const?std::string?&?prefix) ????????:?mLog(log) ????????,?mMsg(prefix) ????{} ?? ????void?operator()(const?char?*?fmt,?...) ????{ ????????va_list?ap; ????????va_start(ap,?fmt); ????????AppendString(mMsg,?fmt,?ap); ????????WriteLog(mMsg); ????????va_end(ap); ????} ???? private: ????virtual?void?WriteLog(const?std::string?&?message)?=?0; ????void?AppendString(std::string?&?message,?const?char?*?format,?va_list?args) ????{ ????????size_t?size?=?1024; ????????char?*?buffer?=?new?char[size]; ????? ????????while?(1) ????????{ ????????????int?n?=?_vsnprintf(buffer,?size,?format,?args); ????? ????????????// If that worked, return a string. ????????????if?((n?>?-1)?&&?(static_cast<size_t>(n)?<?size)) ????????????{ ????????????????message.append(buffer); ????????????????delete?[]?buffer; ????????????????return; ????????????} ????? ????????????// Else try again with more space. ????????????size?=?(n?>?-1)?? ????????????????n?+?1?:?// ISO/IEC 9899:1999 ????????????????size?*?2;?// twice the old size ????? ????????????delete?[]?buffer; ????????????buffer?=?new?char[size]; ????????} ????} private: ????// copy-ctor and operator= ????LogTracer(const?LogTracer?&); ????LogTracer?&?operator=(const?LogTracer?&); protected: ????log4cpp::Category?&?mLog; ????std::string?mMsg; }; class?LogDebuger ????:?public?LogTracer { public: ????LogDebuger(log4cpp::Category?&?log,?const?std::string?&?prefix) ????????:?LogTracer(log,?prefix) ????{ ????} ???? private: ????virtual?void?WriteLog(const?std::string?&?message) ????{ ????????mLog.debug(message); ????} }; class?LogInfoer ????:?public?LogTracer { public: ????LogInfoer(log4cpp::Category?&?log,?const?std::string?&?prefix) ????????:?LogTracer(log,?prefix) ????{ ????} ???? private: ????virtual?void?WriteLog(const?std::string?&?message) ????{ ????????mLog.info(message); ????} }; class?LogNoticer ????:?public?LogTracer { public: ????LogNoticer(log4cpp::Category?&?log,?const?std::string?&?prefix) ????????:?LogTracer(log,?prefix) ????{ ????} ???? private: ????virtual?void?WriteLog(const?std::string?&?message) ????{ ????????mLog.notice(message); ????} }; class?LogErrorer ????:?public?LogTracer { public: ????LogErrorer(log4cpp::Category?&?log,?const?std::string?&?prefix) ????????:?LogTracer(log,?prefix) ????{ ????} ???? private: ????virtual?void?WriteLog(const?std::string?&?message) ????{ ????????mLog.error(message); ????} }; } #endif #endif
總結
以上是生活随笔 為你收集整理的封装log4cp p 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。