C++ 应用程序中的日志记录:最佳实践与工具

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程
```html

C++ 应用程序中的日志记录:最佳实践



日志记录是任何严肃 C++ 软件开发的基础部分。没有可靠的日志记录系统,调试复杂错误、监控性能和安全审计几乎不可能。在本文中,我们将探讨 C++ 中日志记录的最佳实践,从库的选择到高级格式化和文件轮转技术。



1. 选择日志记录库



C++ 中有几个成熟的日志记录库。放弃自己实现而选择现成的解决方案可以节省时间并减少错误数量。



  • spdlog — 最流行的库。具有高性能(header-only、异步模式)、简单的 API 以及对多种格式(JSON、纯文本)的支持。
  • Boost.Log — 来自 Boost 的一个功能强大但更重量级的库。非常适合需要复杂过滤和灵活后端配置的企业级项目。
  • Google Logging (glog) — 来自 Google 的简单库。非常适合小型项目,但灵活性较差。


spdlog 初始化示例:



#include <spdlog/spdlog.h>#include <spdlog/sinks/basic_file_sink.h>

int main() { // 创建一个写入文件 "logs/app.log" 的记录器 auto logger = spdlog::basic_logger_mt("file_logger", "logs/app.log"); // 设置日志级别 logger->set_level(spdlog::level::debug); // 记录消息 logger->info("应用程序已启动"); return 0;}


2. 日志级别和过滤



使用日志级别(trace、debug、info、warning、error、critical)是事实上的标准。它们允许根据环境(开发、测试、生产)灵活配置输出的信息量。



级别建议:

  • Trace/Debug — 仅用于开发。关于执行流程、变量值的详细信息。
  • Info — 标准事件:服务启动/停止、成功操作。
  • Warning — 不会导致错误的异常情况(例如,使用过时的 API)。
  • Error — 需要注意但非致命的错误。
  • Critical — 致命错误,应用程序无法继续运行。


在 spdlog 中配置过滤的示例:



// 在生产环境中只记录 warning 及以上级别auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();console_sink->set_level(spdlog::level::warn);

// 在文件中记录所有内容,包括 debugauto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/debug.log");file_sink->set_level(spdlog::level::debug);

auto logger = std::make_shared<spdlog::logger>("multi_sink", spdlog::sinks_init_list({console_sink, file_sink}));

spdlog::register_logger(logger);


3. 性能和异步日志记录



同步日志记录可能成为性能瓶颈,尤其是在高负载系统中。每次调用 logger->info(...) 都会阻塞线程,直到写入磁盘完成。



性能最佳实践:

  • 异步日志记录 — 使用单独的线程进行日志写入。spdlog 开箱即支持此功能。
  • 避免在日志字符串中进行昂贵操作 — 不要在日志宏内部调用重型函数。例如,logger->info("Result: {}", computeExpensiveValue()); 即使日志级别未达到也会调用 computeExpensiveValue()。
  • ```

博客

书籍推荐