【轉】 log4cpp 的使用

【轉自】 http://sogo6.iteye.com/blog/1154315     Log4cpp配置文件格式說明html

 
log4cpp有3個主要的組件:categories(類別)、appenders(附加目的地)、和 layouts(佈局),layout類控制輸出日誌消息的顯示樣式(看起來像什麼)。log4cpp當前提供如下layout格式: 

log4cpp::BasicLayout    // 以「時間戳 優先級(priority,下文介紹) 
                        // 類別(category,下文介紹) 
                        // NDC標籤 
log4cpp::PatternLayout  // 讓用戶根據相似於 C 語言 printf 函數的轉換模式來指定輸出格式。 
log4cpp::SimpleLayout   // 以「優先級(priority) - 日誌信息」格式顯示。 

appender類用來輸出日誌(被layout格式化後的)到一些設備上。好比文件、syslog服務、 某個socket等。能夠定義本身的appender類輸出日誌信息到別的設備上,好比應用自身的 linux

日子處理進程、數據庫等。appender和layout的關係是layout附在appender上, appender類調用layout處理完日誌消息後,記錄到某個設備上。log4cpp當前提供如下appender:          
1 log4cpp::IdsaAppender   // 發送到IDS或者logger,
2 log4cpp::FileAppender   // 輸出到文件
3 log4cpp::RollingFileAppender  // 輸出到回捲文件,即當文件到達某個大小後回捲
4 log4cpp::OstreamAppender   // 輸出到一個ostream類
5 log4cpp::RemoteSyslogAppender  // 輸出到遠程syslog服務器
6 log4cpp::StringQueueAppender  // 內存隊列
7 log4cpp::SyslogAppender   // 本地syslog
8 log4cpp::Win32DebugAppender  // 發送到缺省系統調試器
9 log4cpp::NTEventLogAppender  // 發送到win 事件日誌

category 類真正完成記錄日誌功能,兩個主要組成部分是appenders和priority(優先級)。優先級控制哪類日誌信息能夠被這個category記錄,當前優先級分爲:NOTSET, DEBUG, INFO, NOTICE, WARN, ERROR, CRIT, ALERT 或 FATAL/EMERG 。每一個日誌信息有個優先級,每一個category有個優先級,當消息的優先級大於等於category的優先級時,這個消息纔會被category記錄,不然被忽略。優先級的關係以下。category類和appender的關係是,多個appender附在category上,這樣一個日誌消息能夠同時輸出到多個設備上。 數據庫

NOTSET < DEBUG < INFO < NOTICE < WARN < ERROR < CRIT < ALERT < FATAL = EMERG 
category被組織成一個樹,子category建立時優先級缺省NOTSET,category缺省會繼承父category的appender。而若是不但願這種appender的繼承關係,log4cpp容許使用additivity 標籤,爲false時新的appender取代category的appender列表。 
log4cpp能夠用手動方式使用,也可使用配置文件使用,用配置文件的方式簡單,便捷。全部,如今都用配置文件的方式。 

log 的優先級別解讀,參閱源碼 log4cpp-0.3.5rc3\include\log4cpp\Priority.hh 

由高到低 

EMERG 
FATAL 
ALERT 
CRIT 
ERROR 
WARN 
NOTICE 
INFO 
DEBUG 
NOTSET 

對應到 Category 相應函數,參閱源碼 log4cpp-0.3.5rc3\include\log4cpp\Category.hh 

Category::emerg() 
Category::fatal() 
Category::alert() 
Category::crit() 
Category::error() 
Category::warn() 
Category::notice() 
Category::info() 
Category::debug() 

以上函數都有 2 個重載函數,可分別接受格式化字串或 std::string,例如 debug(),有 
 
1 void debug(const char* stringFormat, ...) throw();
2 void debug(const std::string& message) throw();

關於優先級別使用的建議 服務器

