news 2026/4/16 19:48:26

C++高效日志与命令行解析实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++高效日志与命令行解析实战

好的,这是一个关于如何在 C++ 项目中结合使用gflags进行命令行参数解析和spdlog实现高性能日志记录的实战指南。

目标:让程序能够方便地通过命令行配置参数,并将运行信息高效、灵活地记录到日志中。

核心组件:

  1. gflags:Google 的命令行标志库,用于解析和存储命令行参数。
  2. spdlog:一个高性能、功能丰富的 C++ 日志库。

步骤指南:

1. 引入依赖

确保你的项目已经包含了gflagsspdlog库。可以通过包管理器(如 vcpkg, conan)或直接下载源码编译集成。

2. 定义命令行参数 (使用 gflags)

在你的主程序文件(如main.cpp)或专门的配置文件中,使用DEFINE_xxx宏来定义你需要的命令行参数。常用类型有:

#include <gflags/gflags.h> // 定义字符串参数,默认值 "info", 描述 "日志级别" DEFINE_string(log_level, "info", "日志级别 (trace, debug, info, warn, error, critical, off)"); // 定义整数参数,默认值 1048576, 描述 "日志队列大小" DEFINE_int32(log_queue_size, 1048576, "异步日志队列大小(字节)"); // 定义布尔参数,默认值 true, 描述 "是否启用异步日志" DEFINE_bool(log_async, true, "启用异步日志记录"); // 定义文件路径参数,默认值空, 描述 "日志文件路径" DEFINE_string(log_file, "", "日志文件路径(空则输出到控制台)"); // 其他需要的参数...

3. 初始化 gflags 和 解析命令行

main函数开始处,初始化gflags并解析命令行参数:

