c++日志庫log4cplus快速入門小結(jié)
簡介
log4j 用于Java,log4cplus從它衍生而來,用于c++。
用于c++的日志庫還有很多,如 log4cxx等,可以根據(jù)實(shí)際需求選擇使用。
log4cplus 的地址:https://github.com/log4cplus/log4cplus。
log4cplus是一種易于使用的C ++日志記錄API,可提供線程安全,靈活且任意粒度的日志管理和配置控制。
本文旨在快速使用。
日志等級(jí)
log4cplus 提供的日志等級(jí)如下:
ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
舉例來說,
- 如果定義了日志等級(jí)為 ERROR,那么只有標(biāo)記為 ERROR, FATAL的日志信息才會(huì)被記錄
- 如果等級(jí)為 DEBUG,則所有標(biāo)記為 DEBUG/INFO/WARN/ERROR/FATAL 的日志才會(huì)被記錄
- ALL和OFF級(jí)別用來將所有其他類型的級(jí)別分別切換為打開或關(guān)閉的標(biāo)志,不會(huì)用于設(shè)置日志級(jí)別
配置文件
關(guān)于配置文件,說明幾點(diǎn):
- 日志輸出到 appenders,appenders 可以是文件或者控制臺(tái),可以把輸出當(dāng)作cpp流的概念
- 一個(gè)日志類別可以關(guān)聯(lián)到多個(gè) appenders
- 所有的日志類別都是從抽象 root 類繼承日志級(jí)別和 appender,除非另行定義
- 支持記錄工作線程的id,用來分析線程行為
下面是一個(gè)配置文件的示例:
# 文件名:log4cplus.config
###################################
########Define log Levels##########
###################################
# 告警級(jí)別由低到高排序: TRACE DEBUG INFO WARN ERROR FATAL
#All classes - except those in log4cplus.logger.* - use DEBUG level to print information on file
log4cplus.rootLogger=WARN, MyFileAppender
#For MemoryCheck class I need to inspect all the details, and I want print information even to the console
log4cplus.logger.MemoryCheck=INFO, MyConsoleAppender
#For database stuff, I don't need to logging everything, it's enough printing only errors!
log4cplus.logger.DatabaseOperations=ERROR
###################################
########Define the Appenders#######
###################################
#MyConsoleAppender:
log4cplus.appender.MyConsoleAppender=log4cplus::ConsoleAppender
log4cplus.appender.MyConsoleAppender.layout=log4cplus::PatternLayout
log4cplus.appender.MyConsoleAppender.layout.ConversionPattern=[%-5p][%d] %m%n
#MyFileAppender
log4cplus.appender.MyFileAppender=log4cplus::RollingFileAppender
log4cplus.appender.MyFileAppender.File=logging.txt
log4cplus.appender.MyFileAppender.MaxFileSize=16MB
log4cplus.appender.MyFileAppender.MaxBackupIndex=1
log4cplus.appender.MyFileAppender.layout=log4cplus::PatternLayout
log4cplus.appender.MyFileAppender.layout.ConversionPattern=[%-5p][%D{%Y/%m/%d %H:%M:%S:%q}][%-l][%t] %m%n
其中,
- 每個(gè)logger可以添加級(jí)別和apppender,分別為第一個(gè)參數(shù)和第二個(gè)參數(shù)
- MemoryCheck和DatabaseOperations都繼承rootLogger的屬性,但它們各自的定義會(huì)與root共存,如 MemoryCheck 會(huì)打印 info 級(jí)別以上日志,并且同時(shí)輸出到文件和控制臺(tái)
- 直接使用根節(jié)點(diǎn):
Logger logger = Logger::getRoot(); - 每個(gè) apppender 可以設(shè)置日志輸出位置、路徑、layout等內(nèi)容
- appender輸出位置的輸出位置可以是控制臺(tái)、文件,其中文件可以是 FileAppender / RollingFileAppender / DailyRollingFileAppender / TimeBasedRollingFileAppender
- layout是控制日志輸出格式的,格式有三種類型:
- SimpleLayout 是一種簡單格式的布局器,在輸出的原始信息之前加上LogLevel和一個(gè)"-"
- TTCCLayout 其格式由時(shí)間,線程ID,Logger和NDC 組成
- PatternLayout 是一種有詞法分析功能的模式布局器,類似正則表達(dá)式。以“%”作為開頭的特殊預(yù)定義標(biāo)識(shí)符,將產(chǎn)生特殊的格式信息,如下:
(1)"%%",轉(zhuǎn)義為% 。
(2)"%c",輸出logger名稱,如test.subtest 。也可以控制logger名稱的顯示層次,比如"%c{1}"時(shí)輸出"test",其中數(shù)字表示層次。
(3)"%D",顯示本地時(shí)間,比如:"2004-10-16 18:55:45",%d顯示標(biāo)準(zhǔn)時(shí)間。
可以通過%d{...}定義更詳細(xì)的顯示格式,比如%d{%H:%M:%s}表示要顯示小時(shí):分鐘:秒。大括號(hào)中可顯示的預(yù)定義標(biāo)識(shí)符如下:
%a -- 表示禮拜幾,英文縮寫形式,比如"Fri"
%A -- 表示禮拜幾,比如"Friday"
%b -- 表示幾月份,英文縮寫形式,比如"Oct"
%B -- 表示幾月份,"October"
%c -- 標(biāo)準(zhǔn)的日期+時(shí)間格式,如"Sat Oct 16 18:56:19 2004"
%d -- 表示今天是這個(gè)月的幾號(hào)(1-31)"16"
%H -- 表示當(dāng)前時(shí)刻是幾時(shí)(0-23),如"18"
%I -- 表示當(dāng)前時(shí)刻是幾時(shí)(1-12),如"6"
%j -- 表示今天是哪一天(1-366),如"290"
%m -- 表示本月是哪一月(1-12),如"10"
%M -- 表示當(dāng)前時(shí)刻是哪一分鐘(0-59),如"59"
%p -- 表示現(xiàn)在是上午還是下午,AM or PM
%q -- 表示當(dāng)前時(shí)刻中毫秒部分(0-999),如"237"
%Q -- 表示當(dāng)前時(shí)刻中帶小數(shù)的毫秒部分(0-999.999),如 "430.732"
%S -- 表示當(dāng)前時(shí)刻的多少秒(0-59),如"32"
%U -- 表示本周是今年的第幾個(gè)禮拜,以周日為第一天開始計(jì)算(0-53),如 "41"
%w -- 表示禮拜幾,(0-6, 禮拜天為0),如"6"
%W -- 表示本周是今年的第幾個(gè)禮拜,以周一為第一天開始計(jì)算(0-53),如 "41"
%x -- 標(biāo)準(zhǔn)的日期格式,如"10/16/04"
%X -- 標(biāo)準(zhǔn)的時(shí)間格式,如"19:02:34"
%y -- 兩位數(shù)的年份(0-99),如"04"
%Y -- 四位數(shù)的年份,如"2004"
%Z -- 時(shí)區(qū)名,比如"GMT"
(4)"%F",輸出當(dāng)前記錄器所在的文件名稱,比如"main.cpp"
(5)"%L",輸出當(dāng)前記錄器所在的文件行號(hào),比如"51"
(6)"%l",輸出當(dāng)前記錄器所在的文件名稱和行號(hào),比如"main.cpp:51"
(7)"%m",輸出原始信息。
(8)"%n",換行符。
(9)"%p",輸出LogLevel,比如"DEBUG"
(10)"%t",輸出記錄器所在的線程ID,比如 "1075298944"
(11)"%x",嵌套診斷上下文NDC (nested diagnostic context) 輸出,從堆棧中彈出上下文信息,NDC可以用對(duì)不同源的log信息(同時(shí)地)交叉輸出進(jìn)行區(qū)分。
(12)格式對(duì)齊,比如"%-10m"時(shí)表示左對(duì)齊,寬度是10,當(dāng)然其它的控制字符也可以相同的方式來使用,比如"%-12d","%-5p"等等。
log4cplus提供一個(gè)類【PropertyConfigurator】來實(shí)現(xiàn)從文件讀取配置,參數(shù)就是文件名。其他參數(shù)采用默認(rèn),初始化時(shí)使用。
使用
關(guān)于初始化
使用前必須初始化,代碼如下:
#include <log4cplus/logger.h>
#include <log4cplus/configurator.h>
{
log4cplus::initialize();
log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("log4cplus.config"));
}
可以把這段代碼放在main的開頭,或者專門用來做初始化的類中。總之,在使用 Log4cplus 的實(shí)例前,必須初始化。
使用示例
如下代碼:
#include <string>
#include <log4cplus/logger.h>
#include <log4cplus/configurator.h>
#include <log4cplus/loggingmacros.h>
using namespace log4cplus;
using namespace std;
int main()
{
log4cplus::initialize();
log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("log4cplus.config"));
log4cplus::Logger m_log = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("MemoryCheck"));
try
{
int x = 8;
double y = 8.88;
string allocated_memory = "here";
LOG4CPLUS_DEBUG(m_log, "x = " << x);
LOG4CPLUS_DEBUG(m_log, "y = " << y);
/* ... */
LOG4CPLUS_INFO(m_log, "Allocated = " << allocated_memory);
}
catch (std::bad_alloc &e)
{
/* I KNOW HOW TO DEAL WITH THIS ERROR!! */
/* ...code that handle the error is here... */
LOG4CPLUS_ERROR(m_log, e.what());
}
catch (std::exception &e)
{
/* I KNOW HOW TO DEAL WITH THIS ERROR!! */
/* ...code that handle the error is here... */
LOG4CPLUS_ERROR(m_log, e.what());
}
catch (...)
{
/* I DON'T KNOW HOW MANAGE THE ERROR!! */
LOG4CPLUS_FATAL(m_log, "unexpected error...use gdb core dump");
exit(-1);
}
int memory_remaining = 122;
if (memory_remaining < 123)
{
LOG4CPLUS_WARN(m_log, "LOW MEMORY!!");
}
return 0;
}
因?yàn)?MemoryCheck 自己定義了 日志級(jí)別和 appender,它又從 rootlogger繼承,所以,最終它的日志級(jí)別為 INFO,日志同時(shí)輸出到控制臺(tái)和文件中。
輸出結(jié)果如下:

完整代碼及編譯請(qǐng)移步:log4cplus_demo
以上代碼應(yīng)該不用過多解釋,從中可知各個(gè)日志等級(jí)的使用方式:
- TRACE:調(diào)試應(yīng)用的詳細(xì)步驟
- DEBUG:算法關(guān)鍵部分的相關(guān)信息
- INFO:應(yīng)用的內(nèi)部狀態(tài)信息
- WARN:可以避免的內(nèi)部狀態(tài)信息
- ERROR:發(fā)生了錯(cuò)誤,且應(yīng)用程序知道如何處理它
- FATAL:發(fā)生了不可逆轉(zhuǎn)的錯(cuò)誤,程序無法繼續(xù)運(yùn)行
當(dāng)然,以上分類只是根據(jù)項(xiàng)目需求,具體的日志級(jí)別分類應(yīng)該結(jié)合實(shí)際需要,以及相對(duì)應(yīng)的處理策略。
總結(jié)
以上介紹了Log4cplus 的基礎(chǔ)使用,里面很多靈活地配置可以在使用中逐步了解。
總之,使用它可以簡單便捷地建立起日志體系,步驟如下:
- 建立配置文件
- 初始化
- 開始使用
參考資料
到此這篇關(guān)于c++日志庫log4cplus快速入門的文章就介紹到這了,更多相關(guān)c++日志庫log4cplus內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
簡要對(duì)比C語言中的dup()函數(shù)和dup2()函數(shù)
這篇文章主要介紹了簡要對(duì)比C語言中的dup()函數(shù)和dup2()函數(shù),是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-08-08
使用C++開發(fā)一個(gè)串口讀寫軟件的實(shí)現(xiàn)步驟
這篇文章主要介紹了使用xmake(一個(gè)項(xiàng)目管理工具兼包管理工具)和asio2(一個(gè)asio的框架,可以實(shí)現(xiàn)輕松各種網(wǎng)絡(luò)應(yīng)用,一般支持tcp,udp,http,websocket,rpc,ssl,icmp,serial_port.)來快速的開發(fā)個(gè)串口讀寫軟件(整合例程),需要的朋友可以參考下2025-04-04
C++中signed?main和int?main的區(qū)別
這篇文章介紹了C++中signed?main和int?main的區(qū)別,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-12-12
C++中字符串的反轉(zhuǎn)與去重實(shí)現(xiàn)方式
本文介紹了兩種字符串反轉(zhuǎn)方法:雙指針法和reverse()函數(shù),同時(shí)給出了字符串去重的兩種方法:使用bool數(shù)組記錄字符出現(xiàn)情況和先排序再刪除重復(fù)元素,這些都是編程中的常用操作2026-04-04
C語言/C++中如何產(chǎn)生隨機(jī)數(shù)
這里要用到的是rand()函數(shù), srand()函數(shù),和time()函數(shù)。需要說明的是,iostream頭文件中就有srand函數(shù)的定義,不需要再額外引入stdlib.h;而使用time()函數(shù)需要引入ctime頭文件2013-10-10