開發運行時,設爲 DEBUG 級,而正式運營時,則設爲 NOTICE ; 
必定要顯示出來的信息則能夠用 NOTICE 或以上級別; 
跟蹤函數運行痕跡的信息用 INFO 級別; 
運行時調試的信息用 DEBUG 級別; 

舉例說明 
1 void initialize(int argc, char* argv[])
2 {
3   log.info("initialize() : argc=%d", argc);
4   for (int i=0; i < argc; ++i)
5   {
6     log.debug("initialize() : argv[%d]=%s", i, argv[i]);
7   }
8   log.notice("initialize() : done");
9 }

 

log4cpp 的 category 分爲 rootCategory 和其它自定義的 category。 
而每一個 category 均可以輸出到多個 appender。而且 category 也是有包含關係的。 
例如 rootCategory 就是全部 category 的根。而自定義的 category 也能夠在配置文件中定義其包含關係。 
先看一個 rootCategory 的配置 
log4cpp.rootCategory=DEBUG, console, sample 
這個定義裏,指定了 rootCategory 的 log 優先級是 DEBUG,其 appender 有 2 個,分別是 console 和 sample。
便是說,等號右邊內容以逗號分隔,第一項是優先級別,接下來的都是 appender 名字,能夠有一個或多個。 
如今來看看自定義的 category 
log4cpp.category.demo=DEBUG, sample 
這裏定義了一個名字爲 demo 的 category,其優先級爲 DEBUG,appender 爲 sample。 
注意, category 和 appender 名字能夠徹底相同。 
再來看看有包含關係的 category 的定義 
log4cpp.category.demo.son=DEBUG, son 
log4cpp.category.demo.daughter=DEBUG, daughter 

以上定義了 2 個 category,名字分別爲 son 和 daughter,其父 category 爲 demo。 
son 產生的 log 會寫到 son 和 demo 的 appender 中。同理,daughter 的 log 會寫到 daughter 和 demo 的 appender 中。 
如今來看看 appender 的定義。appender 有不少種,我這裏只介紹幾種,分別是 
ConsoleAppender : 控制檯輸出,即 std::cout 
Win32DebugAppender : VC IDE 的輸出,即 ::OutputDebugString 
FileAppender : 文件輸出 
RollingFileAppender : 回滾文件輸出,對多個日誌文件0,..., n-1,依次記錄滿後,回滾至第0個文件開始記錄。 
如今看一個 ConsoleAppender 的例子 
log4cpp.appender.console=ConsoleAppender 
log4cpp.appender.console.layout=PatternLayout 
log4cpp.appender.console.layout.ConversionPattern=%d [%p] - %m%n 

以上信息解釋爲:一個名爲 console 的 appender,其類型爲 ConsoleAppender,即 控制檯輸出 log 輸出的佈局是 指定的樣式 
輸出的格式 是 "%d [%p] - %m%n" 

ConversionPattern 參數解讀,參閱源碼 log4cpp-0.3.5rc3\src\PatternLayout.cpp app

%m log message 內容, 即 用戶寫 log 的具體信息 
%n 回車換行 
%c category 名字 
%d 時間戳 
%p 優先級 
%r 距離上一次寫 log 的間隔, 單位毫秒 
%R 距離上一次寫 log 的間隔, 單位秒 
%t 線程名 
%u 處理器時間 
%x NDC ? 
竊覺得,如下格式就足夠了,即輸出 "時間 [線程名] 優先級 - log內容 回車換行" 
%d [%t] %p - %m%n 

再看一個 FileAppender 的例子 
log4cpp.appender.sample=FileAppender 
log4cpp.appender.sample.fileName=sample.log 
log4cpp.appender.sample.layout=PatternLayout 
log4cpp.appender.sample.layout.ConversionPattern=%d [%p] - %m%n 

