一.如何將日志寫入到文件
將log信息記錄到文件應該說是日志系統的一個基本功能,log4cplus在此基礎上,提供了更多的功能,
可以按照你預先設定的大小來決定是否轉儲,當超過該大小,后續log信息會另存到新文件中,
依次類推;或者按照日期來決定是否轉儲。log4cplus提供了三個類用于文件操作,它們是:
FileAppender類、RollingFileAppender類、DailyRollingFileAppender類
二.FileAppender類
實現了基本的文件操作功能,構造函數如下:
FileAppender(const log4cplus::tstring& filename,
LOG4CPLUS_OPEN_MODE_TYPE mode = LOG4CPLUS_FSTREAM_NAMESPACE::ios::trunc,
bool immediateFlush = true);
filename: 文件名
mode : 文件類型,可選擇的文件類型包括app、ate、binary、in、out、trunc,
因為實際上只是對stl的一個簡單包裝,缺省是trunc,表示將先前文件刪除。
immediateFlush :緩沖刷新標志,如果為true表示每向文件寫一條記錄就刷新一次緩存,
否則直到FileAppender被關閉或文件緩存已滿才更新文件,一般是要設置true的,
比如你往文件寫的過程中出現了錯誤(如程序非正常退出),即使文件沒有正常關閉也可以保證程序終
止時刻之前的所有記錄都會被正常保存。
三. RollingFileAppender類
構造函數如下:
log4cplus::RollingFileAppender::RollingFileAppender(
const log4cplus::tstring& filename,
long maxFileSize,
int maxBackupIndex,
bool immediateFlush)
filename : 文件名
maxFileSize : 文件的最大尺寸
maxBackupIndex : 最大記錄文件數
immediateFlush : 緩沖刷新標志
RollingFileAppender類可以根據你預先設定的大小來決定是否轉儲,當超過該大小,后續log信息會另存到新文件中,
除了定義每個記錄文件的大小之外,你還要確定在RollingFileAppender類對象構造時最多需要多少個這樣的記錄文件
(maxBackupIndex+1),當存儲的文件數目超過maxBackupIndex+1時,會刪除最早生成的文件,保證整個文件數目等于
maxBackupIndex+1。然后繼續記錄,比如以下代碼片段:

#define LOOP_COUNT 200000
SharedAppenderPtr _append(new RollingFileAppender("Test.log", 5*1024, 5));
_append->setName("file test");
_append->setLayout( std::auto_ptr(new TTCCLayout()) );
Logger::getRoot().addAppender(_append);
Logger root = Logger::getRoot();
Logger test = Logger::getInstance("test");
Logger subTest = Logger::getInstance("test.subtest");

for(int i=0; i<1000;i++)
{
NDCContextCreator _context("loop");
LOG4CPLUS_DEBUG(subTest, "Entering loop #" << i)
}
運行結果:運行后會產生6個輸出文件,Test.log、Test.log.1、Test.log.2、Test.log.3、Test.log.4、Test.log.5
其中Test.log存放著最新寫入的信息,而最后一個文件中并不包含第一個寫入信息,說明已經被不斷更新了。
需要指出的是,這里除了Test.log之外,每個文件的大小都是200K,而不是我們想像中的5K,
這是因為log4cplus中隱含定義了文件的最小尺寸是200K,只有大于200K的設置才生效,<= 200k的設置都會被認為是200K.
四. DailyRollingFileAppender類
構造函數如下:
DailyRollingFileAppender::DailyRollingFileAppender(const log4cplus::tstring& filename,
DailyRollingFileSchedule schedule,
bool immediateFlush,
int maxBackupIndex)
filename : 文件名
schedule : 存儲頻度
immediateFlush : 緩沖刷新標志
maxBackupIndex : 最大記錄文件數
DailyRollingFileAppender類可以根據你預先設定的頻度來決定是否轉儲,當超過該頻度,
后續log信息會另存到新文件中,這里的頻度包括:
MONTHLY(每月)、WEEKLY(每周)、DAILY(每日)、TWICE_DAILY(每兩天)、HOURLY(每時)、MINUTELY(每分)。
maxBackupIndex的含義同上所述,比如以下代碼片段:

SharedAppenderPtr _append(new DailyRollingFileAppender("Test.log", MINUTELY, true, 5));
_append->setName("file test");
_append->setLayout( std::auto_ptr(new TTCCLayout()) );
Logger::getRoot().addAppender(_append);
Logger root = Logger::getRoot();
Logger test = Logger::getInstance("test");
Logger subTest = Logger::getInstance("test.subtest");

for(int i=0; i<100;i++)
{
NDCContextCreator _context("loop");
LOG4CPLUS_DEBUG(subTest, "Entering loop #" << i)
}

運行結果:運行后會以分鐘為單位,分別生成名為
Test.log.2004-10-17-03-03、Test.log.2004-10-17-03-04和Test.log.2004-10-17-03-05這樣的文件。
需要指出的是,剛看到按照頻度(如HOURLY、MINUTELY)轉儲這樣的概念,以為log4cplus提供了內部定
時器,感覺很奇怪,因為日志系統不應該主動記錄,而loging事件總是應該被動觸發的啊。仔細看了源
代碼后才知道這里的"頻度"并不是你寫入文件的速度,其實是否轉儲的標準并不依賴你寫入文件的速度,
而是依賴于寫入的那一時刻是否滿足了頻度條件,即是否超過了以分鐘、小時、周、月為單位的時間刻度,
如果超過了就另存。本部分詳細介紹log信息的幾種文件操作方式,下面將重點介紹一下如何有選擇地控
制log信息的輸出。