log4cpp的使用

逻辑构造

目的地Appender:用于表示日志系统最后输出到哪
布局Layout:表示你输出的格式,类似与printf
优先级Priority:常见的优先级有emerg,alert,crit,error,warn,notice,info,debug,优先级从高到低排列,优先级主要针对不同用户设定,如果一个用户设定的优先级是warn,那么notice,info,debug的信息就会忽略掉不输出
日志Category:是整个日志系统的主干,目的地的设定添加和模板设置,日志记录都由Category完成

一个目的地只能有一个布局,一个布局对应一个目的地

基本模板

#include <iostream>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/Appender.hh>
#include <log4cpp/BasicLayout.hh>
#include <log4cpp/Category.hh>
#include <log4cpp/Priority.hh>

using std::cout;
using namespace log4cpp;

void test0()
{
//设置目的地对象
//参数1 目的地的名字 console代表控制台,
//参数2 流对象
OstreamAppender* posAp = new OstreamAppender("console", &cout);

//设置目的地布局 BasicLayout函数是创建布局对象
posAp->setLayout(new BasicLayout());

//创建日志对象,getRoot函数返回的是创建的日志对象,用引用符号接取
Category& root = Category::getRoot();

//设置日志的目的地
root.setAppender(posAp);
//设置日志的优先级
root.setPriority(Priority::DEBUG);

//设置模板
Category& model1 = root.getInstance("register");

//打印日志记录
root.emerg("this is an emrge");
root.alert("this is an alert");
root.crit("this is a critical");
root.error("this is an error");
root.warn("this is a warn");
root.notice("this is a notice");
root.info("this is an info");
root.debug("this is a debug");

model1.debug("123456");
}
int main()
{
test0();

return 0;
}

输出结果

1684758947 FATAL  : this is an emrge
1684758947 ALERT : this is an alert
1684758947 CRIT : this is a critical
1684758947 ERROR : this is an error
1684758947 WARN : this is a warn
1684758947 NOTICE : this is a notice
1684758947 INFO : this is an info
1684758947 DEBUG : this is a debug
1684758947 DEBUG register : 123456

打印第一列代表时间,单位为秒,第二列为优先级,第三列为模块名,root没有设置所以是空白,最后面为日志内容

布局的格式化

类似于priintf函数,常以%d代表输出十进制,Layout对象也有着类似的表达方式

PatternLayout

setConversionPattern成员函数,PatternLayout的格式化函数
%c 获取模块名
%d 打印日期时间,将第一列时间单位为秒转化为可读性时间
%m 打印消息内容
%p 打印优先级
%n 换行符

#include <iostream>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/Category.hh>
#include <log4cpp/Priority.hh>

using namespace log4cpp;
using std::cout;

void test0()
{
OstreamAppender* posAp = new OstreamAppender("console", &cout);

//设置格式化布局
PatternLayout* ptnLayout = new PatternLayout();
ptnLayout->setConversionPattern("%d [%c] [%p] %m %n");

posAp->setLayout(ptnLayout);

Category& root = Category::getRoot();

root.setAppender(posAp);
root.setPriority(Priority::DEBUG);

Category& model1 = root.getInstance("register");

model1.emerg("this is an emerg");
root.emerg("this is an emerg");

Category::shutdown();
}
int main()
{
test0();
}

输出结果

2023-05-23 18:57:33,748 [register] [FATAL] this is an emerg
2023-05-23 18:57:33,749 [] [FATAL] this is an emerg

目的地对象操作文件

FileAppender

参数列表
参数1 目的地名字
参数2 文件名
参数3 是否以追加模式写入(默认追加)
参数4 文件权限(不写以默认权限为主)
#include <iostream>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/BasicLayout.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/Category.hh>
#include <log4cpp/Priority.hh>

using namespace log4cpp;
using std::cout;

void test0()
{
//两个目的地对象创建,最后一个输出在控制台一个写入到文件中去
OstreamAppender* posAp = new OstreamAppender("console", &cout);
FileAppender* FileAp = new FileAppender("FileAp", "test.log");

PatternLayout* ptnLayout = new PatternLayout();
ptnLayout->setConversionPattern("%d [%c] [%p] %m %n");

//让目的地为控制台的对象打印普通日志信息
//让目的地为文件的对象打印格式化日志信息
posAp->setLayout(new BasicLayout());
FileAp->setLayout(ptnLayout);

Category& root = Category::getRoot();
root.setAppender(posAp);
//追加目的地
root.addAppender(FileAp);
root.setPriority(Priority::DEBUG);

Category& model = root.getInstance("register");

root.emerg("root emerg");
root.alert("root alert");
root.crit("root crit");
root.error("root error");
root.warn("root warn");
root.notice("root notice");
root.info("root info");
root.debug("root debug");

model.emerg("model emerg");
model.debug("model debug");

Category::shutdown();
}
int main()
{
test0();
}

输出结果

1684840653 FATAL  : root emerg
1684840653 ALERT : root alert
1684840653 CRIT : root crit
1684840653 ERROR : root error
1684840653 WARN : root warn
1684840653 NOTICE : root notice
1684840653 INFO : root info
1684840653 DEBUG : root debug
1684840653 FATAL register : model emerg
1684840653 DEBUG register : model debug