以上信息解釋爲:一個名爲 sample 的 appender,其類型爲 FileAppender,即 文件輸出指定的 log 文件名爲 sample.log,輸出的佈局是 指定的樣式,輸出的格式 是 "%d [%p] - %m%n" 
對應 category 和 appender 的配置方式,能夠發現 
category 是 "log4cpp.category." + "category name" 
category 名字能夠用 "." 分隔,以標識包含關係 
appender 是 "log4cpp.appender." + "appender name" 
appender 名字 不能 用 "." 分隔,便是說 appender 是沒有包含關係的 
如今看一個完整的配置文件例子 
 
#定義 root category 的屬性 
log4cpp.rootCategory=DEBUG, console 

#定義 console 屬性 
log4cpp.appender.console=ConsoleAppender 
log4cpp.appender.console.layout=PatternLayout 
log4cpp.appender.console.layout.ConversionPattern=%d [%p] - %m%n 

#定義 sample category 的屬性 
log4cpp.category.sample=DEBUG, sample 

#定義 sample appender 的屬性 
log4cpp.appender.sample=FileAppender 
log4cpp.appender.sample.fileName=sample.log 
log4cpp.appender.sample.layout=PatternLayout 
log4cpp.appender.sample.layout.ConversionPattern=%d [%p] - %m%n 

#定義 sample.son category 的屬性 
log4cpp.category.sample.son=DEBUG, son 

#定義 son appender 的屬性 
log4cpp.appender.son=FileAppender 
log4cpp.appender.son.fileName=son.log 
log4cpp.appender.son.layout=PatternLayout 
log4cpp.appender.son.layout.ConversionPattern=%d [%p] - %m%n 

#定義 sample.daughter category 的屬性 
log4cpp.category.sample.daughter=DEBUG, daughter 

#定義 daughter appender 的屬性 
log4cpp.appender.daughter=FileAppender 
log4cpp.appender.daughter.fileName=daughter.log 
log4cpp.appender.daughter.layout=PatternLayout 
log4cpp.appender.daughter.layout.ConversionPattern=%d [%p] - %m%n 

 

配置的知識就差很少了,如今看看實際代碼應用 
首先是初始化 log4cpp 的配置,例如個人配置文件名是 log4cpp.properties 
 
1 try
2 {
3   log4cpp::PropertyConfigurator::configure("log4cpp.properties");
4 }
5 catch (log4cpp::ConfigureFailure & f)
6 {
7   std::cerr << "configure problem " << f.what() << std::endl;
8 }

 

初始化完成後,就能夠這樣用了(具體的應用技巧,你本身摸索吧) 
 
 1 log4cpp::Category & log = log4cpp::Category::getInstance(std::string("sample"));
 2 log.debug("test debug log");
 3 log.info("test info log");
 4  
 5 // 用 sample.son
 6 log4cpp::Category & log = log4cpp::Category::getInstance(std::string("sample.son"));
 7 log.debug("test debug log of son");
 8 log.info("test info log of son");
 9 
10 // 用 sample.daughter
11 log4cpp::Category & log = log4cpp::Category::getInstance(std::string("sample.daughter"));
12 log.debug("test debug log of daughter");
13 log.info("test info log of daughter");

 

再舉一個在自定義類中的使用 
 
#include <log4cpp/Category.hh>
namespace demo
{
  class Sample
  {
  public:
    Sample();
    ~Sample();
  public:
    Testing(int i);
  private:
    static log4cpp::Category & log;
  };
}
#include "Sample.h"

namespace demo
{
  log4cpp::Category & Sample::log = log4cpp::Category::getInstance(std::string("sample"));

  Sample::Sample()
  {
    log.debug("Sample::Sample()");
  }

  Sample::~Sample()
  {
    log.debug("Sample::~Sample()");
  }

  Sample::Testing(int i)
  {
    log.debug("Sample::Testing() : i=%d", i);
  }
}
轉載文章:  1. 便利的開發工具-log4cpp快速使用指南(http://www.ibm.com/developerworks/cn/linux/l-log4cpp/index.html)  2. example of log4cpp properties configuration(http://blog.chinaunix.net/u1/50766/showart_400018.html)
相關文章
相關標籤/搜索