1. 程式人生 > 其它 >01安裝配置與基本使用

01安裝配置與基本使用

一、介紹

Log4cpp是一個開源的C++類庫,它提供了在C++程式中使用日誌和跟蹤除錯的功能。使用log4cpp,可以很便利地將日誌或者跟蹤除錯資訊寫入字元流、記憶體字串佇列、檔案、回滾檔案、偵錯程式、Windows日誌、本地syslog和遠端syslog伺服器中。

Log4cpp有如下優點:

  • 提供了可擴充套件的多種日誌記錄方式;
  • 提供了NDC(巢狀診斷上下文),可用於多執行緒、多場景的跟蹤除錯;
  • 提供了完整的日誌動態優先順序控制,可隨時調整需要記錄的日誌優先順序
  • 可通過配置檔案完成所有配置並動態載入;
  • 效能優秀,記憶體佔用小,經過編譯後的log4cpp.dll大小僅有160kb;
  • 程式碼級的平臺無關性,Log4cpp原始碼經過編譯後,適用於大多數主流的作業系統和開發工具;
  • 概念清晰,學習和使用方便,熟練程式設計師一天之內即可很好地應用log4cpp進行開發。

Log4cpp的主頁為:http://sourceforge.net/projects/log4cpp/

log4cpp是個基於LGPL的開源項⽬,移植⾃Java的⽇志處理跟蹤項⽬log4j,並保持了API上的⼀致。其類
似的⽀持庫還包括Java(log4j),C++(log4cpp、log4cplus),C(log4c),python(log4p)等。

二、安裝與編譯

這裡使用的是log4cpp-1.1.3版本

#!/bin/bash

tar zxf log4cpp-1.1.3.tar.gz

cd log4cpp
./configure   #其實也就是執行了一個shell指令碼
make
make check
sudo make install # 標頭檔案安裝路徑 /usr/local/include/log4cpp   庫安放位置 /usr/local/lib/
sudo ldconfig

三、使用細節

3.1 包含的內容物件

Log4cpp中最重要概念有Category(種類)、Appender(附加器)、Layout(佈局)、Priorty(優先
級)、NDC(巢狀的診斷上下⽂)

Category、Appender與Layout三者的關係如下圖所示:

3.2 先舉個簡單的例子

#include "log4cpp/Category.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/BasicLayout.hh"

int main(int argc, char *argv[])
{
    // 1. 例項化⼀個layout 物件
    log4cpp::Layout *layout = new log4cpp::BasicLayout();
    // 2. 初始化⼀個appender 物件
    log4cpp::Appender *appender = new log4cpp::FileAppender("File Appender", "./01test.log");
    // 3. 把layout物件附著在appender物件上
    appender->setLayout(layout);
    // 4. 例項化⼀個category物件
    log4cpp::Category &warn_log = log4cpp::Category::getInstance("zh_test");
    // 5. 設定additivity為false,替換已有的appender
    warn_log.setAdditivity(false);
    // 5. 把appender物件附到category上
    warn_log.setAppender(appender);
    // 6. 設定category的優先順序,低於此優先順序的⽇志不被記錄
    warn_log.setPriority(log4cpp::Priority::WARN);

    // 記錄⼀些⽇志
    warn_log.info("Program info which cannot be wirten");
    warn_log.debug("This debug message will fail to write");
    warn_log.alert("Alert info");

    // 其他記錄⽇志⽅式
    warn_log.log(log4cpp::Priority::WARN, "This will be a logged warning");
    
    log4cpp::Priority::PriorityLevel priority;
    bool this_is_critical = true;
    if (this_is_critical)
        priority = log4cpp::Priority::CRIT;
    else
        priority = log4cpp::Priority::DEBUG;
    warn_log.log(priority, "Importance depends on context");

    warn_log.critStream() << "This will show up << as " << 1 << " critical message";
    // clean up and flush all appenders
    log4cpp::Category::shutdown();
    return 0;
}

