日志_图解spdlog

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() 设置日志格式 (自定义格式)
相关推荐
老秦包你会37 分钟前
计算机网络第二课 ----Socket(套接字)编程预备
开发语言·计算机网络·php
旖旎夜光38 分钟前
【C++ 基础入门】C++多态(下):单/多继承虚表、多态补充与 21 道高频题
开发语言·c++·笔记·学习
Wang's Blog10 小时前
Java 项目实战: 交友项目 - FastDFS:入门案例
java·开发语言·交友
apcipot_rain11 小时前
C++转Java日记(03)
java·开发语言·c++
布莱克60511 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map
xys_67811 小时前
深挖C++:类和对象(中)
开发语言·c++
灿飞屋11 小时前
Rust 编程其实很简单
开发语言·rust
MOONICK13 小时前
QT元数据
开发语言·qt
D e re k ZH14 小时前
C++ 系统学习手记:从语法细节到工程实践
开发语言·数据结构·c++·算法
灿飞屋15 小时前
Kotlin与Java虚拟机三:控制流
android·java·开发语言·后端·python·kotlin·安卓