小工具知识网

当前位置: 首页 > 行业知识 > C++高性能日志库spdlog使用指南

行业知识

C++高性能日志库spdlog使用指南

2026-11-03 08:19:14 来源:互联网转载

spdlog库简介

  • spdlog 是一个高性能的 C++ 日志库,它设计时充分考虑了速度和易用性,具有以下特点
    • 高效与快速:Spdlog 专注于提供极致的性能,在大量日志记录场景下也能保持较低的延迟和较高的吞吐量。
    • 轻量化设计:Spdlog 是头文件(header-only)库,这意味着用户只需要包含相应的头文件即可开始使用,无需编译链接额外的库文件。
    • 跨平台支持:它支持多种操作系统,包括但不限于 Windows、Linux 和 macOS,并且在这些平台上都能够良好运行。
    • 丰富的日志级别:Spdlog 支持常见的日志级别,如 TRACE、DEBUG、INFO、WARN、ERROR、CRITICAL 等,用户可以根据需要选择不同级别的日志输出。
    • 格式化与定位信息:通过集成 fmt 库,Spdlog 允许用户自定义日志消息的格式,可以轻松地包含时间戳、线程ID、文件名、行号以及函数名等上下文信息。
    • 多目标输出:可以将日志输出到控制台、普通文本文件、循环写入文件(rotating log files)、每日生成新文件(daily logs)、系统日志等目标,同时也支持异步写入以提高性能。
    • 线程安全:对于多线程环境,Spdlog 提供了线程安全的日志接口,确保在并发环境下日志记录的正确性和完整性。
    • 异步模式:提供可选的异步日志记录机制,能够将日志操作放入后台线程执行,从而避免阻塞主线程。
    • 条件日志:根据预定义的条件开关,可以动态启用或禁用特定级别的日志输出。

      使用步骤

      • spdlog库的使用也非常简单,只需要下载源代码,然后把根目录下的include目录下的文件拷贝到我们的工程下,在工程中包含相应的头文件即可。

        实例演示

        控制台打印

        • 首先看下最简单的使用,如何在控制台打印以及如何进行参数化打印。
        • main.cpp
        •   #include   #include   #include     int main()  {  // 普通打印  spdlog::info("Welcome to info spdlog!");    // 格式化打印  // 打印字符串  spdlog::info("Hello World {}", "spdlog!");  // 打印数字  spdlog::error("spdlog errCode : {}", -10020);  // 指定打印数字的占位符  spdlog::warn("spdlog format char {:08d}", 12);  // 格式化打印不同进制的数据  spdlog::critical("Support for int:{0:d} hex:{0:x} oct:{0:o} bin:{0:b}", 42);  // 打印浮点型数据  spdlog::info("float args are {:03.2f}", 1.23456);  // 打印多个参数  spdlog::info("string args are {0} {1}..", "too", "supported");  spdlog::info("number args are {0} {1} {2}..", 10020, 10040, -100);    system("pause");  }
        • 执行结果
        • 这里参数化打印的实现是通过 {} 实现的,跟常见函数的参数化打印有点不一样。

          在文件中打印日志

          • 接下来就看下如何在文件中打印日志
          • main.cpp
          •   #include   #include   #include   #include     int main()  {  try  {  // 参数1 日志标识符, 参数2 日志文件名  std::shared_ptr mylogger = spdlog::basic_logger_mt("spdlog", "spdlog.log");  // 设置日志格式. 参数含义: [日志标识符] [日期] [日志级别] [线程号] [数据]  mylogger->set_pattern("[%n][%Y-%m-%d %H:%M:%S.%e] [%l] [%t]  %v");  mylogger->set_level(spdlog::level::debug);  spdlog::flush_every(std::chrono::seconds(5)); // 定期刷新日志缓冲区    mylogger->trace("Welcome to info spdlog!");  mylogger->debug("Welcome to info spdlog!");  mylogger->info("Welcome to info spdlog!");  mylogger->warn("Welcome to info spdlog!");  mylogger->error("Welcome to info spdlog!");  mylogger->critical("Welcome to info spdlog!");    // 刷新  mylogger->flush_on(spdlog::level::debug);  }  catch (const spdlog::spdlog_ex& ex)  {  std::cout   try  {  std::shared_ptrflush();  }  catch (const spdlog::spdlog_ex& ex)  {  std::cout   try  {  // 基本文件  std::shared_ptrtrace("Welcome to info spdlog!");  my_logger->debug("[{0}:{1}] Welcome to info spdlog!", __FILENAME__, __LINE__);  my_logger->info("[{0}:{1}] Welcome to info spdlog!", __FILENAME__, __LINE__);  my_logger->error("Welcome to info spdlog!");    my_logger->flush();    system("pause");  }  catch (const spdlog::spdlog_ex& ex)  {  std::cout   try  {  // 基本文件  std::shared_ptrtrace("Welcome to info spdlog!");  my_logger->debug("[{0}:{1}] Welcome to info spdlog!", __FILENAME__, __LINE__);  my_logger->info("[{0}:{1}] Welcome to info spdlog!", __FILENAME__, __LINE__);  my_logger->error("Welcome to info spdlog!");    myFuncPrint();    my_logger->flush();    system("pause");  }  catch (const spdlog::spdlog_ex& ex)  {  std::cout   std::shared_ptrinfo("[{0}:{1}] Welcome to myFuncPrint!", __FILENAME__, __LINE__);  mylogger->error("Welcome to myFuncPrint!");  }
          • 在main函数中定义了 mylogger 对象后,在其他文件中通过 spdlog::get 获取到这个对象,就可以打印了。
          • 打印结果

            在线程中打印

            • main.cpp
            •   #include   #include   #include   #include   #include   #include     unsigned int __stdcall ThreadFun(PVOID lpParam) {  std::shared_ptr mylogger = spdlog::get("spdlog");    mylogger->trace("Welcome to ThreadFun!");  mylogger->debug("Welcome to ThreadFun!");  mylogger->info("Welcome to ThreadFun!");  mylogger->error("Welcome to ThreadFun!");    return 0;  }      int main()  {  try  {  // 基本文件  std::shared_ptr my_logger = spdlog::basic_logger_mt("spdlog", "spdlog.txt");  // 设置日志格式. 参数含义: [日志标识符] [日期] [日志级别] [线程号] [数据]  my_logger->set_pattern("[%n][%Y-%m-%d %H:%M:%S.%e] [%l] [%t] %v");  my_logger->set_level(spdlog::level::debug);  spdlog::flush_every(std::chrono::seconds(5)); // 定期刷新日志缓冲区    my_logger->trace("Welcome to trace spdlog!");  my_logger->debug("Welcome to debug spdlog!");  my_logger->info("Welcome to info spdlog!");  my_logger->error("Welcome to error spdlog!");    HANDLE handle1 = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, NULL, 0, NULL);  HANDLE handle2 = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, NULL, 0, NULL);  HANDLE handle3 = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, NULL, 0, NULL);    //永久等待线程运行结束  WaitForSingleObject(handle1, INFINITE);  WaitForSingleObject(handle2, INFINITE);  WaitForSingleObject(handle3, INFINITE);    // 刷新缓冲区  my_logger->flush();    system("pause");  }  catch (const spdlog::spdlog_ex& ex)  {  std::cout 

上一篇:揭秘FlashFXP源码,深入解析FTP客户端的神秘世界

下一篇:揭秘重置所有设置的后果,意想不到的重启冒险之旅