最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ spdlog日志庫示例詳解

 更新時間:2025年12月31日 09:17:10   作者:小灰灰搞電子  
本文詳細介紹了C++的spdlog日志庫,包括其核心優(yōu)勢、核心概念、基本用法、高級用法與特性、性能考量與最佳實踐、編譯與依賴以及庫的下載與編譯,spdlog是一個高性能、功能豐富且易于使用的開源日志庫,適用于各種C++項目,感興趣的朋友跟隨小編一起看看吧

一、spdlog日志庫詳解

C++的 spdlog 日志庫。這是一款高性能、功能豐富且易于使用的開源日志庫。

1. 概述與核心優(yōu)勢

  • 高性能: 這是 spdlog 的核心設(shè)計目標之一。它采用了異步日志記錄機制(可選),將日志消息的格式化、寫入等耗時操作放入后臺線程執(zhí)行,極大地減少了對主線程性能的影響。其性能通常優(yōu)于許多其他C++日志庫。
  • 極簡的頭部引用: 只需包含一個頭文件 #include <spdlog/spdlog.h> 即可開始使用基本功能。
  • 豐富的特性:
    • 支持多種日志級別(trace, debug, info, warn, error, critical)。
    • 支持多種日志目標(控制臺、文件、系統(tǒng)日志、TCP套接字、UDP套接字、Rotating files - 滾動文件、Daily files - 每日文件、Windows debugger 等)。
    • 支持自定義格式(使用類似 printf 的格式化語法或自定義模式)。
    • 支持多線程安全。
    • 支持異步日志(默認是同步的,但可以輕松配置為異步)。
    • 支持日志刷新策略。
    • 支持自定義日志器(logger)和接收器(sink)。
    • 支持全局和特定日志器。
  • 易用性: API設(shè)計簡潔直觀,學(xué)習(xí)曲線平緩。

2. 核心概念

  • 日志器(Logger): 日志記錄的核心對象。每個日志器可以有:
    • 名稱: 用于標識和檢索。
    • 日志級別: 決定哪些級別的消息會被實際記錄。低于設(shè)置級別的消息會被忽略。
    • 接收器(Sinks)列表: 一個或多個輸出目標。日志消息會被發(fā)送到所有關(guān)聯(lián)的接收器。
    • 錯誤處理器: 當寫入失敗時的回調(diào)函數(shù)。
    • 格式化器: 控制日志消息的輸出格式。
  • 接收器(Sink): 負責將格式化后的日志消息輸出到具體的目標。spdlog 提供了多種內(nèi)置接收器:
    • stdout_sink_mt, stderr_sink_mt: 輸出到標準輸出/標準錯誤(多線程安全)。
    • basic_file_sink_mt: 輸出到文件(多線程安全)。
    • rotating_file_sink_mt: 基于文件大小的滾動日志文件。
    • daily_file_sink_mt: 基于時間的每日日志文件(每天或指定時間創(chuàng)建新文件)。
    • syslog_sink_mt: 輸出到Unix系統(tǒng)日志(如 /var/log/syslog)。
    • win_eventlog_sink_mt: 輸出到Windows事件查看器。
    • msvc_sink_mt: 輸出到Visual Studio調(diào)試窗口(僅Windows)。
    • tcp_sink_mt, udp_sink_mt: 輸出到網(wǎng)絡(luò)套接字。
    • dist_sink_mt: 分布式接收器,將消息分發(fā)到多個其他接收器。
    • null_sink_mt: 丟棄所有日志消息(用于測試或禁用)。
    • ostream_sink_mt: 輸出到任意 std::ostream。
    • ansicolor_sink: 支持ANSI顏色代碼的控制臺輸出。
    • android_sink: Android平臺日志輸出。
  • 格式化器(Formatter): 定義了每條日志消息的最終輸出格式。它使用特定的模式字符串來指定如何組合時間戳、日志級別、日志器名稱、線程ID、消息內(nèi)容等。spdlog 默認使用類似以下格式:
    [%Y-%m-%d %H:%M:%S.%e] [%l] [%t] %v
    對應(yīng):[日期 時間] [級別] [線程ID] 消息正文
    你可以使用 set_pattern 自定義格式。
  • 日志級別: 定義了日志消息的嚴重性,從低到高依次為:
    • spdlog::level::trace
    • spdlog::level::debug
    • spdlog::level::info
    • spdlog::level::warn
    • spdlog::level::err
    • spdlog::level::critical
    • spdlog::level::off (關(guān)閉所有日志)
      每個日志器都有自己的級別,低于該級別的消息不會被記錄。全局默認級別可以通過 spdlog::set_level 設(shè)置。

