C++ 日志库 spdlog 使用教程
Spdlog是一个快速、异步、线程安全的C++日志库,他可以方便地记录应用程序的运行状态,并提供多种输出格式。官网:https://github.com/gabime/spdlog
安装教程可以参考:https://blog.csdn.net/Harrytsz/article/details/144887297
Spdlog的优点:
- 只包含头文件
- 速度很快
- 无需依赖第三方库
- 支持跨平台
- 支持多线程—线程安全
- 可对日志文件进行循环输出
- 可每日生成日志文件
- 可支持控制台日志输出
- 可选的异步输出
- 可定义日志格式
1、日志级别
trace = SPDLOG_LEVEL_TRACE // 最低级(用来记录代码执行轨迹)
debug = SPDLOG_LEVEL_DEBUG // (用来记录debug信息)
info = SPDLOG_LEVEL_INFO // 在上面的测试例子中用过
warn = SPDLOG_LEVEL_WARN
err = SPDLOG_LEVEL_ERROR
critical = SPDLOG_LEVEL_CRITICAL
off = SPDLOG_LEVEL_OFF // 最高级
2、控制台打印日志
方式一,最简单的使用方式,将日志输出到控制台。
#include <iostream>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>void stdout_easy()
{// 根据参数,在内部创建了一个名为 "console" 的 logger,返回 logger 的智能指针。auto console = spdlog::stdout_color_mt("console");// 通过智能指针调用 logger 对象的函数。console->info("hello world");
}
int main()
{stdout_easy();return 0;
}
输出结果:
方式二,
#include <iostream>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>void stdout_example() {// create a color multi-threaded logger// spdlog::stdout_color_mt("console")函数创建一个名字为console的console logger,// 把这个 logger 注册到 spdlog 的全局注册表中,并且返回指向这个 logger 的指针(shared_ptr)auto console_stdout = spdlog::stdout_color_mt("console");// 如果我们不知道上方创建函数返回的指针,我们也可以直接通过 logger 名称来获取对应 logger // 通过 get 来获取已经创建好的 logger,获取方式通过指针名,同时使用 info 函数输出日志内容spdlog::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name)");
}int main() {stdout_example();return 0;
}
输出结果:
3、保存日志文件
下面的案例将日志记录保存到文件中,以便于长久保存。basic_logger_mt
只是 spdlog 中封装的其中一个日志记录器,还有很多其他的记录器。
#include<iostream>
#include<spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>int main() {// 创建一个名为 basic_logger 的日志记录器,并且返回指针。// mt 表示多线程,意味着多个线程中使用同一个日志记录器。// 需要注意的是在文件内添加数据是通过追加的形式进行的,并且如果没有创建文件会自动创建文件。auto basic_logger = spdlog::basic_logger_mt("basic_logger", "./logs/basic_log.txt");for (int i = 0; i < 10000; i++) {basic_logger->info("Test file logger{}", i);}return 0;
}
4、自定义日志记录器
我们根据以上的学习之后,大体了解了其中的运行机制,所以我们就可以不使用他封装的日志记录器,而是使用他内部的 logger 对象封装适合自己的日志记录器。
需要注意的是,所谓的不同的日志记录器其实就是不同的 logger 对象,那么用什么来区分不同的 logger 对象呢,就是用创建logger对象时传入的参数 sink 对象,这个sink对象标记着不同的类型,把他作为参数 logger 会根据 sink 对象类型的不同创建不同的日志记录器。
这种方式有很大的用途,比如我们可以创建一个日志记录器,但是里边有多个类型的 sink,从而可以一个 logger 能够实现多种效果。
#include<iostream>
#include<spdlog/spdlog.h>
//#include <spdlog/sinks/stdout_sinks.h>
#include <spdlog/sinks/stdout_color_sinks.h>void make_console_spdlog() {/*auto console_level = std::make_shared<spdlog::sinks::stdout_sink_mt>();*/ // 黑白日志auto console_level = std::make_shared<spdlog::sinks::stdout_color_sink_mt>(); // 彩色日志auto console = std::make_shared<spdlog::logger>("console", console_level);console->info("hello world");
}int main() {make_console_spdlog();return 0;
}
输出结果:
注意:通过手动创建的日志记录器是无法通过名字在 spdlog 中进行查找的,因为他并没有注册到 spdlog 的全局注册表。
void make_console_spdlog() {auto console_level = std::make_shared<spdlog::sinks::stdout_sink_mt>();auto console = std::make_shared<spdlog::logger>("console", console_level);// 直接使用这种方式去获取日志记录器发生错误spdlog::get("console")->info("hello world!");
}
所以在创建日志记录器完成后,要将其注册到spdlog的全局注册表中。
#include<iostream>
#include<spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>void make_console_spdlog() {auto console_level = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();auto console = std::make_shared<spdlog::logger>("console", console_level);// 将创建的日志记录器注册到全局注册表中spdlog::register_logger(console);spdlog::get("console")->info("hello world!");
}int main() {make_console_spdlog();return 0;
}
5、多记录器共享文件
#include <iostream>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>void multi_file_write()
{// 创建filesink,以便多个日志共享器共享。auto filesink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("./logs/multilogger.txt");// 创建两个日志记录器来进行测试auto onelogger = std::make_shared<spdlog::logger>("onelogger", filesink);auto twologger = std::make_shared<spdlog::logger>("twologger", filesink);// 注册进spdlog的全局注册表spdlog::register_logger(onelogger);spdlog::register_logger(twologger);for (int i = 0; i < 100; i++) {onelogger->info("onelogger write:{}", i);twologger->info("twologger write:{}", i);}
}int main() {multi_file_write();return 0;
}
6、日志分割
在我们的应用程序有很多日志需要记录时,每个日志文件就会变得非常大,这样就会影响应用程序的性能以及稳定性。所以为了解决这个问题,可以使用Spdlog的日志分割功能。
rotating log 滚动日志,当日志文件超出规定大小时,会删除当前日志文件中所有内容,重新开始写入
#include<iostream>
#include<spdlog/spdlog.h>
#include <spdlog/sinks/rotating_file_sink.h>void rotaing_file() {// 首先定义要使用分割文件的大小和数量int max_size = 1048576 * 5;int file_size = 3;// 创建 rotaing_logger_mt 日志记录器auto rotaing_file = spdlog::rotating_logger_mt("rotaing_file", "./logs/rotaingLogger.txt", max_size, file_size);for (int i = 0; i < 100000; i++) {rotaing_file->info("rotaing file:{}", i);}
}int main() {rotaing_file();return 0;
}
7、定时日志
Spdlog还可以实现定时创建文件存储日志的功能。
#include<iostream>
#include<spdlog/spdlog.h>
#include <spdlog/sinks/daily_file_sink.h>void daily_log() {// 创建daily_log日志// 参数介绍 1日志记录器名称 2文件名 3时 4分auto daily_log = spdlog::daily_logger_mt("daily_log", "./logs/daily_log.txt", 16, 18);for (int i = 0; i < 100000; i++) {daily_log->info("daily log print {}", i);}
}int main() {daily_log();return 0;
}
8、记录器包含多个 sink
#include<iostream>
#include<spdlog/spdlog.h>
#include<spdlog/sinks/stdout_color_sinks.h>
#include<spdlog/sinks/basic_file_sink.h>void multi_sink() {// 创建两个sink,一个用于控制台输出,一个用于文件输出auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("./logs/multi_sink.txt");// 设置两者输出等级console_sink->set_level(spdlog::level::info);file_sink->set_level(spdlog::level::debug);// 将两种不同的sink放到一个日志输出器中auto multi_sink = std::make_shared<spdlog::logger>("multi_sink", spdlog::sinks_init_list({ console_sink, file_sink }));multi_sink->set_level(spdlog::level::debug);// 输出不同等级日志测试multi_sink->info("hello world info");multi_sink->debug("hello world debug");
}int main() {multi_sink();return 0;
}
9、其他介绍
通过上面的学习,我们学会了 spdlog 其函数的基本使用方式,下面对 spdlog 中常用的一些函数和类进行介绍。
- level_enum:日志等级枚举,包括trace、info、debug、warn、err、critical、off、n_levels。
- sink:日志记录槽,进行底层操作(比如格式化内容,输出内容到控制台/文件)的类。spdlog自带的几种sinks已经能满足日常需求,也可以派生其基类设计新的 sink 以满足特殊的需求。sink类主要使用的函数包括:
- set_pattern(const std::string&):设置日志输出格式。
- set_level(level_enum):设置日志输出的最低等级。
- log(log_msg):由logger自动调用,外部不会主动调用。
- logger:日志记录器,被顶层调用来输出日志的类。一个logger对象中存储有多个sink,当调用logger的日志输出函数时,logger会调用自身存储的所有sink对象的log(log_msg)函数进行输出。与自身的sink对应,spdlog也自带了几种logger。logger类主要使用的函数包括:
- set_pattern(const std::string&):设置logger包括的所有sink的日志输出内容格式。
- set_level(level_enum):设置logger日志输出最低等级,如果logger包含的sink没有设置日志等级的话,则会为其设置日志等级。
- log(level_enum level, log_msg content):按照level等级进行输出content,logger其中日志输出最低等级小于或等于level的sink会执行输出操作。
- info(content, arg1, arg2…):按照trace等级进行输出,输出内容由content与后面的采纳数格式化组成。荣磊的函数还包括debug/trace/warn…。
- st/mt:对象版本,spdlog 中 logger 对象和 sink 对象都有两种版本,一种是以 st 结尾的单线程版本,以及以 mt 结尾的多线程版本。
- st:单线程版本,不用加锁,效率更高。
- mt:多线程版本,用于多线程程序是线程安全的。
相关文章:

C++ 日志库 spdlog 使用教程
Spdlog是一个快速、异步、线程安全的C日志库,他可以方便地记录应用程序的运行状态,并提供多种输出格式。官网:https://github.com/gabime/spdlog 安装教程可以参考:https://blog.csdn.net/Harrytsz/article/details/144887297 S…...
`http_port_t
http_port_t 是 SELinux(Security-Enhanced Linux)中的一种端口类型标签,用于标识哪些端口可以被 HTTP 和 HTTPS 服务使用。SELinux 是一种强制访问控制(MAC)安全模块,它通过定义安全策略来限制进程对系统资…...

SpringBoot中实现拦截器和过滤器
【SpringBoot中实现过滤器和拦截器】 1.过滤器和拦截器简述 过滤器Filter和拦截器Interceptor,在功能方面很类似,但在具体实现方面差距还是比较大的。 2.过滤器的配置 2.1 自定义过滤器,实现Filter接口(SpringBoot 3.0 开始,jak…...
不锈钢均温板结合强力粘合技术革新手机内部架构
摘要: 本文介绍了一种创新性的手机内部架构设计方案,其中不锈钢均温板不仅作为高效的散热元件,还充当了手机中框的主要结构件。通过使用强力不可拆胶水将主板、尾插和其他关键部件直接粘合到均温板上,该方案实现了更为紧密的热耦合…...

Docker安装使用
文章目录 Docker安装Docker的基础使用搜索&拉取镜像 Docker的生命周期利用Docker切换不同OSDocker容器 镜像的保存&分享Docker存储Docker网络 Docker安装 更新apt索引 sudo apt-get update添加Docker所需要的依赖 apt-get install ca-certificates curl gnupg lsb-r…...
React 如何进行路由变化监听
一、使用react-router库(以react-router-dom为例) 1. 历史(history)对象监听 1.1 原理 react-router内部使用history对象来管理路由历史记录。可以通过访问history对象来监听路由变化。在基于类的组件中,可以通过组…...

Unity UGUI使用技巧与经验总结(不定期更新)
Text自动缩放参考连接: Unity -UGUI中Text文本框的自动调整,字体大小的自适应调节_unity添加的字体大小锁定-CSDN博客 Toggle按钮选择时,显示对应的UI界面: 为Toggle组件的On Value Change事件添加对需要显示的对象的SetActive…...

中国乡镇界shp全境arcgis格式shp数据乡镇名称下载后内容测评
下载乡镇界shp链接:https://download.csdn.net/download/zhongguonanren99/19354855 标题中的“中国乡镇界shp全境arcgis格式shp数据乡镇名称2012年”揭示了这个数据集的核心内容。它是一个地理信息系统(GIS)数据,具体来说是使用…...

第 31 章 - 源码篇 - Elasticsearch 写入流程深入分析
写入源码分析 接收与处理 请求首先会被 Netty4HttpServerTransport 接收,接着交由 RestController 进行路由分发。 private void tryAllHandlers(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) throws Exception {…...

node.js下载、安装、设置国内镜像源(永久)(Windows11)
目录 node-v20.18.0-x64 工具下载安装设置国内镜像源(永久) node-v20.18.0-x64 工具 系统:Windows 11 下载 官网https://nodejs.org/zh-cn/download/package-manager 版本我是跟着老师选的node-v20.18.0-x64如图选择 Windows、x64、v2…...
小于n的最大数 - 贪心算法 - C++
字节经典面试题 给定一个整数n,并从1~9中给定若干个可以使用的数字,根据上述两个条件,得到每一位都为给定可使用数字的、最大的小于整数n的数,例如,给定可以使用的数字为 {2,3,8} 三个数:给定 n3589&#x…...

【顶刊TPAMI 2025】多头编码(MHE)之极限分类 Part 3:算法实现
目录 1 三种多头编码(MHE)实现1.1 多头乘积(MHP)1.2 多头级联(MHC)1.3 多头采样(MHS)1.4 标签分解策略 论文:Multi-Head Encoding for Extreme Label Classification 作者…...
解决CentOS 8 YUM源更新后报错问题:无法下载AppStream仓库元数据
背景介绍 在尝试更新CentOS 8的YUM源以使用阿里云镜像时,遇到了Failed to download metadata for repo appstream的错误。此错误通常出现在执行yum clean all && yum makecache命令之后,表明系统无法从指定的URL获取AppStream仓库的元数据。本文…...
[python3]Excel解析库-openpyxl
https://openpyxl.readthedocs.io/en/stable/ openpyxl 是一个用于读写 Excel 2010 xlsx/xlsm/xltx/xltm 文件的 Python 库。它允许开发者创建、修改和保存电子表格,而无需依赖 Microsoft Excel 软件本身。openpyxl 支持读取和写入 Excel 的工作簿(Work…...

Docker 远程访问完整配置教程以及核心参数理解
Docker 远程访问完整配置教程 以下是配置 Docker 支持远程访问的完整教程,包括参数说明、配置修改、云服务器安全组设置、主机防火墙配置,以及验证远程访问的详细步骤。 1. 理解 -H fd:// 参数的作用(理解了以后容易理解后面的操作ÿ…...

王老吉药业SRM系统上线 携手隆道共启战略合作新篇章
12月27日,广州王老吉药业股份有限公司(简称“王老吉药业”)SRM项目上线启动会,在王老吉科普教育基地——“吉园”隆重举行。广药集团纪委主任陈耕、王老吉药业总工程师黄晓丹、隆道公司总裁吴树贵、项目经理赵耀、供应商代表郭伟及…...
MyBatis 配置文件全解析
一、MyBatis 配置文件为何至关重要? 在 Java 后端开发领域,MyBatis 作为一款广受欢迎的持久层框架,极大地简化了数据库操作。而 MyBatis 配置文件,恰似整个框架的 “神经中枢”,掌控着其运行的方方面面,对…...

unity学习6:unity的3D项目的基本界面和菜单
目录 1 unity界面的基本认识 1.1 file 文件 1.2 edit 编辑/操作 1.3 Assets 1.4 gameobject 游戏对象 1.5 组件 1.6 windows 2 这些部分之间的关系 2.1 关联1: Assets & Project 2.2 关联2:gameobject & component 2.3 关联3…...

企业二要素如何用C#实现
一、什么是企业二要素? 企业二要素,通过输入统一社会信用代码、企业名称或统一社会信用代码、法人名称,验证两者是否匹配一致。 二、企业二要素适用哪些场景? 例如:信用与金融领域 1.信用评级:信用评级…...

中科院空天院无人机视觉语言导航新基准!AeroVerse:模拟、预训练、微调和评估空中无人机具身世界模型的测试基准
作者: Fanglong Yao, Yuanchang Yue, Youzhi Liu, Xian Sun, Kun Fu 单位:中国科学院空天信息创新研究院网络信息系统技术重点实验室,中国科学院大学电子电气与通信工程学院 原文链接: AeroVerse: UAV-Agent Benchmark Suite fo…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...

Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)
错误一:yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因,后面把yaml.safe_dump直接替换成yaml.dump,确实能保存,但出现乱码: 放弃yaml.dump,又切…...

2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...