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類輸出日志信息到別的設備上,比如應用自身的
日子處理進程、數據庫等。appender和layout的關系是layout附在appender上,
appender類調用layout處理完日志消息后,記錄到某個設備上。log4cpp當前
提供以下appender:
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(),有
關於優先級別使用的建議
開發運行時,設為 DEBUG 級,而正式運營時,則設為 NOTICE ;
一定要顯示出來的信息則可以用 NOTICE 或以上級別;
跟蹤函數運行痕跡的信息用 INFO 級別;
運行時調試的信息用 DEBUG 級別;
舉例說明
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 : 有待研究
現在看一個 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" (稍后再解釋)
再看一個 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
ConversionPattern 參數解讀,參閱源碼 log4cpp-0.3.5rc3\src\PatternLayout.cpp
%m log message 內容, 即 用戶寫 log 的具體信息
%n 回車換行
%c category 名字
%d 時間戳
%p 優先級
%r 距離上一次寫 log 的間隔, 單位毫秒
%R 距離上一次寫 log 的間隔, 單位秒
%t 線程名
%u 處理器時間
%x NDC ?
竊以為,以下格式就足夠了,即輸出 "時間 [線程名] 優先級 - log內容 回車換行"
%d [%t] %p - %m%n
配置的知識就差不多了,現在看看實際代碼應用
首先是初始化 log4cpp 的配置,例如我的配置文件名是 log4cpp.properties
初始化完成后,就可以這樣用了(具體的應用技巧,你自己摸索吧)
再舉一個在自定義類中的使用
轉載文章:
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)
log4cpp::BasicLayout // 以“時間戳 優先級(priority,下文介紹)
// 類別(category,下文介紹)
// NDC標簽
log4cpp::PatternLayout // 讓用戶根據類似於 C 語言 printf 函數的轉換模式來指定輸出格式。
log4cpp::SimpleLayout // 以“優先級(priority) - 日志信息”格式顯示。
appender類用來輸出日志(被layout格式化后的)到一些設備上。比如文件、syslog服務、
某個socket等。可以定義自己的appender類輸出日志信息到別的設備上,比如應用自身的
日子處理進程、數據庫等。appender和layout的關系是layout附在appender上,
appender類調用layout處理完日志消息后,記錄到某個設備上。log4cpp當前
提供以下appender:
- log4cpp::IdsaAppender // 發送到IDS或者logger,
- log4cpp::FileAppender // 輸出到文件
- log4cpp::RollingFileAppender // 輸出到回卷文件,即當文件到達某個大小后回卷
- log4cpp::OstreamAppender // 輸出到一個ostream類
- log4cpp::RemoteSyslogAppender // 輸出到遠程syslog服務器
- log4cpp::StringQueueAppender // 內存隊列
- log4cpp::SyslogAppender // 本地syslog
- log4cpp::Win32DebugAppender // 發送到缺省系統調試器
- 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(),有
- void debug(const char* stringFormat, ...) throw();
- void debug(const std::string& message) throw();
關於優先級別使用的建議
開發運行時,設為 DEBUG 級,而正式運營時,則設為 NOTICE ;
一定要顯示出來的信息則可以用 NOTICE 或以上級別;
跟蹤函數運行痕跡的信息用 INFO 級別;
運行時調試的信息用 DEBUG 級別;
舉例說明
- void initialize(int argc, char* argv[])
- {
- log.info("initialize() : argc=%d", argc);
- for (int i=0; i < argc; ++i)
- {
- log.debug("initialize() : argv[%d]=%s", i, argv[i]);
- }
- log.notice("initialize() : done");
- }
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 : 有待研究
現在看一個 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" (稍后再解釋)
再看一個 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
ConversionPattern 參數解讀,參閱源碼 log4cpp-0.3.5rc3\src\PatternLayout.cpp
%m log message 內容, 即 用戶寫 log 的具體信息
%n 回車換行
%c category 名字
%d 時間戳
%p 優先級
%r 距離上一次寫 log 的間隔, 單位毫秒
%R 距離上一次寫 log 的間隔, 單位秒
%t 線程名
%u 處理器時間
%x NDC ?
竊以為,以下格式就足夠了,即輸出 "時間 [線程名] 優先級 - log內容 回車換行"
%d [%t] %p - %m%n
配置的知識就差不多了,現在看看實際代碼應用
首先是初始化 log4cpp 的配置,例如我的配置文件名是 log4cpp.properties
- try
- {
- log4cpp::PropertyConfigurator::configure("log4cpp.properties");
- }
- catch (log4cpp::ConfigureFailure & f)
- {
- std::cerr << "configure problem " << f.what() << std::endl;
- }
初始化完成后,就可以這樣用了(具體的應用技巧,你自己摸索吧)
- log4cpp::Category & log = log4cpp::Category::getInstance(std::string("sample"));
- log.debug("test debug log");
- log.info("test info log");
- // 用 sample.son
- log4cpp::Category & log = log4cpp::Category::getInstance(std::string("sample.son"));
- log.debug("test debug log of son");
- log.info("test info log of son");
- // 用 sample.daughter
- log4cpp::Category & log = log4cpp::Category::getInstance(std::string("sample.daughter"));
- log.debug("test debug log of daughter");
- 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)