//編譯指令
// g++ -o 01test 01test.cpp -llog4cpp -lpthread

輸出:

3.3 從配置檔案的方式讀取日誌屬性使用

完整使用範例:
配置檔案:

#定義 root category 的屬性
log4cpp.rootCategory=WARN, console # console是appender物件

#定義 console 屬性
log4cpp.appender.console=ConsoleAppender # ConsoleAppender是控制檯型別
#log4cpp.appender.console.layout=PatternLayout # PatternLayout是模式樣式
#log4cpp.appender.console.layout.ConversionPattern=%d [%p] - %m%n # 格式
log4cpp.appender.console.layout=org.apache.log4cpp.BasicLayout


#定義 sample category 的屬性
log4cpp.category.sample=DEBUG, sample # sample是appender物件
#定義 sample appender 的屬性
log4cpp.appender.sample=FileAppender # 檔案型別
log4cpp.appender.sample.fileName=sample.log # 具體哪個log檔案
log4cpp.appender.sample.layout=PatternLayout
log4cpp.appender.sample.layout.ConversionPattern=%d [%p] - %m%n

# 設定sub1.sub2 的additivity屬性
log4cpp.additivity.sample.son=true
log4cpp.additivity.sample.daughter=true

#定義 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

測試程式:

// g++ -o 03test 03test.cpp -llog4cpp -lpthread

#include "log4cpp/Category.hh"
#include "log4cpp/PropertyConfigurator.hh"
#include "log4cpp/NDC.hh"


void test(log4cpp::Category& category)
{
    log4cpp::NDC::push(__FUNCTION__);     // 記錄NDC資訊
    category.error("zhonghao");
    log4cpp::NDC::pop();
}

int main(int argc, char* argv[])
{
    log4cpp::PropertyConfigurator::configure("./03test_conf.conf");
    log4cpp::Category& root = log4cpp::Category::getRoot();

    log4cpp::Category& sample = log4cpp::Category::getInstance(std::string("sample"));
    log4cpp::Category& sample_son = log4cpp::Category::getInstance(std::string("sample.son"));
    log4cpp::Category& sample_daughter = log4cpp::Category::getInstance(std::string("sample.daughter"));

    log4cpp::NDC::push(__FUNCTION__);     // 記錄NDC資訊,容器中
    test(root); 

    root.info("root.info()");
    sample.info("sample.info()");
    sample_son.info("sample_son.info()");
    sample_daughter.info("sample_daughter.info()");

    root.error("root.error()");
    sample.error("sample.error()");
    sample_son.error("sample_son.error()");
    sample_daughter.error("sample_daughter.error()");

    //其他輸出方式
    sample_daughter.critStream() << "sample_daughter.critStream() << \" \" ";
    sample_daughter << log4cpp::Priority::ERROR << "sample_daughter << log4cpp::Priority::ERROR << \" \";";
    sample_daughter.log(log4cpp::Priority::WARN, "sample_daughter.log(log4cpp::Priority::WARN, \" \");");

    // clean up and flush all appenders
    log4cpp::Category::shutdown();
    return 0;
}

四、⽇志級別

4.1 log 的優先順序

別解讀,參閱原始碼 log4cpp-1.1.3\include\log4cpp\Priority.hh

由⾼到低

EMERG
FATAL
ALERT
CRIT
ERROR
WARN
NOTICE
INFO
DEBUG
NOTSET  

對應到 Category 相應函式,參閱原始碼 log4cpp-1.1.3\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();

4.2 關於優先級別使⽤的建議:

開發運⾏時,設為 DEBUG 級,⽽正式運營時,則設為 NOTICE ;

⼀定要顯示出來的資訊則可以⽤ NOTICE 或以上級別;

跟蹤函式運⾏痕跡的資訊⽤ INFO 級別;

運⾏時除錯的資訊⽤ DEBUG 級別;