3. 基本用法

#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h> // 文件接收器
#include <spdlog/sinks/stdout_color_sinks.h> // 帶顏色的控制臺接收器
int main() {
    // 創(chuàng)建一個同時輸出到控制臺(帶顏色)和文件的日志器
    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());
    // 設(shè)置日志級別 (全局設(shè)置也可以使用 spdlog::set_level)
    logger->set_level(spdlog::level::debug);
    // 設(shè)置輸出格式 (可選,這里設(shè)置一個簡潔格式)
    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.");
    // 使用我們創(chuàng)建的日志器
    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. 高級用法與特性

異步日志: 創(chuàng)建異步日志器可以顯著提升性能,尤其在高頻日志場景。

#include <spdlog/async.h>
#include <spdlog/sinks/rotating_file_sink.h>
int main() {
    // 創(chuàng)建一個異步日志器工廠 (通常全局一個足夠)
    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);
    // 設(shè)置級別、格式等
    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.");
    // 結(jié)束時,確保關(guān)閉異步日志器 (釋放后臺線程)
    spdlog::drop_all(); // 或者單獨 drop("async_logger")
    return 0;
}
  • 自定義格式化: 使用 set_pattern 方法。模式字符含義:
    • %v - 實際消息文本。
    • %t - 線程ID。
    • %P - 進程ID。
    • %n - 日志器名稱。
    • %l - 日志級別 (短字符:T, D, I, W, E, C)。
    • %L - 日志級別 (長字符:TRACE, DEBUG, INFO, WARN, ERROR, CRITICAL)。
    • %a - 縮寫的星期幾。
    • %A - 完整的星期幾。
    • %b, %h - 縮寫的月份。
    • %B - 完整的月份。
    • %c - 日期時間 (e.g., Thu Aug 23 15:35:46 2018)。
    • %C - 年份 (2位數(shù))。
    • %Y - 年份 (4位數(shù))。
    • %D, %x - 日期 (e.g., 08/23/18)。
    • %T, %X - 時間 (e.g., 15:35:46)。
    • %r - 12小時制時間。
    • %R - 24小時制時間 (HH:MM)。
    • %m - 月份 (數(shù)字)。
    • %d - 日 (數(shù)字)。
    • %H - 小時 (24小時制)。
    • %I - 小時 (12小時制)。
    • %M - 分鐘。
    • %S - 秒。
    • %e - 毫秒。
    • %f - 微秒。
    • %F - 納秒。
    • %p - AM/PM。
    • %z - UTC偏移 (e.g., +0200)。
    • %Z - 時區(qū)名稱。
    • %s - 自紀元以來的秒數(shù)。
    • %g - 自紀元以來的毫秒數(shù)。
    • %u - 自紀元以來的微秒數(shù)。
    • %w - 星期幾 (數(shù)字,0=周日)。
    • %j - 一年中的第幾天。
    • %% - 百分號本身。
    • %^ - 開始顏色范圍。
    • %$ - 結(jié)束顏色范圍。

日志宏: 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(...);
// 帶位置信息的宏 (文件名、行號、函數(shù)名)
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__);
  • 自定義接收器: 你可以繼承 spdlog::sinks::base_sink 類并實現(xiàn)其 sink_itflush 方法,將日志輸出到任何你想要的地方(如數(shù)據(jù)庫、消息隊列等)。
  • 錯誤處理: 可以設(shè)置 logger->set_error_handler([](const std::string &msg) { ... }) 來處理寫入失敗等錯誤。
  • 自動注冊與獲?。?/strong> 使用 spdlog::createspdlog::create_async 創(chuàng)建的日志器會自動注冊到全局注冊表。之后可以通過 spdlog::get("name") 獲取。使用 spdlog::drop_all()spdlog::drop("name") 釋放資源(特別是異步日志器的后臺線程)。

