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…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