int main(int argc, char** argv) { // 初始化 gflags,解析命令行参数 gflags::ParseCommandLineFlags(&argc, &argv, true); // true 表示移除已解析的标志,argv 只保留非标志参数 // ... 后续程序逻辑 ... }

4. 初始化 spdlog 日志系统 (基于 gflags 参数)

使用gflags定义的参数值来配置spdlog日志器:

#include <spdlog/spdlog.h> #include <spdlog/async.h> // 异步日志需要 #include <spdlog/sinks/basic_file_sink.h> #include <spdlog/sinks/stdout_color_sinks.h> // 根据 log_level 参数设置全局日志级别 std::string level_str = FLAGS_log_level; spdlog::level::level_enum log_level = spdlog::level::from_str(level_str); // 将字符串转换为日志级别枚举 // 创建 sink(输出目标)的 vector std::vector<spdlog::sink_ptr> sinks; // 总是添加控制台 sink(带颜色) sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); // 如果指定了日志文件,添加文件 sink if (!FLAGS_log_file.empty()) { try { auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(FLAGS_log_file, true); // true 表示截断文件 sinks.push_back(file_sink); } catch (const spdlog::spdlog_ex& ex) { spdlog::error("创建日志文件失败: {}", ex.what()); // 处理错误,可能只保留控制台日志 } } // 创建日志器 std::shared_ptr<spdlog::logger> logger; if (FLAGS_log_async) { // 创建异步日志器 (高性能) spdlog::init_thread_pool(FLAGS_log_queue_size, 1); // 队列大小来自 gflags 参数 logger = std::make_shared<spdlog::async_logger>( "main_logger", sinks.begin(), sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block // 队列满时阻塞 ); } else { // 创建同步日志器 logger = std::make_shared<spdlog::logger>("main_logger", sinks.begin(), sinks.end()); } // 设置日志格式 (可选,根据需要自定义) logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [thread %t] %v"); // 设置日志级别 (来自 gflags 参数) logger->set_level(log_level); // 注册为全局日志器 (可选) spdlog::register_logger(logger); spdlog::set_default_logger(logger); // ... 后续程序逻辑,开始使用 logger 记录日志 ...

5. 在代码中使用 spdlog 记录日志

在程序的任何地方,都可以使用spdlog的宏或全局logger对象记录日志:

// 使用全局默认日志器 (如果注册了) spdlog::info("程序启动成功!"); spdlog::debug("调试信息: 参数 log_level={}, log_async={}", FLAGS_log_level, FLAGS_log_async); // 或者使用命名的日志器对象 (推荐) logger->warn("这是一个警告信息!"); logger->error("发生了一个错误!错误码: {}", 404); try { // ... 可能抛出异常的代码 ... } catch (const std::exception& e) { logger->critical("发生未捕获的异常: {}", e.what()); }

6. 程序退出前清理 (可选)

main函数返回前,可以显式关闭日志系统以确保所有日志消息都被刷新:

// ... 程序结束前的代码 ... spdlog::shutdown(); // 关闭所有日志器并释放资源 return 0; }

编译命令示例 (Linux/g++)

g++ -std=c++17 -O2 -o myapp main.cpp -lgflags -lspdlog -lpthread
  • -std=c++17: 指定 C++ 标准版本(spdlog常用特性)。
  • -O2: 优化级别。
  • -lgflags: 链接gflags库。
  • -lspdlog: 链接spdlog库。
  • -lpthread: 链接 pthread 库(spdlog的异步日志需要)。

使用示例

# 默认参数运行 (日志级别info, 异步, 输出到控制台) ./myapp # 指定日志级别为debug,关闭异步,输出到文件 ./myapp --log_level=debug --log_async=false --log_file=app.log # 查看帮助 (gflags 自动生成) ./myapp --help

优势总结

  1. 便捷配置:gflags使得命令行参数定义、解析和访问变得极其简单,程序行为高度可配置。
  2. 高性能日志:spdlog的异步日志模式能显著减少 I/O 阻塞,保证程序主线程的性能,队列大小可调。
  3. 灵活性:日志级别、输出目标(控制台/文件)、格式均可通过命令行参数或代码动态调整。
  4. 易用性:spdlog的 API 简洁明了,日志记录语句清晰易读。
  5. 线程安全:两者都支持多线程环境。

通过遵循这个指南,你可以轻松地在你的 C++ 项目中实现强大的命令行参数处理和高效、灵活的日志记录功能。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 18:24:33

基于PLC的变频恒压供水系统设计

目录PLC变频恒压供水系统概述系统核心组成控制策略与原理节能优势分析典型设计流程应用案例源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;PLC变频恒压供水系统概述 PLC变频恒压供水系统通过可编程逻辑控制器&#xff08;PLC&#xff…

作者头像 李华
网站建设 2026/4/16 13:15:04

Whisper-large-v3惊艳表现:音乐背景中人声分离后转录准确率提升37%案例

Whisper-large-v3惊艳表现&#xff1a;音乐背景中人声分离后转录准确率提升37%案例 1. 这不是普通语音识别&#xff0c;是听清嘈杂世界的新方式 你有没有试过在咖啡馆里录一段采访&#xff0c;结果回放时满耳都是背景爵士乐&#xff0c;人声像被裹在棉花里&#xff1f;或者会…

作者头像 李华
网站建设 2026/4/16 13:15:03

multiprocessing.Pool 中 starmap 与 imap_unordered

在 Python 中,multiprocessing.Pool 是实现多进程并行计算的常用工具。其中,starmap 和 imap_unordered 都能用来并行执行函数,但它们的行为、性能特点和适用场景有很大不同。很多开发者在选择时容易混淆。本文将通过清晰的解释和一个实际性能对比示例,帮助你理解两者的区别…

作者头像 李华
网站建设 2026/4/16 14:20:19

系统思考:创造价值并非卖时间

赚钱的第一性原理&#xff0c;是创造价值&#xff0c;而不是出卖时间。创造价值的第一性原理&#xff0c;是解决问题&#xff0c;而不是提供劳动。 解决问题的第一性原理&#xff0c;是识别真需求&#xff0c;而不是自我感动。识别真需求的第一性原理&#xff0c;是实践反馈&a…

作者头像 李华
网站建设 2026/4/16 14:44:26

【课程设计/毕业设计】基于springboot+vue的Android的作物病虫害防治科普系统的设计与实现app小程序基于Android的作物病虫害防治科普系统的设计与实现【附源码、数据库、万字文档】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华