同时在该项目目录下可以找到之前生成的文件test.log
在这里插入图片描述
打开后可看到日志内容(我这里生成了两次所以上下时间不同,写入了两次,也可以看出FileAppender默认是以追加模式进行写入的)在这里插入图片描述

回卷文件

RollingFileAppender

应用场景:用于一些对于存储空间要求较高,不希望日志文件占用过多空间
回卷文件说明:假如一次产生连续十个回卷文件,编号为1-10,要求日志文件只能占10M空间,那么每个回卷文件最大大小为1M,当日志信息填入回卷文件1且填满时,会使用回卷文件2继续写入,当10个回卷文件都填满时,会删除最早的回卷文件,重新写入数据,在当前场景下,回卷文件1是最早的一个,于是将他重定向操作,这种结构类似于队列一样,也有着先进先出的特点(再严谨一点是循环队列)

参数列表
参数1 目的地名字
参数2 文件名
参数3 每个文件大小,单位为字节,5000则为5KB
参数4 需要多少个回卷文件

#include <iostream>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/RollingFileAppender.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/BasicLayout.hh>
#include <log4cpp/Category.hh>
#include <log4cpp/Priority.hh>

using namespace log4cpp;
using std::cout;

void test0()
{
//设置三个对象,分别对应控制台,文件,回卷文件
OstreamAppender* posAp = new OstreamAppender("console",&cout);
FileAppender* FileAp = new FileAppender("FileAp","test.log");
RollingFileAppender* RollingFileAp = new RollingFileAppender("RollingFileAp","a.log",5000,10);

PatternLayout* ptnLayout1 = new PatternLayout();
PatternLayout* ptnLayout2 = new PatternLayout();
ptnLayout2->setConversionPattern("%d [%c] [%p] %m %n");
ptnLayout2->setConversionPattern("%d [%c] [%p] %m %n");
//一个目的地只能对应一个布局,一个布局只能对应一个目的地

posAp->setLayout(new BasicLayout());
FileAp->setLayout(ptnLayout1);
RollingFileAp->setLayout(ptnLayout2);

Category& root = Category::getRoot();
root.setAppender(posAp);
root.addAppender(FileAp);
root.addAppender(RollingFileAp);
root.setPriority(Priority::DEBUG);

Category& model = root.getInstance("register");

for(int i = 0;i < 100;++i)
{
root.emerg("this is an emrge");
root.alert("this is an alert");
root.crit("this is a critical");
root.error("this is an error");
root.warn("this is a warn");
root.notice("this is a notice");
root.info("this is an info");
root.debug("this is a debug");

model.emerg("this is an emrge");
model.alert("this is an alert");
model.crit("this is a critical");
model.error("this is an error");
model.warn("this is a warn");
model.notice("this is a notice");
model.info("this is an info");
model.debug("this is a debug");
}

Category::shutdown;
}
int main()
{
test0();

return 0;
}

输出结果

1684842384 FATAL  : this is an emrge
1684842384 ALERT : this is an alert
1684842384 CRIT : this is a critical
1684842384 ERROR : this is an error
1684842384 WARN : this is a warn
1684842384 NOTICE : this is a notice
1684842384 INFO : this is an info
1684842384 DEBUG : this is a debug
1684842384 FATAL register : this is an emrge
1684842384 ALERT register : this is an alert
1684842384 CRIT register : this is a critical
1684842384 ERROR register : this is an error
1684842384 WARN register : this is a warn
1684842384 NOTICE register : this is a notice
1684842384 INFO register : this is an info
1684842384 DEBUG register : this is a debug
...
...
1684842384 FATAL : this is an emrge
1684842384 ALERT : this is an alert
1684842384 CRIT : this is a critical
1684842384 ERROR : this is an error
1684842384 WARN : this is a warn
1684842384 NOTICE : this is a notice
1684842384 INFO : this is an info
1684842384 DEBUG : this is a debug
1684842384 FATAL register : this is an emrge
1684842384 ALERT register : this is an alert
1684842384 CRIT register : this is a critical
1684842384 ERROR register : this is an error
1684842384 WARN register : this is a warn
1684842384 NOTICE register : this is a notice
1684842384 INFO register : this is an info
1684842384 DEBUG register : this is a debug
1684842384 FATAL : this is an emrge
1684842384 ALERT : this is an alert
1684842384 CRIT : this is a critical
1684842384 ERROR : this is an error
1684842384 WARN : this is a warn
1684842384 NOTICE : this is a notice
1684842384 INFO : this is an info
1684842384 DEBUG : this is a debug
1684842384 FATAL register : this is an emrge
1684842384 ALERT register : this is an alert
1684842384 CRIT register : this is a critical
1684842384 ERROR register : this is an error
1684842384 WARN register : this is a warn
1684842384 NOTICE register : this is a notice
1684842384 INFO register : this is an info
1684842384 DEBUG register : this is a debug

目录下生成结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/a1f4133bd1c3459587ef0281c5c029ed.png

在这里插入图片描述

在这里插入图片描述
可以看到通过FileAppender生成了test.log,文件大小为28KB
通过RollingFileAppender生成了10个a.log回卷文件,每个文件大小都为5KB,总和为50KB,此时还并不能体现出回卷文件节省空间的能力
我们把for循环改为1000次
在这里插入图片描述

此时可以看到test.log大小为899KB,a.log回卷文件大小总和依然为50KB