生活随笔
收集整理的這篇文章主要介紹了
日志库EasyLogging++学习系列(6)—— 日志记录器
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
所有的日志都是由日志記錄器完成的,日志記錄器使用唯一的 ID(大小寫敏感)來標識。在 Easylogging++ 中默認了三個現(xiàn)有的日志記錄器:
- 性能日志記錄器,其 ID 為:performance
- 系統(tǒng)日志記錄器,其 ID 為:syslog,需要定義宏?ELPP_SYSLOG?,否則不存在
注冊日志記錄器
除了上述三個默認現(xiàn)有的日志記錄器,我們還可以注冊新的日志記錄器,這個在前面的《日志庫EasyLogging++學習系列(3)—— 配置功能》一文中就提到了一種方法,就是使用全局配置文件來注冊。
現(xiàn)在介紹另外一種更通用的方法,就是使用?
el::Loggers::getLogger()函數(shù)。下面把這個函數(shù)從源碼中摘錄出來:
[cpp] view plaincopy print?
static?inline?Logger*?getLogger(const?std::string&?identity,?bool?registerIfNotAvailable?=?true)?{??????????base::threading::ScopedLock?scopedLock(ELPP->lock());??????????return?ELPP->registeredLoggers()->get(identity,?registerIfNotAvailable);??????}?? static inline Logger* getLogger(const std::string& identity, bool registerIfNotAvailable = true) {base::threading::ScopedLock scopedLock(ELPP->lock());return ELPP->registeredLoggers()->get(identity, registerIfNotAvailable);}函數(shù)參數(shù)說明:
- ?identity,日志記錄器 ID 標識,注意大小寫敏感。
- registerIfNotAvailable,當指定 ID 的日志記錄器不存在時,值為true則新建一個指定 ID 的日志記錄器,并返回它的一個對象指針,值為false則返回 NULL;當指定 ID 的日志記錄器已經(jīng)存在時,不論該參數(shù)為何值,都返回它的一個對象指針。
所有新建的日志記錄器都是使用通過默認配置功能設置好的配置,同樣是詳見《日志庫EasyLogging++學習系列(3)—— 配置功能》一文中的默認配置功能介紹。其實,每一個日志記錄器的配置都可以是不同的,只需利用函數(shù) ?
el::Loggers::reconfigureLogger()重新設置即可。
注銷日志記錄器
你可以注銷除了默認日志記錄器(ID:default)以外所有的日志記錄器。不過僅僅建議你選擇注銷由你自己注冊的并且不再使用的日志記錄器,否則可能會出現(xiàn)意料之外的錯誤。你可以使用函數(shù)
el::Loggers::unregisterLogger()注銷某一個日志記錄器。下面是這個函數(shù)的源碼:
[cpp] view plaincopy print?
static?inline?bool?unregisterLogger(const?std::string&?identity)?{??????????base::threading::ScopedLock?scopedLock(ELPP->lock());??????????return?ELPP->registeredLoggers()->remove(identity);??????}?? static inline bool unregisterLogger(const std::string& identity) {base::threading::ScopedLock scopedLock(ELPP->lock());return ELPP->registeredLoggers()->remove(identity);}
在 Easylogging++ V9.80版本中,這個函數(shù)有個錯誤,最終會導致程序崩潰。原因很簡單,就是有個指針對象釋放之后仍被使用,下面是出錯的源碼:
[cpp] view plaincopy print?
inline?void?unregister(const?T_Key&?uniqKey)?{??????????T_Ptr*?existing?=?get(uniqKey);??????????if?(existing?!=?nullptr)?{??????????????base::utils::safeDelete(existing);??????????????this->list().erase(uniqKey);??????????}??????}?? inline void unregister(const T_Key& uniqKey) {T_Ptr* existing = get(uniqKey);if (existing != nullptr) {base::utils::safeDelete(existing);this->list().erase(uniqKey);}}第四行的 existing 和第五行的 uniqKey 其實是指向同一個對象的,先 delete 后 erase 導致出錯。改正的方法也很簡單,只需替換兩行代碼順序即可。
枚舉日志記錄器
你可以使用函數(shù)
el::Loggers::populateAllLoggerIds(std::vector<std::string>&)枚舉日志庫中所有的日志記錄器。下面的代碼演示了注冊、注銷、枚舉日志記錄器等功能:
[cpp] view plaincopy print?
#define?ELPP_STL_LOGGING????#include?"easylogging++.h"????INITIALIZE_EASYLOGGINGPP????int?main(int?argc,?char**?argv)??{????????????CLOG(INFO,?"testlog");??????????????el::Logger*?newLogger?=?el::Loggers::getLogger("testlog");??????CLOG(INFO,?"testlog")?<<?"this?is?a?new?logger";??????????????std::vector<std::string>?allLoggers;??????el::Loggers::populateAllLoggerIds(&allLoggers);??????LOG(INFO)?<<?allLoggers;??????????????el::Loggers::unregisterLogger("testlog");????????????CLOG(INFO,?"testlog");??????????????el::Loggers::populateAllLoggerIds(&allLoggers);??????LOG(INFO)?<<?allLoggers;????????system("pause");??????return?0;??}?? #define ELPP_STL_LOGGING
#include "easylogging++.h"INITIALIZE_EASYLOGGINGPPint main(int argc, char** argv)
{/// 使用一個不存在的日記記錄器會輸出一條錯誤信息CLOG(INFO, "testlog");/// 注冊一個新的日志記錄器el::Logger* newLogger = el::Loggers::getLogger("testlog");CLOG(INFO, "testlog") << "this is a new logger";/// 枚舉日志記錄器,沒有定義宏 ELPP_SYSLOG,不會枚舉出系統(tǒng)日志記錄器std::vector<std::string> allLoggers;el::Loggers::populateAllLoggerIds(&allLoggers);LOG(INFO) << allLoggers;/// 注銷日志記錄器el::Loggers::unregisterLogger("testlog");/// 使用一個不存在的日記記錄器會輸出一條錯誤信息CLOG(INFO, "testlog");/// 枚舉日志記錄器el::Loggers::populateAllLoggerIds(&allLoggers);LOG(INFO) << allLoggers;system("pause");return 0;
}
總結
以上是生活随笔為你收集整理的日志库EasyLogging++学习系列(6)—— 日志记录器的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。