日志_图解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() 设置日志格式 (自定义格式)
相关推荐
gCode Teacher 格码致知2 小时前
Pandas教学-17:Series与Dataframe的关系
开发语言·python·pandas
发量惊人的中年网工2 小时前
分公司访问总部ERP慢怎么办?SD-WAN组网的排查与验收要点
服务器·开发语言·php
下页、再停留2 小时前
【C#桌面客户端系列学习-15】生成可视化图表之折线图、柱状图、饼状图
开发语言·c#
ShineWinsu2 小时前
对于JavaScript:操作元素的解析
开发语言·前端·javascript·面试·web·dom·元素
益莱储中国4 小时前
深度解析:RF 实验室从 5G迈向 6G 的过程中保持技术领先与设备升级的路径
开发语言·php
丰色木夕4 小时前
Ubuntu22.04下源码编译安装USD-Brep
c++·ubuntu·nvidia·usd-brep
benchmark_cc5 小时前
Python 量化系统如何设计统一的数据访问接口:从策略解耦到数据层架构
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
const_qiu5 小时前
第四章 00:开篇 —— 从「会聊天」到「记得住、会干活、能协作」
java·开发语言·人工智能·python
Wang's Blog5 小时前
Java 项目实战: 交友项目 - 个人资料管理的更新接口实现与坑
java·开发语言·交友
CoderYanger5 小时前
Java EE 进阶:4.Spring Web MVC 入门(第一弹)
java·开发语言·前端·spring·面试·java-ee·mvc