日志库 Spdlog
1.Spdlog
- 用途:快速且易于使用的 C++ 日志库。
- 使用场景:记录服务器运行时的各种信息,便于调试和问题排查。
可以输出报错的行数,代码:日志输出中要携带文件名、行数或函数名时,必须使用SPDLOG_LOGGER_*宏,
spdlog中字符串格式化使用fmt(https://github.com/fmtlib/fmt)库。
可以使用循环文件(超过设定大小删除之前的日志),每日文件(日期命名)
2.编写一个例子,在多线程中测试spdlog库的循环日志文件功能
这里是同步写入的
#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include <thread>
#include <vector>
void log_messages(std::shared_ptr<spdlog::logger> logger) {
for (int i = 0; i < 100; ++i) {
logger->info("Logging message {}", i);
}
}
int main() {
// 创建一个循环日志记录器
auto rotating_logger = spdlog::rotating_logger_mt(
"rotating_logger",
"logs/rotating_log.txt",
1024 * 1024 * 5, // 每个文件最大5MB
3); // 最多保留3个文件
// 设置日志级别为 info
rotating_logger->set_level(spdlog::level::info);
过滤掉info级别以下的日志
// 设置日志模式以包含线程ID
logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%t] [%^%l%$] %v");
// 启动多个线程进行日志记录
const int num_threads = 5;
std::vector<std::thread> threads;
for (int i = 0; i < num_threads; ++i) {
threads.emplace_back(log_messages, rotating_logger);
}
// 等待所有线程完成
for (auto& t : threads) {
t.join();
}
return 0;
}
3.异步写入循环文件
#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/async.h"
#include <thread>
#include <vector>
// 定义全局日志记录器
std::shared_ptr<spdlog::logger> rotating_logger;
void log_messages() {
for (int i = 0; i < 100; ++i) {
rotating_logger->info("Logging message {}", i);
异步模式下,默认情况下不需要手动开启定时刷新,因为后台线程会持续处理队列中的日志消息并适时地写入磁盘。
}
}
int main() {
// 初始化异步日志队列
spdlog::init_thread_pool(8192, 1); // 队列大小和线程数
// 创建一个旋转日志接收器
auto rotating_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
"logs/rotating_log.txt",
1024 * 1024 * 5, // 每个文件最大5MB
3); // 最多保留3个文件
// 创建一个异步日志记录器并将旋转日志接收器添加到其中
rotating_logger = std::make_shared<spdlog::async_logger>(
"rotating_logger",
rotating_sink,
spdlog::thread_pool(),
spdlog::async_overflow_policy::block);
//or 或者使用 spdlog::async_overflow_policy::overrun_oldest 来覆盖最旧的日志
// 设置日志级别为 info
rotating_logger->set_level(spdlog::level::info);
// 设置日志模式以包含线程ID
rotating_logger->set_pattern("%t [%Y-%m-%d %H:%M:%S.%e] [%^%l%$] %v");
// 注册全局日志记录器
spdlog::register_logger(rotating_logger);
// 启动多个线程进行日志记录
const int num_threads = 5;
std::vector<std::thread> threads;
for (int i = 0; i < num_threads; ++i) {
threads.emplace_back(log_messages);
}
// 等待所有线程完成
for (auto& t : threads) {
t.join();
}
// 关闭所有日志记录器
spdlog::drop_all();
return 0;
}
- 大型项目如果多个模块日志分开记录,则可以
在init中注册多个文件日志记录器,然后使用spdlog::get()获取
在关键点手动调用 logger->flush() 方法来立即把队列中的日志消息写入磁盘
#include "spdlog/spdlog.h"
#include "spdlog/rotating_logger.h"
void setup_logging() {
// 创建并注册一个轮转日志记录器
auto rotating_logger = spdlog::rotating_logger_mt("rotating_logger", "logs/rotating_log.txt", 1024 * 1024 * 5, 3);
spdlog::register_logger(rotating_logger);
}
int main() {
setup_logging(); // 初始化日志系统
// 获取之前注册的 logger
auto logger = spdlog::get("rotating_logger");
if (logger) {
logger->info("This is an info message.");
} else {
std::cerr << "Logger not found!" << std::endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!