log4cpp的使用

news2024/12/25 23:46:00

  • 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://www.coloradmin.cn/o/560152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【WSN覆盖】基于麻雀搜索算法的三维无线传感器网络覆盖优化 三维WSN覆盖优化【Matlab代码#26】

文章目录 【可更换其他算法&#xff0c;获取资源请见文章第5节&#xff1a;资源获取】1. SSA算法2. 三维覆盖模型3. 部分代码展示4. 仿真结果展示5. 资源获取 【可更换其他算法&#xff0c;获取资源请见文章第5节&#xff1a;资源获取】 1. SSA算法 2. 三维覆盖模型 三维覆盖模…

搜狐发布Q1财报:读懂前瞻性布局背后的长期主义

5月15日&#xff0c;搜狐发布了2023年第一季度财报。财报显示&#xff0c;搜狐总收入为1.62亿美元&#xff0c;其中&#xff0c;品牌广告收入为2300万美元&#xff1b;在线游戏收入为1.29亿美元。 同时&#xff0c;归于搜狐公司的非美国通用会计准则净亏损为1300万美元。 搜狐…

ChatGPT+Mermaid Live Editor画流程图

1.粘贴代码通过gpt翻译成Mermaid代码&#xff0c;生成流程图 public int largestValsFromLabels(int[] values, int[] labels, int numWanted, int useLimit) {// 将元素按值从大到小排序PriorityQueue<int[]> pq new PriorityQueue<>((a, b) -> b[0] - a[0])…

MySQL运维篇

一.日志 1.1 错误日志 错误日志是 MySQL 中最重要的日志之一&#xff0c;它记录了当 mysqld 启动和停止时&#xff0c;以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时&#xff0c;建议首先查看此日志。 错误日志是默认开启的…

数学(四) -- LC[29][166] 两数相除与分数到小数

1 分数到小数 1.1 题目描述 题目链接&#xff1a;https://leetcode.cn/problems/fraction-to-recurring-decimal/description/ 1.2 思路分析 1. 长除法 题目要求根据给定的分子和分母&#xff0c;将分数转成整数或小数。由于给定的分子和分母的取值范围都是 [ − 2 31 , 2 …

Linux环境变量提权

linux提权信息收集 Exploit Database - Exploits for Penetration Testers, Researchers, and Ethical Hackers Vulnerability & Exploit Database - Rapid7 NVD - Home CVE -CVE SecWiki GitHub linux系统内核漏洞提权 脏牛提权漏洞&#xff1a; 脏牛提权&#xf…

推荐5个免费好用的UI模板网站!

1、即时设计 即时设计资源广场是一个聚集了大量优秀设计作品和大厂设计系统超过3000个UI组件库的设计师灵感库。该广场每月更新上百个精品模板&#xff0c;且还将这些模板分门别类按不同类型素材进行分类&#xff0c;其丰富的设计资源包括移动设计、网页设计、插画、线框图、矢…

Qt--信号和槽

写在前面 信号与槽机制是Qt中最重要的特性之一&#xff0c;也是其与其他GUI框架的主要区别之一。信号与槽机制允许不同对象之间进行通信和交互&#xff0c;从而实现程序的模块化和可重用性。 在Qt中&#xff0c;信号是一种事件&#xff0c;它可以被任何对象接收并执行相应的操…

Zookeeper、Nacos、Dubbo、Kafka之间的关系

1.Zookeeper Zookeeper 是 Apache Hadoop 的子项目&#xff0c;是一个树型的目录服务&#xff0c;支持变更推送&#xff0c;适合作为 Dubbo 服务的注册中心&#xff0c;工业强度较高。 Zookeeper的功能主要是它的树形节点来实现的。当有数据变化的时候或者节点过期的时候&…

AGV/AMR控制器--科聪

AGV/AMR控制器--科聪 1 行业介绍1.1 控制器概念1.2 行业发展1.3 竞争格局 2 科聪控制器 MRC50002.1 介绍2.2 支持多种导航方式2.3 适配各种轮系底盘2.4 核心参数2.5 优势灵活的二次开发平台&#xff1a;机器人设计软件&#xff08;xRobotStudio&#xff09;完备的实施调试工具&…

