说到C++日志,你是不是还在用printf或者笨重的log4cpp?要是遇到多线程、格式化、文件轮转啥的就崩溃……别怕,今天给大家安利一个「轻量又彪悍」的日志库——spdlog,特别适合嵌入式平台用,超快,功能又强大。
什么是spdlog
简单来说,spdlog是一个基于fmt库的超高性能C++日志库。
-
• 支持纯头文件模式,也可编译成库
-
• 完全C++11,零依赖(除了
fmt) -
• 支持同步/异步、单/多线程、安全靠谱
大家可以把它想象成一个「小而美」的日志框架,不用学一堆配置文件,直接在代码里嗨。
spdlog解决了哪些痛点
传统日志库常见的坑:
-
1. 编译慢:头文件堆一大堆,增量编译慢得要死
-
2. 格式化不爽:自己写
snprintf太累,还容易越界 -
3. 线程安全:多线程下日志乱序、死锁频发
-
4. 文件管理:日志切割、归档要自己写脚本
spdlog的killer features:
|
功能 |
说明 |
|
异步模式 |
后台线程写日志,不阻塞主线程 |
|
文件轮转/按天切割 |
支持大小/时间自动切割,轻松搞定归档 |
|
多种输出目标 |
控制台(彩色)、文件、syslog、Android logcat |
|
动态改级别 |
运行时修改日志级别,线上排查更灵活 |
|
回溯缓冲 |
出错时才dump debug信息,不浪费IO |
安装&快速上手
安装超简单!在Linux下直接:
sudo apt install libspdlog-dev
也可以手动搞:
git clone https://github.com/gabime/spdlog.git
cd spdlog && mkdir build && cd build
cmake .. && cmake --build .
在CMakeLists.txt里这么用:
find_package(spdlog REQUIRED)
target_link_libraries(your_target PRIVATE spdlog::spdlog)
简单示例
#include "spdlog/spdlog.h"
int main() {
spdlog::info("Hello, {}!", "spdlog");
spdlog::set_level(spdlog::level::debug);
spdlog::debug("Debug模式,超详细");
// 日志格式
spdlog::set_pattern("[%H:%M:%S %^%L%$] [%t] %v");
spdlog::warn("警告:内存 {}MB 不够用", 10);
}
运行后,会看到彩色、格式化的日志,非常直观。
在嵌入式领域的妙用
-
• 内存占用小:头文件模式占用很少,适合资源受限的MCU/ARM板子。
-
• 动态日志级别:可通过环境变量或者命令行改Level,线上调试方便。
-
• 异步不卡顿:用异步模式,把日志写到SD卡或NAND时不卡主循环。
-
• 自定义Sink:比如写到串口(UART)或RTOS日志队列,轻松扩展。
下面这张表,帮你比对一下spdlog在嵌入式开发里的优势:
|
特性 |
原生printf |
spdlog |
|
占用ROM/RAM |
很多 |
较少 |
|
线程安全 |
手写锁 |
内置 |
|
格式化效率 |
低 |
超快(百万行/秒级别) |
|
日志切割/归档 |
无 |
内建支持 |
|
动态调整日志级别 |
不可 |
可(runtime/cli/env) |
优缺点小结
|
优点 |
缺点 |
|
极致性能:同步模式 500w/s,异步模式更高 |
对C++11以上要求 |
|
API简单:几行代码搞定 |
编译选项多,初学者要捋一下 |
|
丰富Sink:控制台、文件、syslog、串口…… |
部分高级功能要写模板 |
|
可嵌入RTOS/裸机 |
体量比 |
总结
总的来说,spdlog就是「想要快速、稳定、功能全」的日志方案,特别推荐给嵌入式开发的小伙伴。直接拷头文件或者编译成库都行,不用折腾太多依赖,日志切割、异步写、线程安全全包了。试试再说,肯定让你爱不释手。
项目地址:https://github.com/gabime/spdlog