spdlog架构

- registry:全局单例管理中心
- 负责统一管理所有的 Logger、Sinks 和线程池资源。
- 提供通过名称获取 Logger 实例的能力,确保全局访问的一致性
- loggers:负责记录日志消息,是用户直接调用的接口
- 控制 Flush 策略:决定何时将缓冲区数据强制刷新到目标存储中
- 控制日志级别 :支持
trace、debug、info、warn、error和critical六种级别
- sinks:接收器
- 指定输出位置:决定日志是去控制台、文件,还是通过网络发送到远程服务器
- 包含 Formatter:每个 Sink 通常持有一个 Formatter,用于定制该输出目标的具体格式
- Formatters:格式化器,负责将日志消息转换为用户指定的结构化字符串格式
- Async Logger & Thread Pool (异步记录器与线程池)
- 异步写入:Async Logger 将日志消息推送到线程池中进行后台处理 。
- 性能保障:通过线程池异步化 I/O 操作,显著减少对主线程性能的影响
spdlog工作流程
#mermaid-svg-5NeA9yqaWhklPDXI{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5NeA9yqaWhklPDXI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5NeA9yqaWhklPDXI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5NeA9yqaWhklPDXI .error-icon{fill:#552222;}#mermaid-svg-5NeA9yqaWhklPDXI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5NeA9yqaWhklPDXI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5NeA9yqaWhklPDXI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5NeA9yqaWhklPDXI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5NeA9yqaWhklPDXI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5NeA9yqaWhklPDXI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5NeA9yqaWhklPDXI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5NeA9yqaWhklPDXI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5NeA9yqaWhklPDXI .marker.cross{stroke:#333333;}#mermaid-svg-5NeA9yqaWhklPDXI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5NeA9yqaWhklPDXI p{margin:0;}#mermaid-svg-5NeA9yqaWhklPDXI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5NeA9yqaWhklPDXI .cluster-label text{fill:#333;}#mermaid-svg-5NeA9yqaWhklPDXI .cluster-label span{color:#333;}#mermaid-svg-5NeA9yqaWhklPDXI .cluster-label span p{background-color:transparent;}#mermaid-svg-5NeA9yqaWhklPDXI .label text,#mermaid-svg-5NeA9yqaWhklPDXI span{fill:#333;color:#333;}#mermaid-svg-5NeA9yqaWhklPDXI .node rect,#mermaid-svg-5NeA9yqaWhklPDXI .node circle,#mermaid-svg-5NeA9yqaWhklPDXI .node ellipse,#mermaid-svg-5NeA9yqaWhklPDXI .node polygon,#mermaid-svg-5NeA9yqaWhklPDXI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5NeA9yqaWhklPDXI .rough-node .label text,#mermaid-svg-5NeA9yqaWhklPDXI .node .label text,#mermaid-svg-5NeA9yqaWhklPDXI .image-shape .label,#mermaid-svg-5NeA9yqaWhklPDXI .icon-shape .label{text-anchor:middle;}#mermaid-svg-5NeA9yqaWhklPDXI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5NeA9yqaWhklPDXI .rough-node .label,#mermaid-svg-5NeA9yqaWhklPDXI .node .label,#mermaid-svg-5NeA9yqaWhklPDXI .image-shape .label,#mermaid-svg-5NeA9yqaWhklPDXI .icon-shape .label{text-align:center;}#mermaid-svg-5NeA9yqaWhklPDXI .node.clickable{cursor:pointer;}#mermaid-svg-5NeA9yqaWhklPDXI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5NeA9yqaWhklPDXI .arrowheadPath{fill:#333333;}#mermaid-svg-5NeA9yqaWhklPDXI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5NeA9yqaWhklPDXI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5NeA9yqaWhklPDXI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5NeA9yqaWhklPDXI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5NeA9yqaWhklPDXI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5NeA9yqaWhklPDXI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5NeA9yqaWhklPDXI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5NeA9yqaWhklPDXI .cluster text{fill:#333;}#mermaid-svg-5NeA9yqaWhklPDXI .cluster span{color:#333;}#mermaid-svg-5NeA9yqaWhklPDXI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5NeA9yqaWhklPDXI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5NeA9yqaWhklPDXI rect.text{fill:none;stroke-width:0;}#mermaid-svg-5NeA9yqaWhklPDXI .icon-shape,#mermaid-svg-5NeA9yqaWhklPDXI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5NeA9yqaWhklPDXI .icon-shape p,#mermaid-svg-5NeA9yqaWhklPDXI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5NeA9yqaWhklPDXI .icon-shape .label rect,#mermaid-svg-5NeA9yqaWhklPDXI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5NeA9yqaWhklPDXI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5NeA9yqaWhklPDXI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5NeA9yqaWhklPDXI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Output & Formatting Layer
Async Engine
User Interface Layer
Global Management Layer
Manages & Locates
Manages & Locates
(1) Check Level
(1) Check Level
Trace, Debug, Info, etc.
(2) Push Message
(3) Pop Task
Direct Write
Background Write
Diverse Sinks
Console Sink
Formatter
File Sink
Formatter
Network Sink
Formatter
Registry Singleton
Sync Logger
Async Logger
Log Level?
Flush Policy?
Blocking Queue
Thread Pool
创建方式 - logger
- 工厂方法:每个 logger 携带 1 个 sink
- 手动创建:方便给 logger 绑定多个 sink,日志多端输出
工厂方法
c
#include "spdlog/spdlog.h"
#include "spdlog/sinks/basic_file_sink.h"
void factory_example() {
// spdlog::basic_logger_mt 是工厂函数,自动处理 Sink 创建和 Registry 注册
auto file_logger = spdlog::basic_logger_mt("file_logger", "logs/basic-log.txt");
file_logger->info("Hello, Factory Method!");
// 也可以通过全局 Registry 随时找回
spdlog::get("file_logger")->warn("Still here!");
}
手动创建 - logger
- 创建sink
- 创建logger,调用
push_back()将sink加入logger - 将logger注册到registry
- 使用不同级别的日志输出
c
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/basic_file_sink.h"
#include <vector>
void manual_example() {
// 创建不同的 Sinks
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/multisink.txt", true);
// 将 Sinks 放入 vector
std::vector<spdlog::sink_ptr> sinks {console_sink, file_sink};
// 创建 Logger 并绑定 Sinks
auto combined_logger = std::make_shared<spdlog::logger>("multi_sink_logger", sinks.begin(), sinks.end());
// 将 Logger 手动注册到 Registry (方便全局调用)
spdlog::register_logger(combined_logger);
// 设置级别和输出
combined_logger->set_level(spdlog::level::debug);
combined_logger->error("This error goes to both console and file!");
}
方法
| 方法 | 说明 |
|---|---|
| spdlog::info() | 输出info级别的日志 |
| set_level() | 设置日志级别 |
| set_pattern() | 设置日志格式 (已有标签) |
| set_formatter() | 设置日志格式 (自定义格式) |