5. 性能考量與最佳實踐

  • 評估是否需要異步: 對于性能要求極高的應(yīng)用,或者日志量非常大的場景,使用異步日志器。但異步日志器在程序異常退出時可能會丟失最后幾條日志(雖然可以通過設(shè)置隊列大小和刷新策略緩解)。
  • 合理設(shè)置日志級別: 生產(chǎn)環(huán)境通常設(shè)置為 infowarn,開發(fā)調(diào)試時可用 debugtrace。避免在循環(huán)中記錄大量低級別日志。
  • 選擇合適的接收器: 文件寫入通常比控制臺慢。rotating_file_sinkdaily_file_sink 有助于管理日志文件大小和數(shù)量。
  • 避免昂貴的操作: 在日志語句中盡量避免執(zhí)行耗時的操作(如復(fù)雜計算、IO操作),尤其是在同步日志模式下。可以先判斷日志級別是否啟用 if (logger->should_log(spdlog::level::debug)) { ... }。
  • 注意格式化開銷: 復(fù)雜的格式化字符串或大量參數(shù)也會帶來開銷。

6. 編譯與依賴

  • 依賴: spdlog 是一個頭文件庫(header-only),但需要依賴一個C++11兼容的編譯器和一個格式化庫(默認使用其內(nèi)置的 fmt 庫分支)。因此,通常只需要包含頭文件即可使用。
  • 編譯選項: 可以通過定義宏來控制 spdlog 的行為:
    • SPDLOG_COMPILED_LIB: 將其編譯為靜態(tài)庫(需要包含 spdlog.cpp)。
    • SPDLOG_FMT_EXTERNAL: 使用外部的 fmt 庫(需確保已安裝)而不是 spdlog 內(nèi)置的版本。
    • SPDLOG_NO_EXCEPTIONS: 禁用異常(在異常被禁用的環(huán)境中使用)。
    • SPDLOG_NO_THREAD_ID: 禁用線程ID記錄(如果獲取線程ID開銷大)。
    • SPDLOG_CLOCK_COARSE: 使用更快的 coarse 時鐘源(精度較低)。
  • 安裝: 可以通過包管理器(如vcpkg, conan)、Git子模塊或直接下載源碼放入項目目錄。

7. 總結(jié)

spdlog 是一個強大、高效且靈活的C++日志庫,幾乎能滿足所有常見的日志記錄需求。其簡潔的API、出色的性能表現(xiàn)(尤其是異步模式)以及豐富的功能(多接收器、自定義格式、多級別)使其成為C++項目中日志組件的優(yōu)秀選擇。無論是快速原型開發(fā)還是大型高性能應(yīng)用,spdlog 都值得考慮。

二、庫的下載與編譯

參考我這篇博文:C++ spdlog日志庫編譯與安裝詳解

三、示例

1、測試代碼

以下是一個較為復(fù)雜的C++ spdlog日志庫使用示例,包含多線程、異步日志、多接收器(sink)和自定義格式設(shè)置:

#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 {
        // 創(chuàng)建異步日志線程池(隊列大小1024,線程數(shù)1)
        spdlog::init_thread_pool(1024, 1);
        // 創(chuàng)建文件接收器(每天輪轉(zhuǎn),最大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");
        // 創(chuàng)建控制臺彩色輸出接收器
        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");
        // 創(chuàng)建異步日志器(組合兩個接收器)
        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); // 設(shè)置日志級別
        // 注冊全局日志器
        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、運行結(jié)果

