C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++ spdlog日志库

C++ spdlog日志库示例详解

作者:小灰灰搞电子

本文详细介绍了C++的spdlog日志库,包括其核心优势、核心概念、基本用法、高级用法与特性、性能考量与最佳实践、编译与依赖以及库的下载与编译,spdlog是一个高性能、功能丰富且易于使用的开源日志库,适用于各种C++项目,感兴趣的朋友跟随小编一起看看吧

一、spdlog日志库详解

C++的 spdlog 日志库。这是一款高性能、功能丰富且易于使用的开源日志库。

1. 概述与核心优势

2. 核心概念

3. 基本用法

#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h> // 文件接收器
#include <spdlog/sinks/stdout_color_sinks.h> // 带颜色的控制台接收器
int main() {
    // 创建一个同时输出到控制台(带颜色)和文件的日志器
    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/basic-log.txt", true); // true 表示覆盖而非追加
    std::vector<spdlog::sink_ptr> sinks{console_sink, file_sink};
    auto logger = std::make_shared<spdlog::logger>("my_logger", sinks.begin(), sinks.end());
    // 设置日志级别 (全局设置也可以使用 spdlog::set_level)
    logger->set_level(spdlog::level::debug);
    // 设置输出格式 (可选,这里设置一个简洁格式)
    logger->set_pattern("[%H:%M:%S] [%l] %v");
    // 注册此日志器,之后可通过名称获取 (可选)
    spdlog::register_logger(logger);
    // 使用默认全局日志器 (快速开始)
    spdlog::info("This is an info message using the default global logger.");
    spdlog::warn("This is a warning message.");
    // 使用我们创建的日志器
    logger->debug("This is a debug message.");
    logger->error("Some error occurred: {}", 42); // 格式化,类似 `printf`
    logger->critical("Critical error! Exiting...");
    // 刷新日志 (确保所有消息都写入目标,特别是对于文件。异步日志器通常自动处理)
    logger->flush();
    // 通过名称获取已注册的日志器
    auto same_logger = spdlog::get("my_logger");
    same_logger->info("Retrieved logger by name.");
    return 0;
}

4. 高级用法与特性

异步日志: 创建异步日志器可以显著提升性能,尤其在高频日志场景。

#include <spdlog/async.h>
#include <spdlog/sinks/rotating_file_sink.h>
int main() {
    // 创建一个异步日志器工厂 (通常全局一个足够)
    auto async_factory = spdlog::create_async<my_logger_name>("async_logger");
    // 添加接收器 (例如一个滚动文件接收器)
    auto rotating_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("logs/rotating-log.txt", 1024 * 1024 * 5, 3); // 5MB大小,保留3个备份
    async_factory->add_sink(rotating_sink);
    // 设置级别、格式等
    async_factory->set_level(spdlog::level::info);
    async_factory->set_pattern("%^[%L]%$ %v"); // %^ %$ 用于颜色控制
    // 获取并使用异步日志器
    auto async_logger = spdlog::get("async_logger");
    async_logger->info("This message is logged asynchronously.");
    // 结束时,确保关闭异步日志器 (释放后台线程)
    spdlog::drop_all(); // 或者单独 drop("async_logger")
    return 0;
}

日志宏: spdlog 提供了方便的宏,可以自动记录 __FILE__, __LINE__, __func__ 等信息。

#include <spdlog/spdlog.h>
#include <spdlog/fmt/ostr.h> // 对于自定义类型输出可能需要
// 基本宏
LOG_TRACE(...);
LOG_DEBUG(...);
LOG_INFO(...);
LOG_WARN(...);
LOG_ERROR(...);
LOG_CRITICAL(...);
// 带位置信息的宏 (文件名、行号、函数名)
SPDLOG_TRACE(...);
SPDLOG_DEBUG(...);
SPDLOG_INFO(...);
SPDLOG_WARN(...);
SPDLOG_ERROR(...);
SPDLOG_CRITICAL(...);
// 示例
int value = 42;
SPDLOG_INFO("The value is {}", value);
SPDLOG_ERROR("Error in function {} at line {}", __func__, __LINE__);

5. 性能考量与最佳实践

6. 编译与依赖

7. 总结

spdlog 是一个强大、高效且灵活的C++日志库,几乎能满足所有常见的日志记录需求。其简洁的API、出色的性能表现(尤其是异步模式)以及丰富的功能(多接收器、自定义格式、多级别)使其成为C++项目中日志组件的优秀选择。无论是快速原型开发还是大型高性能应用,spdlog 都值得考虑。

二、库的下载与编译

参考我这篇博文:C++ spdlog日志库编译与安装详解

三、示例

1、测试代码

以下是一个较为复杂的C++ spdlog日志库使用示例,包含多线程、异步日志、多接收器(sink)和自定义格式设置:

#include <spdlog/spdlog.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/async.h>
#include <thread>
#include <iostream>
int main() {
    try {
        // 创建异步日志线程池(队列大小1024,线程数1)
        spdlog::init_thread_pool(1024, 1);
        // 创建文件接收器(每天轮转,最大3个文件,单个文件最大50MB)
        auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
            "logs/mylog.log", 50 * 1024 * 1024, 3
        );
        file_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [%t] %v");
        // 创建控制台彩色输出接收器
        auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
        console_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] %v");
        // 创建异步日志器(组合两个接收器)
        std::vector<spdlog::sink_ptr> sinks{file_sink, console_sink};
        auto async_logger = std::make_shared<spdlog::async_logger>(
            "async_logger", sinks.begin(), sinks.end(), spdlog::thread_pool()
        );
        async_logger->set_level(spdlog::level::trace); // 设置日志级别
        // 注册全局日志器
        spdlog::register_logger(async_logger);
        spdlog::set_default_logger(async_logger);
        // 自定义错误处理
        spdlog::flush_every(std::chrono::seconds(3)); // 每3秒刷新到磁盘
        spdlog::set_error_handler([](const std::string& msg) {
            std::cerr << "Log error: " << msg << std::endl;
        });
        // 多线程日志测试
        auto log_func = []() {
            for (int i = 0; i < 100; ++i) {
                SPDLOG_TRACE("Trace message {}", i);
                SPDLOG_DEBUG("Debug message {}", i);
                SPDLOG_INFO("Info message {}", i);
                SPDLOG_WARN("Warning message {}", i);
                SPDLOG_ERROR("Error message {}", i);
                SPDLOG_CRITICAL("Critical message {}", i);
            }
        };
        std::thread t1(log_func);
        std::thread t2(log_func);
        t1.join();
        t2.join();
        // 显式刷新确保所有日志写入
        spdlog::shutdown();
    } catch (const spdlog::spdlog_ex& ex) {
        std::cerr << "Log exception: " << ex.what() << std::endl;
    }
    return 0;
}

2、运行结果

3、功能说明:

到此这篇关于C++ spdlog日志库详解的文章就介绍到这了,更多相关C++ spdlog日志库内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文