C++ 日志记录:实践中的最佳实践

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

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

开始课程

引言:为什么日志记录不仅仅是输出文本?



在现代 C++ 开发中,日志记录已超越了简单的 std::cout。它是用于应用程序调试、监控和审计的关键工具。然而,不正确的实现可能导致性能下降、数据丢失或磁盘空间浪费。在本文中,我们将通过具体示例分析 C++ 日志记录的最佳实践,这些示例可立即应用于实际项目。



1. 选择日志记录库:spdlog 与替代方案



C++ 标准库不提供内置的灵活日志记录工具。建议使用经过验证的第三方解决方案。Spdlog 因其高性能和易于集成而成为最流行的库之一。



安装 spdlog(通过 vcpkg 或 header-only 方式)

// 通过 vcpkg 安装vcpkg install spdlog

// 或使用 header-only 版本#include "spdlog/spdlog.h"#include "spdlog/sinks/basic_file_sink.h"#include "spdlog/sinks/rotating_file_sink.h"


日志记录器基本配置示例

#include <memory>#include "spdlog/spdlog.h"#include "spdlog/sinks/stdout_color_sinks.h"

int main() { // 创建带彩色输出的控制台日志记录器 auto console = spdlog::stdout_color_mt("console"); // 设置日志级别 spdlog::set_level(spdlog::level::debug); // 消息示例 console->info("应用程序已启动"); console->warn("检测到潜在问题"); console->error("严重错误: {}", errno); return 0;}


替代方案: Boost.Log(适用于企业级项目),Google Glog(如需与 Google Test 集成)。对于嵌入式系统,请使用 EasyLogger。



2. 日志级别与过滤



正确使用日志级别是保证日志可读性的关键。在 C++ 中,采用以下层级(从最严重到最不严重):



  • TRACE — 详细的执行跟踪(仅用于调试)
  • DEBUG — 调试信息
  • INFO — 应用程序运行信息性消息
  • WARN — 潜在问题警告
  • ERROR — 不影响应用程序运行的错误
  • CRITICAL — 需要立即干预的致命错误


在 spdlog 中配置过滤

// 仅启用 WARN 及以上级别spdlog::set_level(spdlog::level::warn);

// 调试时启用所有级别#ifdef _DEBUG spdlog::set_level(spdlog::level::trace);#endif

// 使用宏的示例#define LOG_TRACE(...) spdlog::trace(__VA_ARGS__)#define LOG_ERROR(...) spdlog::error(__VA_ARGS__)

LOG_TRACE("进入函数 processData()");LOG_ERROR("无法打开文件: {}", filename);


建议: 切勿在生产构建中使用 TRACE —— 由于字符串格式化,它可能将性能降低 10-100 倍。



3. 日志记录性能:同步模式 vs 异步模式



在高负载系统中,同步日志记录可能成为瓶颈。每次调用日志记录器都会阻塞线程直到写入完成。解决方案是异步日志记录。



在 spdlog 中配置异步日志记录器

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

int main() { // 创建队列大小为 8192 的异步日志记录器 spdlog::init_thread_pool(8192, 1); // 1 个处理线程 auto async_file = spdlog::rotating_logger_mt<spdlog::async_factory>( "async_logger", "logs/app.log", 102

博客

书籍推荐