3、功能說明:

  • 多接收器配置
    • 文件接收器:帶輪轉(zhuǎn)功能(每天/按大?。?/li>
    • 控制臺接收器:帶彩色級別顯示
  • 異步日志
    • 使用線程池處理日志寫入
    • 避免阻塞主線程
  • 自定義格式
    • 時間格式:%Y-%m-%d %H:%M:%S.%e
    • 包含線程ID:%t
    • 級別高亮:%^%l%$
  • 多線程支持
    • 兩個線程同時寫入日志
    • 線程安全保證
  • 異常處理
    • 自定義錯誤回調(diào)
    • 全局異常捕獲
  • 性能優(yōu)化
    • 定期刷新(flush_every
    • 隊列大小控制

到此這篇關(guān)于C++ spdlog日志庫詳解的文章就介紹到這了,更多相關(guān)C++ spdlog日志庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • VC++獲得當前進程運行目錄的方法

    VC++獲得當前進程運行目錄的方法

    這篇文章主要介紹了VC++獲得當前進程運行目錄的方法,可通過系統(tǒng)函數(shù)實現(xiàn)該功能,是非常實用的技巧,需要的朋友可以參考下
    2014-10-10
  • C++實現(xiàn)對RGB圖片進行編碼的示例代碼

    C++實現(xiàn)對RGB圖片進行編碼的示例代碼

    這篇文章主要為大家詳細介紹了如何利用得到的RGB信息重新對RGB圖片進行編碼,以及對其他圖片如BMP所得到的RGB信息進行編碼從而得到*.jpg文件,感興趣的可以了解一下
    2023-05-05
  • 用C語言實現(xiàn)通訊錄

    用C語言實現(xiàn)通訊錄

    這篇文章主要為大家詳細介紹了用C語言實現(xiàn)通訊錄,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C++中auto_ptr智能指針的用法詳解

    C++中auto_ptr智能指針的用法詳解

    這篇文章主要介紹了C++中auto_ptr智能指針的用法詳解的相關(guān)資料,需要的朋友可以參考下
    2016-07-07
  • C++?折疊參數(shù)包詳解(悄然增強編程效率)

    C++?折疊參數(shù)包詳解(悄然增強編程效率)

    折疊參數(shù)就是一個參數(shù)包, 代表是多個未知,tuple元組就是一個折疊參數(shù)的使用,這篇文章主要介紹了C++?折疊參數(shù)包悄然增強編程效率,需要的朋友可以參考下
    2023-05-05
  • C語言深入淺出分析函數(shù)指針

    C語言深入淺出分析函數(shù)指針

    函數(shù)指針是一個指針變量,它可以存儲函數(shù)的地址,然后使用函數(shù)指針,下面這篇文章主要給大家介紹了關(guān)于C語言進階教程之函數(shù)指針的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • C/C++中線程基本概念與創(chuàng)建詳解

    C/C++中線程基本概念與創(chuàng)建詳解

    線程是在進程中產(chǎn)生的一個執(zhí)行單元,是CPU調(diào)度和分配的最小單元,其在同一個進程中與其他線程并行運行,他們可以共享進程內(nèi)的資源。本文就和大家一起聊聊線程基本概念以及如何創(chuàng)建多線程,需要的可以參考一下
    2022-09-09
  • C語言 語義陷阱超詳細梳理總結(jié)

    C語言 語義陷阱超詳細梳理總結(jié)

    這篇文章主要介紹了C語言常見的一些語義陷阱,梳理的比較全面,對我們做開發(fā)的過程中有一定幫助,感興趣的朋友快來看看吧
    2022-03-03
  • 詳解C++內(nèi)存的代碼區(qū),全局區(qū),棧區(qū)和堆區(qū)

    詳解C++內(nèi)存的代碼區(qū),全局區(qū),棧區(qū)和堆區(qū)

    這篇文章主要為大家介紹了C++內(nèi)存的代碼區(qū),全局區(qū),棧區(qū)和堆區(qū),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • C++ const修飾變量和修飾函數(shù)介紹

    C++ const修飾變量和修飾函數(shù)介紹

    這篇文章主要介紹了C++ const修飾變量和修飾函數(shù)介紹,本文直接用實例來講解各自的作用,并總結(jié)了各自的使用技巧,需要的朋友可以參考下
    2015-03-03

最新評論

延庆县| 河曲县| 定西市| 嘉善县| 阿瓦提县| 河西区| 洞口县| 华亭县| 潜江市| 和顺县| 陆川县| 肥乡县| 平安县| 柏乡县| 大丰市| 安义县| 贵港市| 新郑市| 宿州市| 金坛市| 虹口区| 河北省| 双辽市| 焉耆| 德庆县| 菏泽市| 邳州市| 蒙自县| 青田县| 金昌市| 揭西县| 开远市| 石家庄市| 遂溪县| 安国市| 临邑县| 临沧市| 天津市| 顺平县| 新余市| 醴陵市|