如何控制輸出訊息的格式
前面已經講過,log4cplus通過布局器(Layouts)來控制輸出的格式,log4cplus提供了三種類型的Layouts,
分別是SimpleLayout、PatternLayout、和TTCCLayout。
1. SimpleLayout
是一種簡單格式的布局器,在輸出的原始資訊之前加上LogLevel和一個"-"。
比如以下程式碼片段:
/* step 1: Instantiate an appender object */
//appender的名字就是最後產生的log的檔案名稱.
SharedObjectPtr _append (new ConsoleAppender());
_append->setName("append for test");
/* step 2: Instantiate a layout object */
std::auto_ptr< log4cplus::SimpleLayout> _layout(new log4cplus::SimpleLayout());
/* step 3: Attach the layout object to the appender */
_append->setLayout( _layout );
/* step 4: Instantiate a logger object */
Logger _logger = Logger::getInstance("test");
/* step 5: Attach the appender object to the logger */
_logger.addAppender(_append);
/* log activity */
LOG4CPLUS_DEBUG(_logger, "This is the simple formatted log message...")
... ...
將列印結果:
DEBUG - This is the simple formatted log message...
2. PatternLayout
是一種有詞法分析功能的模式布局器,一提起模式就會想起Regex,這裡的模式和Regex類似,但是
遠比後者簡單,能夠對預定義的標識符(稱為conversion specifiers)進行解析,轉換成特定格式輸出。以下
程式碼片段示範了如何使用PatternLayout:
... ...
/* step 1: Instantiate an appender object */
SharedObjectPtr _append (new ConsoleAppender());
_append->setName("append for test");
/* step 2: Instantiate a layout object */
std::string pattern = "%d{%m/%d/%y %H:%M:%S} - %m [%l]%n";
std::auto_ptr<PatternLayout> _layout(new PatternLayout(pattern));
/* step 3: Attach the layout object to the appender */
_append->setLayout( _layout );
/* step 4: Instantiate a logger object */
Logger _logger = Logger::getInstance("test_logger.subtest");
/* step 5: Attach the appender object to the logger */
_logger.addAppender(_append);
/* log activity */
LOG4CPLUS_DEBUG(_logger, "teststr")
... ...
輸出結果:
10/16/04 18:51:25 - teststr [main.cpp:51]
可以看出通過填寫特定格式的模式字串"pattern",原始資訊被包含到一堆有格式的資訊當中了,這就使得
使用者可以根據自身需要來定製顯示內容。"pattern"可以包含一般字元串和預定義的標識符,其中:
(1)一般字元串,能夠被直接顯示的資訊。
(2)預定義標識符,通過"%"與一個或多個字元共同構成預定義的標識符,能夠產生出特定格式資訊。
關於預定義標識符,log4cplus文檔中提供了詳細的格式說明,我每種都試了一下,以上述代碼為例,根據不同
的pattern,各種訊息格式使用方式列舉如下:
(1)"%%",轉義為%, 即,std::string pattern = "%%" 時輸出: "%"
(2)"%c",輸出logger名稱,比如std::string pattern ="%c" 時輸出: "test_logger.subtest",
也可以控制logger名稱的顯示層次,比如"%c{1}"時輸出"test_logger",其中數字展示層次。
(3)"%D",顯示本地時間,當std::string pattern ="%D" 時輸出:"2004-10-16 18:55:45",%d顯示標準時間,
所以當std::string pattern ="%d" 時輸出 "2004-10-16 10:55:45" (因為我們是東8區,差8個小時啊)。
可以通過%d{...}定義更詳細的顯示格式,比如%d{%H:%M:%s}表示要顯示小時:分鐘:秒。大括弧中可顯示的
預定義標識符如下:
%a -- 表示禮拜幾,英文縮寫形式,比如"Fri"
%A -- 表示禮拜幾,比如"Friday"
%b -- 表示幾月份,英文縮寫形式,比如"Oct"
%B -- 表示幾月份,"October"
%c -- 標準的日期+時間格式,如 "Sat Oct 16 18:56:19 2004"
%d -- 表示今天是這個月的幾號(1-31)"16"
%H -- 表示當前時刻是幾時(0-23),如 "18"
%I -- 表示當前時刻是幾時(1-12),如 "6"
%j -- 表示今天是哪一天(1-366),如 "290"
%m -- 表示本月是哪一月(1-12),如 "10"
%M -- 表示當前時刻是哪一分鐘(0-59),如 "59"
%p -- 表示現在是上午還是下午, AM or PM
%q -- 表示當前時刻中毫秒部分(0-999),如 "237"
%Q -- 表示當前時刻中帶小數的毫秒部分(0-999.999),如 "430.732"
%S -- 表示當前時刻的多少秒(0-59),如 "32"
%U -- 表示本周是今年的第幾個禮拜,以周日為第一天開始計算(0-53),如 "41"
%w -- 表示禮拜幾,(0-6, 禮拜天為0),如 "6"
%W -- 表示本周是今年的第幾個禮拜,以周一為第一天開始計算(0-53),如 "41"
%x -- 標準的日期格式,如 "10/16/04"
%X -- 標準的時間格式,如 "19:02:34"
%y -- 兩位元的年份(0-99),如 "04"
%Y -- 四位元的年份,如 "2004"
%Z -- 時區名,比如 "GMT"
(4)"%F",輸出目前記錄器所在的檔案名稱,比如std::string pattern ="%F" 時輸出: "main.cpp"
(5)"%L",輸出目前記錄器所在的檔案行號,比如std::string pattern ="%L" 時輸出: "51"
(6)"%l",輸出目前記錄器所在的檔案名稱和行號,比如std::string pattern ="%L" 時輸出:
"main.cpp:51"
(7)"%m",輸出原始資訊,比如std::string pattern ="%m" 時輸出: "teststr",即上述代碼中
LOG4CPLUS_DEBUG的第二個參數,這種實現機制可以確保原始資訊被嵌入到帶格式的資訊中。
(8)"%n",分行符號,沒什麼好解釋的
(9)"%p",輸出LogLevel,比如std::string pattern ="%p" 時輸出: "DEBUG"
(10)"%t",輸出記錄器所在的線程ID,比如std::string pattern ="%t" 時輸出: "1075298944"
(11)"%x",嵌套診斷上下文NDC (nested diagnostic context) 輸出,從堆棧中彈出上下文資訊,NDC可以用對
不同源的log資訊(同時地)交叉輸出進行區分,關於NDC方面的詳細介紹會在下文中提到。
(12)格式對齊,比如std::string pattern ="%-10m"時表示靠左對齊,寬度是10,此時會輸出"teststr ",當
然其它的控制字元也可以相同的方式來使用,比如"%-12d","%-5p"等等(剛接觸log4cplus文檔時還以為
"%-5p"整個字串代表LogLevel呢,呵呵)。
3. TTCCLayout
是在PatternLayout基礎上發展的一種預設的帶格式輸出的布局器, 其格式由時間,線程ID,Logger和NDC 組
成(consists of time, thread, Logger and nested diagnostic context information, hence the name),
因而得名(怎麼得名的?Logger裡哪裡有那個"C"的縮寫啊!名字起得真夠爛的,想扁人)。提供給那些想顯示
典型的資訊(一般情況下夠用了)又懶得配置pattern的同志們。
TTCCLayout在構造時有機會選擇顯示本地時間或GMT時間,預設是按照本地時間顯示:
TTCCLayout::TTCCLayout(bool use_gmtime = false)
以下程式碼片段示範了如何使用TTCCLayout:
/* step 1: Instantiate an appender object */
SharedObjectPtr _append (new ConsoleAppender());
_append->setName("append for test");
/* step 2: Instantiate a layout object */
std::auto_ptr _layout(new TTCCLayout());
/* step 3: Attach the layout object to the appender */
_append->setLayout( _layout );
/* step 4: Instantiate a logger object */
Logger _logger = Logger::getInstance("test_logger");
/* step 5: Attach the appender object to the logger */
_logger.addAppender(_append);
/* log activity */
LOG4CPLUS_DEBUG(_logger, "teststr")
... ...
輸出結果:
10-16-04 19:08:27,501 [1075298944] DEBUG test_logger <> - teststr
當構造TTCCLayout對象時選擇GMT時間格式時:
std::auto_ptr _layout(new TTCCLayout(true));
... ...
輸出結果:
10-16-04 11:12:47,678 [1075298944] DEBUG test_logger <> - testst
本文介紹了控制log資訊格式的相關知識,下一部分將詳細介紹log資訊的幾種檔案操作方式。