log4cpp的使用

news/2024/7/7 20:47:53

  • log4cpp的使用
    • 逻辑构造
    • 基本模板
    • 布局的格式化
    • 目的地对象操作文件
    • 回卷文件

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


http://lihuaxi.xjx100.cn/news/1162705.html

相关文章

态路小课堂丨光口不亮?三种简单故障排查请查收!

在光链路中&#xff0c;当遇到交换机光口互连不亮情况时&#xff0c;很多人不知道如何处理。本文态路为您介绍三种简单故障排查方案&#xff0c;助您快速进行故障排查和问题定位。 一、首先检查一致性 1、两端光模块型号是否一致。一般包括速率、封装模式、接口类型、传输波长、…

数据库提权

数据库提权的前提就是得到数据库的账号密码。在webshell或本地进行提权。 数据库提权分为四步&#xff1a; 1.服务探针&#xff0c;探测出数据库的类型&#xff08;端口扫描等&#xff09; 2.信息搜集&#xff0c;就是获取到数据库的账号密码。权限要高。 读取数据库密码的…

斐波那契数列相关简化4

看这篇文章前需要看下前面三篇文章&#xff0c;最起码第一第二篇是需要看一下的 斐波那契数列数列相关简化1_鱼跃鹰飞的博客-CSDN博客 斐波那契数列数列相关简化2_鱼跃鹰飞的博客-CSDN博客 算法玩的就是套路&#xff0c;练练就熟悉了 再来一个&#xff1a; 用1*2的瓷砖&am…

Wireshark - 过滤表达式的规则

文章目录 1. 过滤 协议2. 过滤 端口3. 过滤 IP4. 过滤 TCP重传数据包5. 包长度过滤6. <未完待续2023.5.23> 1. 过滤 协议 1、TCP - 只显示TCP协议2、!TCP - 排除TCP协议 2. 过滤 端口 1、tcp.port6666 - 显示&#xff08;不分来源或目标&#xff09;端口2、tcp.dstp…

MySQL之事务初步

0. 数据源 /*Navicat Premium Data TransferSource Server : localhost_3306Source Server Type : MySQLSource Server Version : 80016Source Host : localhost:3306Source Schema : tempdbTarget Server Type : MySQLTarget Server Version…

Scala学习(七)---面向对象特质

文章目录 1.面向对象特质(Trait)2.特质声明2.1 特质的特点2.2 特质冲突2.3 特质叠加2.4 特质自身类型2.5 特质和抽象类的区别扩展 1.面向对象特质(Trait) 在Scala语言中&#xff0c;采用特质trait(特征)来代替接口的概念&#xff0c;也就是说&#xff0c;多个类具有相同的特质…

开了十年服装店之后,我总结出这9条成功“秘诀”

对于开服装店的老板来说&#xff0c;提高营业额一直都是我们的主要目标。 但是放眼望去&#xff0c;一条街上的服装店随处可见&#xff0c;竞争越来越激烈&#xff0c;任何一家服装店想要经营好&#xff0c;持续不断地吸引顾客上门&#xff0c;都不是一件容易的事。 门店虽小&a…

spring Security 认证失败,用户名和密码是正确的还是失败

项目用登录输入正确的用户名和密码为什么还是告知,用户名和密码是不正确? 有这几种情况 第一种是不是开启缓存,数据库中存储的是加密后的密码 第二种,查看源代码,这句是关键,presentedPassword是明文密码,userDetails.getPassword()是加密后的密码,进行比较 this.pa…