日志_图解spdlog

spdlog架构

  • registry:全局单例管理中心
    • 负责统一管理所有的 Logger、Sinks 和线程池资源。
    • 提供通过名称获取 Logger 实例的能力,确保全局访问的一致性
  • loggers:负责记录日志消息,是用户直接调用的接口
    • 控制 Flush 策略:决定何时将缓冲区数据强制刷新到目标存储中
    • 控制日志级别 :支持 tracedebuginfowarnerrorcritical 六种级别
  • 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() 设置日志格式 (自定义格式)
相关推荐
hansang_IR2 小时前
【题解】P4454 [CQOI2018] 破解D-H协议
c++·算法·密码学·数论
梓䈑2 小时前
【动态规划系列】路径问题、子数组 和 子序列问题、背包问题
c++·算法·动态规划
aqiu1111112 小时前
【数位 DP / 记忆化搜索】蓝桥云课 - 光轨区的 AI 数 题解
c++·算法·蓝桥杯·数位dp
CodeStats2 小时前
【Java类加载器】Java 类加载器完整体系深度拆解(下):自定义加载器实战与 SPI 破坏双亲委派(MySQL 驱动揭秘)
java·开发语言·jvm·classloader·双亲委派
砚底藏山河2 小时前
并发与限频工程:把20只的2秒压到0.5秒不封号(魔码量化实战 #03)
java·开发语言·数据库·python·金融
欧特克_Glodon2 小时前
OpenCV计算机视觉开发入门与实践<三十七>:OpenCV中的机器学习
c++·opencv·机器学习·计算机视觉
云雀衔光2 小时前
MCP 协议全景:为什么它是 AI 连接工具的「USB-C」
java·开发语言·数据库·人工智能·ai编程
geovindu2 小时前
go: Task Scheduler
开发语言·后端·golang
会飞的拖把3 小时前
Python 多任务编程:并发、进程、线程与线程安全详解
开发语言·python