0

0

如何在c++中集成spdlog库 实现高性能异步日志记录【项目实战】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-06 18:51:08

|

753人浏览过

|

来源于php中文网

原创

C++中集成spdlog实现高性能异步日志需正确引入header-only库、初始化线程池(如spdlog::init_thread_pool(8192, 1))、配置轮转文件sink、注册async_logger,并注意字符串生命周期与shutdown时机。

如何在c++中集成spdlog库 实现高性能异步日志记录【项目实战】

在 C++ 项目中集成 spdlog 实现高性能异步日志记录,核心在于正确引入库、配置异步模式、避免线程竞争,并兼顾日志轮转与性能开销。它本身不依赖第三方构建系统,轻量且开箱即用。

使用 header-only 方式快速集成 spdlog

spdlog 支持 header-only 使用,适合中小型项目快速上手:

  • GitHub 官方仓库 下载最新 release 的 include/spdlog 目录
  • 将该目录整体复制到项目中的 third_party/spdlog 或类似路径
  • 确保编译器包含路径(-I)指向该目录,例如:-I./third_party/spdlog
  • 在源文件中直接 include:#include "spdlog/async_logger.h"#include "spdlog/sinks/rotating_file_sink.h"

初始化全局异步日志器并设置线程安全策略

异步日志通过内部线程池处理日志写入,避免阻塞主线程。需显式初始化线程池并注册 logger:

  • 调用 spdlog::init_thread_pool(8192, 1):队列容量 8192,工作线程数建议设为 1(多数场景下单线程足够,避免上下文切换开销)
  • 创建 rotating file sink(支持按大小轮转):auto rotating_sink = std::make_shared<:sinks::rotating_file_sink_mt>("app.log", 1024 * 1024 * 5, 3);(单文件上限 5MB,最多保留 3 个历史文件)
  • 构造 async_logger:auto logger = std::make_shared<:async_logger>("app", rotating_sink, spdlog::thread_pool());
  • 注册为默认 logger:spdlog::register_logger(logger); spdlog::set_default_logger(logger);

规范日志调用方式以保障异步性能

异步 logger 对调用方式敏感,不当用法会退化为同步行为或引发崩溃:

Find JSON Path Online
Find JSON Path Online

Easily find JSON paths within JSON objects using our intuitive Json Path Finder

下载

立即学习C++免费学习笔记(深入)”;

  • 避免传递局部变量地址或未持久化字符串(如 std::string 临时对象),应使用 std::string_view 或已拷贝的字符串
  • 推荐格式化方式:logger->info("User {} logged in at {}", user_id, timestamp);(spdlog 内部延迟格式化,线程安全)
  • 禁止在析构函数、信号处理函数、静态对象初始化中调用日志;确保 logger 生命周期长于所有日志调用点
  • 如需立即刷盘(如程序退出前),调用 spdlog::shutdown(); —— 它会等待队列清空并安全关闭线程池

进阶:自定义格式与多 sink 输出

可通过组合多个 sink 实现控制台 + 文件双输出,并统一格式:

  • 创建 console sink:auto console_sink = std::make_shared<:sinks::stdout_color_sink_mt>();
  • 设置格式:console_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%n] [%^%l%$] %v");
  • 合并 sink 到 async logger:std::vector<:sink_ptr> sinks{rotating_sink, console_sink}; auto logger = std::make_shared<:async_logger>("multi", begin(sinks), end(sinks), spdlog::thread_pool());
  • 注意:多个 sink 共享同一 thread pool,无需重复 init

不复杂但容易忽略的是 shutdown 时机和字符串生命周期管理。只要保证 logger 初始化早于任何日志调用、销毁晚于最后一条日志,再配合合理轮转与线程池配置,就能稳定支撑每秒数万条日志的异步写入需求。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

314

2023.08.02

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

253

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

206

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1458

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

612

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

547

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

542

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

159

2025.07.29

PPT动态图表制作教程大全
PPT动态图表制作教程大全

本专题整合了PPT动态图表制作相关教程,阅读专题下面的文章了解更多详细内容。

13

2026.01.07

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.5万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.5万人学习

Git中文开发手册
Git中文开发手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号