干货|写好论文,从一篇优秀的开题报告开始

Hello&#xff0c;大家好&#xff01; 这里是壹脑云科研圈&#xff0c;我是喵君姐姐~ 在今天的推文里&#xff0c;要给大家分享的是从开题报告到论文写作&#xff0c;快来一起看看哦~ 开题报告旨在总结与研究课题有关的立论依据、总体规划和预期研究成果&#xff0c;便于潜在…

一分钟带你了解网络安全(如何自学)

一、关于网络安全职业 早些年&#xff0c;网络安全刚起步&#xff0c;作为一个网络安全从业人员&#xff0c;最苦恼的事情就是每当回到村里变成狗蛋儿的时候&#xff0c;七大姑八大姨&#xff0c;邻里乡亲&#xff0c;村子里的各种人都会来找你&#xff0c;狗蛋儿&#xff0c;你…

(06)---STM32的Systick定时器与ADC

目录 【1】Systick定时器 概念 工作原理 时钟基准 【2】HAL_Delay函数分析 【3】定时器 基本概念 定时器分类 定时器组成 1.计数器 2.自动重装寄存器 3.预分频器 定时器计数原理 实验 2.PWM 定义 参数 工作原理 应用 练习&#xff1a;通过PWM信号调节LED灯亮度 练…

Convolutional Neural Network 的 PyTorch 实现(二)使用TensorRT进行推理加速

本文章针对 Windows 10 系统 目录 TensorRT 环境安装与配置zlibwapi.dll 安装与配置TensorRT 实现 CUDA CuDNN的安装&#xff1a; 参考文章 TensorRT 环境安装与配置 下载链接 TensorRT 本文章针对 Windows10、CUDA10.2 的PC&#xff0c;选择相对应的安装包完成下载。 解压后在…

迪赛智慧数——柱状图(基本柱状图):全球自动化无人机智能支出预测

效果图 全球自动化无人机智能支出及预测分析&#xff0c;2022年机器人流程自动化支出10.4十亿美元&#xff0c;智能流程自动化支出13十亿美元&#xff0c;人工智能业务操作达10.8十亿美元&#xff0c;未来&#xff0c;这些数字将进一步增长&#xff0c;自动化无人机智能也将拥有…

二战京东测试岗失败,真的后悔了....

两天&#xff0c;我的一个朋友去大厂面试&#xff0c;跟我聊天时说&#xff1a;输的很彻底… 我问她&#xff1a;什么情况&#xff1f; 她说&#xff1a;很后悔这5年来一直都干的是功能测试… 相信许多测试人也跟我朋友一样&#xff0c;从事了软件测试很多年&#xff0c;却依然…

小魔驼3.0下探至9万元背后,是毫末智行的“高位再进化”

作者 | 曾响铃 文 | 响铃说 是60分到90分难&#xff0c;还是90分到95分难&#xff1f; 这个问题不难回答——较高基数上的小幅度上升&#xff0c;要比较低基数上的大幅度上升困难得多。 这个道理在很多领域都十分适用&#xff0c;那些前沿技术领域更是如此&#xff0c;越到…

时钟、SysTick定时器、PWM、ADC

目录 【1】STM32的时钟系统 1.时钟基本概念 时钟源&#xff1a; 2.G030时钟源 3.时钟树 4.STM32CubeMX时钟树配置 【2】Systick定时器 1. 概念&#xff1a; 工作原理 时钟基准 【3】HAL_Delay函数分析 【4】定时器 基本概念 定时器分类 定时器组成 1.计数器 2.自…

软件测试----测试管理方法论

1、缺陷 &#xff08;1&#xff09;缺陷的主要变现&#xff1a; 1&#xff09;需求要求的功能没有实现 2&#xff09;实现了需求没有要求的功能 3&#xff09;软件中出现了明确指明不应该出现的错误 4&#xff09;需求虽未明确说明&#xff0c;但是应该实现的功能没有实现 5&…

MySQL高级|最强王者篇

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开兴好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…