日志库 Spdlog

1.Spdlog

  • 用途:快速且易于使用的 C++ 日志库。
  • 使用场景:记录服务器运行时的各种信息,便于调试和问题排查。

可以输出报错的行数,代码:日志输出中要携带文件名、行数或函数名时,必须使用SPDLOG_LOGGER_*宏,

spdlog中字符串格式化使用fmt(https://github.com/fmtlib/fmt)库。

可以使用循环文件(超过设定大小删除之前的日志),每日文件(日期命名)

2.编写一个例子,在多线程中测试spdlog库的循环日志文件功能
这里是同步写入的


#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"

#include <thread>
#include <vector>

void log_messages(std::shared_ptr<spdlog::logger> logger) {
    for (int i = 0; i < 100; ++i) {
        logger->info("Logging message {}", i);
    }
}

int main() {
    // 创建一个循环日志记录器
    auto rotating_logger = spdlog::rotating_logger_mt(
        "rotating_logger", 
        "logs/rotating_log.txt", 
        1024 * 1024 * 5, // 每个文件最大5MB
        3); // 最多保留3个文件

    // 设置日志级别为 info
    rotating_logger->set_level(spdlog::level::info);
过滤掉info级别以下的日志

    // 设置日志模式以包含线程ID
    logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%t] [%^%l%$] %v");

    // 启动多个线程进行日志记录
    const int num_threads = 5;
    std::vector<std::thread> threads;

    for (int i = 0; i < num_threads; ++i) {
        threads.emplace_back(log_messages, rotating_logger);
    }

    // 等待所有线程完成
    for (auto& t : threads) {
        t.join();
    }

    return 0;
}

3.异步写入循环文件

#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/async.h"

#include <thread>
#include <vector>

// 定义全局日志记录器
std::shared_ptr<spdlog::logger> rotating_logger;

void log_messages() {
    for (int i = 0; i < 100; ++i) {
        rotating_logger->info("Logging message {}", i);
异步模式下,默认情况下不需要手动开启定时刷新,因为后台线程会持续处理队列中的日志消息并适时地写入磁盘。
    }
}

int main() {
    // 初始化异步日志队列
    spdlog::init_thread_pool(8192, 1); // 队列大小和线程数

    // 创建一个旋转日志接收器
    auto rotating_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
        "logs/rotating_log.txt",
        1024 * 1024 * 5, // 每个文件最大5MB
        3); // 最多保留3个文件

    // 创建一个异步日志记录器并将旋转日志接收器添加到其中
    rotating_logger = std::make_shared<spdlog::async_logger>(
        "rotating_logger",
        rotating_sink,
        spdlog::thread_pool(),
        spdlog::async_overflow_policy::block);
    //or 或者使用 spdlog::async_overflow_policy::overrun_oldest 来覆盖最旧的日志

    // 设置日志级别为 info
    rotating_logger->set_level(spdlog::level::info);

    // 设置日志模式以包含线程ID
    rotating_logger->set_pattern("%t [%Y-%m-%d %H:%M:%S.%e] [%^%l%$] %v");

    // 注册全局日志记录器
    spdlog::register_logger(rotating_logger);

    // 启动多个线程进行日志记录
    const int num_threads = 5;
    std::vector<std::thread> threads;

    for (int i = 0; i < num_threads; ++i) {
        threads.emplace_back(log_messages);
    }

    // 等待所有线程完成
    for (auto& t : threads) {
        t.join();
    }

    // 关闭所有日志记录器
    spdlog::drop_all();

    return 0;
}
  1. 大型项目如果多个模块日志分开记录,则可以
    在init中注册多个文件日志记录器,然后使用spdlog::get()获取
    在关键点手动调用 logger->flush() 方法来立即把队列中的日志消息写入磁盘
#include "spdlog/spdlog.h"
#include "spdlog/rotating_logger.h"

void setup_logging() {
    // 创建并注册一个轮转日志记录器
    auto rotating_logger = spdlog::rotating_logger_mt("rotating_logger", "logs/rotating_log.txt", 1024 * 1024 * 5, 3);
    spdlog::register_logger(rotating_logger);
}

int main() {
    setup_logging(); // 初始化日志系统

    // 获取之前注册的 logger
    auto logger = spdlog::get("rotating_logger");
    if (logger) {
        logger->info("This is an info message.");
    } else {
        std::cerr << "Logger not found!" << std::endl;
    }

    return 0;
}

posted on   不败剑坤  阅读(45)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示