spdlog日志器(logger)的创建方法大全
根据Spdlog源码分析及技术文档,其日志器(logger)的创建方法可分为以下核心类型:
%%
%%
一、工厂函数直接创建
通过内置工厂模板函数快速生成预配置的日志器,适用于常见场景:
- 控制台日志器
// 多线程彩色控制台输出(_mt表示多线程安全)
auto console = spdlog::stdout_color_mt("console_logger");
// 错误输出专用
auto stderr_logger = spdlog::stderr_color_mt("error_logger");
- 此类日志器支持ANSI颜色编码,输出级别可通过
set_level()
动态调整。
- 基础文件日志器
// 单文件持续写入(无滚动策略)
auto file_logger = spdlog::basic_logger_mt("file_logger", "logs/app.log");
- 需注意长时间运行可能导致文件过大。
- 滚动文件日志器
// 文件大小超过5MB后滚动(保留3个历史文件)
auto rotating_logger = spdlog::rotating_logger_mt("rot_logger", "logs/rot.log", 5 * 1024 * 1024, 3);
- 采用先进先出策略管理历史文件。
- 每日文件日志器
// 每天0点创建新文件,保留7天日志
auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.log", 0, 0, false, 7);
- 第五参数
truncate
控制是否覆盖已有文件。
二、手动组合创建
通过直接构造spdlog::logger
对象实现高度定制化:
// 1. 创建Sink集合
std::vector<spdlog::sink_ptr> sinks;
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); // 控制台
sinks.push_back(std::make_shared<spdlog::sinks::daily_file_sink_mt>("logs/combo.log", 23, 59)); // 每日文件// 2. 构造日志器对象
auto custom_logger = std::make_shared<spdlog::logger>("custom", sinks.begin(), sinks.end());// 3. 注册全局访问(可选)
spdlog::register_logger(custom_logger);
此方式支持多Sink组合输出,如同时写入控制台、文件、网络等。
三、异步日志器创建
采用生产者-消费者模型提升性能:
// 初始化线程池(队列容量8192,2个工作线程)
spdlog::init_thread_pool(8192, 2);// 创建异步日志器
auto async_logger = spdlog::basic_logger_mt<spdlog::async_factory>("async_logger", "logs/async.log");
特点包括:
• 支持阻塞/丢弃/覆盖三种队列溢出策略
• 通过flush_every(sec)
设置定时刷新间隔
• 吞吐量可达同步模式的4倍以上
四、高级配置方法
- 全局注册与访问
// 注册日志器
spdlog::register_logger(my_logger);// 全局获取
auto logger = spdlog::get("logger_name");
- 需注意频繁调用
spdlog::get()
可能影响性能。
- 共享Sink复用
auto shared_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("shared.log");
auto logger1 = std::make_shared<spdlog::logger>("logger1", shared_sink);
auto logger2 = std::make_shared<spdlog::logger>("logger2", shared_sink);
- 多个日志器共享同一Sink时需确保线程安全。
五、源码设计解析
- 工厂模式实现
- 通过模板工厂类(如
synchronous_factory
)解耦日志器与Sink的创建过程,支持扩展自定义Sink类型。
- 通过模板工厂类(如
- 日志器核心结构
class logger {
private:std::string name_;std::vector<sink_ptr> sinks_;level::level_enum level_;// 日志处理逻辑void log(log_msg& msg) {if (should_log(msg.level)) {for (auto& sink : sinks_) sink->log(msg);}}
};
- 采用组合模式管理Sink,支持多路分发。
最佳实践建议
- 高频日志场景启用
SPDLOG_NO_ATOMIC_LEVELS
编译选项提升性能 - 分布式系统建议采用
udp_sink
实现集中式日志管理 - 文件类日志器需设置合理的缓冲区大小(如64KB)减少IO操作
完整代码示例及性能优化参数可参考官方文档。