编辑
2025-07-30
cpp
00
请注意,本文编写于 33 天前,最后修改于 26 天前,其中某些信息可能已经过时。

目录

MadLog - 高性能C++/Qt日志系统
📖 简介
✨ 主要特性
🎯 核心功能
🔧 便捷宏系统
📤 多种输出器
🚀 快速开始
1. 项目集成
2. 基础使用
3. 流式日志使用
流式日志优势
4. 高级配置
📚 详细使用指南
日志宏使用
基础日志宏
格式化日志宏
条件日志宏
指定日志记录器
函数跟踪
性能测量
GUI集成示例
自定义格式化器
🎨 格式化模式
🔧 配置选项
文件输出器配置
GUI输出器配置
Qt控制台输出器配置
🏗️ 架构设计
核心组件说明
🔍 最佳实践
1. 日志级别使用建议
2. 性能优化建议
3. 线程安全注意事项
📝 更新日志
v1.0.0
v1.1.0
v1.2.0
v1.3.0
📄 许可证
🤝 贡献
📞 联系方式

MadLog - 高性能C++/Qt日志系统

📖 简介

MadLog是一个功能强大、高性能的C++/Qt日志系统,提供了灵活的日志记录、格式化和输出功能。该系统采用现代C++设计模式,支持多种输出方式,适用于各种规模的Qt应用程序。

✨ 主要特性

🎯 核心功能

  • 多级别日志:支持Trace、Debug、Info、Warn、Error、Critical六个级别
  • 多输出器:支持控制台、文件、GUI控件、Qt控制台等多种输出方式
  • 自定义格式:灵活的日志格式化系统,支持自定义模式
  • 线程安全:完全线程安全的设计,支持多线程环境
  • 高性能:优化的内存管理和批量输出机制

🔧 便捷宏系统

  • 简单易用:提供丰富的日志宏,使用简单
  • 流式日志:支持C++流式语法,类型安全且高性能
  • 条件日志:支持条件输出,避免不必要的性能开销
  • 函数跟踪:自动函数进入/退出跟踪
  • 性能测量:内置性能测量宏,方便性能分析
  • 作用域跟踪:RAII风格的作用域跟踪

📤 多种输出器

  1. 控制台输出器 (MadConsoleSink)
    • 支持彩色输出
    • 错误级别自动输出到stderr
  2. 文件输出器 (MadFileSink)
    • 文件轮转功能
    • 自动备份管理
    • 定时刷新
  3. QTextEdit输出器 (MadTextEditSink)
    • HTML格式支持
    • 彩色文本显示
    • 行数限制和自动滚动
  4. QPlainTextEdit输出器 (MadPlainTextEditSink)
    • 纯文本格式
    • 高性能显示
    • 彩色文本支持
  5. Qt控制台输出器 (MadQtConsoleSink)
    • 集成Qt日志系统
    • 支持Qt日志分类
    • 与Qt Creator调试器完美集成

🚀 快速开始

1. 项目集成

在你的.pro文件中添加:

qmake
include(MadLog/MadLog.pri)

2. 基础使用

cpp
#include "madlogmacros.h" #include "madconsolesink.h" #include "madlogmanager.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); // 设置日志系统 auto manager = MadLogManager::instance(); auto logger = manager->getLogger("default"); // 添加控制台输出器 auto consoleSink = QSharedPointer<MadConsoleSink>::create(); logger->addSink(consoleSink); // 使用传统日志宏 MAD_INFO("应用程序启动"); MAD_DEBUG("调试信息"); MAD_WARN("警告信息"); MAD_ERROR("错误信息"); // 使用流式日志(推荐) logger->info(__FILE__, __LINE__, __FUNCTION__) << "应用程序启动"; logger->debug(__FILE__, __LINE__, __FUNCTION__) << "用户ID: " << 12345; logger->warn(__FILE__, __LINE__, __FUNCTION__) << "连接超时,重试次数: " << 3; logger->error(__FILE__, __LINE__, __FUNCTION__) << "文件不存在: " << "config.ini"; return app.exec(); }

3. 流式日志使用

流式日志提供了更现代、类型安全的日志记录方式:

cpp
#include "madlogger.h" void demonstrateStreamLogging() { auto logger = MAD_DEFAULT_LOGGER(); // 基础流式日志 logger->info(__FILE__, __LINE__, __FUNCTION__) << "用户登录成功"; logger->debug(__FILE__, __LINE__, __FUNCTION__) << "处理请求ID: " << 12345; // 支持多种数据类型 QString username = "admin"; int userId = 1001; double responseTime = 123.45; logger->info(__FILE__, __LINE__, __FUNCTION__) << "用户: " << username << ", ID: " << userId << ", 响应时间: " << responseTime << "ms"; // 支持QStringList QStringList permissions = {"read", "write", "admin"}; logger->debug(__FILE__, __LINE__, __FUNCTION__) << "用户权限: " << permissions; // 支持Qt容器类型 QList<int> numbers = {1, 2, 3, 4, 5}; logger->trace(__FILE__, __LINE__, __FUNCTION__) << "处理数字列表,大小: " << numbers.size(); }

流式日志优势

  • 类型安全:编译时检查类型,避免格式化错误
  • 性能优化:只在需要时构造字符串
  • 简洁语法:无需手动格式化字符串
  • 自动管理:RAII风格,自动处理资源
  • 扩展性强:支持自定义类型的operator<<重载

4. 高级配置

cpp
#include "madlogmacros.h" #include "madconsolesink.h" #include "madfilesink.h" #include "madqtconsolesink.h" #include "madlogpatternformatter.h" void setupAdvancedLogging() { auto manager = MadLogManager::instance(); // 设置全局日志级别 manager->setGlobalLevel(MadLogLevel::Debug); // 创建自定义格式化器 auto formatter = QSharedPointer<MadLogPatternFormatter>::create( "[%time%] [%level%] [%thread%] [%logger%] %file%:%line% - %msg%"); // 创建多个输出器 auto consoleSink = QSharedPointer<MadConsoleSink>::create(formatter); auto fileSink = QSharedPointer<MadFileSink>::create("logs/app.log", formatter); auto qtConsoleSink = QSharedPointer<MadQtConsoleSink>::create(formatter); // 配置文件输出器 fileSink->setMaxFileSize(10 * 1024 * 1024); // 10MB fileSink->setMaxBackupCount(5); // 配置Qt控制台输出器 qtConsoleSink->setCategoryName("myapp"); qtConsoleSink->setUseQtCategories(true); // 获取日志记录器并添加输出器 auto logger = manager->getLogger("default"); logger->addSink(consoleSink); logger->addSink(fileSink); logger->addSink(qtConsoleSink); }

📚 详细使用指南

日志宏使用

基础日志宏

cpp
MAD_TRACE("跟踪信息"); MAD_DEBUG("调试信息"); MAD_INFO("一般信息"); MAD_WARN("警告信息"); MAD_ERROR("错误信息"); MAD_CRITICAL("严重错误");

格式化日志宏

cpp
int userId = 12345; QString userName = "张三"; MAD_INFO_F("用户登录: ID=%d, 姓名=%s", userId, userName.toUtf8().constData());

条件日志宏

cpp
bool debugMode = true; MAD_DEBUG_IF(debugMode, "调试模式已启用");

指定日志记录器

cpp
auto networkLogger = MAD_LOGGER("network"); MAD_INFO_L(networkLogger, "网络连接已建立");

函数跟踪

cpp
void myFunction() { MAD_FUNCTION_ENTER(); // 函数进入 // 函数逻辑... MAD_FUNCTION_EXIT(); // 函数退出 } // 或者使用作用域跟踪(推荐) void myFunction() { MAD_SCOPE_TRACKER(); // 自动跟踪整个函数作用域 // 函数逻辑... // 函数结束时自动记录退出 }

性能测量

cpp
void performanceTest() { MAD_PERF_START(database_query); // 执行数据库查询... MAD_PERF_END(database_query); // 自动输出执行时间 }

GUI集成示例

cpp
#include "madtexteditsink.h" #include "madplaintexteditsink.h" class MainWindow : public QMainWindow { public: MainWindow(QWidget* parent = nullptr) : QMainWindow(parent) { setupUI(); setupLogging(); } private: void setupLogging() { auto logger = MAD_DEFAULT_LOGGER(); // 添加QTextEdit输出器 auto textEditSink = QSharedPointer<MadTextEditSink>::create(m_logTextEdit); textEditSink->setMaxLines(1000); textEditSink->setColorEnabled(true); logger->addSink(textEditSink); // 添加QPlainTextEdit输出器 auto plainTextSink = QSharedPointer<MadPlainTextEditSink>::create(m_logPlainTextEdit); plainTextSink->setMaxLines(1000); logger->addSink(plainTextSink); } QTextEdit* m_logTextEdit; QPlainTextEdit* m_logPlainTextEdit; };

自定义格式化器

cpp
class CustomFormatter : public MadLogFormatter { public: QString format(const MadLogMessage& msg) override { return QString("[%1] %2: %3") .arg(QDateTime::fromMSecsSinceEpoch(msg.timestamp).toString("hh:mm:ss")) .arg(madLogLevelToString(msg.level)) .arg(msg.message); } }; // 使用自定义格式化器 auto customFormatter = QSharedPointer<CustomFormatter>::create(); auto sink = QSharedPointer<MadConsoleSink>::create(customFormatter);

🎨 格式化模式

内置的MadLogPatternFormatter支持以下占位符:

占位符描述示例
%time%时间戳2023-12-01 14:30:25.123
%level%日志级别INFO, ERROR
%msg%日志消息用户登录成功
%logger%日志记录器名称network, database
%file%源文件名main.cpp
%line%行号42
%func%函数名main
%thread%线程ID12345

示例格式:

cpp
"[%time%] [%level%] [%logger%] %file%:%line% - %msg%" // 输出:[2023-12-01 14:30:25.123] [INFO] [network] main.cpp:42 - 连接建立成功

🔧 配置选项

文件输出器配置

cpp
auto fileSink = QSharedPointer<MadFileSink>::create("logs/app.log"); fileSink->setMaxFileSize(50 * 1024 * 1024); // 50MB fileSink->setMaxBackupCount(10); // 保留10个备份文件 fileSink->setAutoFlushInterval(1000); // 1秒自动刷新

GUI输出器配置

cpp
auto textEditSink = QSharedPointer<MadTextEditSink>::create(textEdit); textEditSink->setMaxLines(500); // 最多显示500行 textEditSink->setAutoScroll(true); // 自动滚动 textEditSink->setColorEnabled(true); // 启用彩色显示 textEditSink->setAutoFlushInterval(100); // 100ms刷新间隔

Qt控制台输出器配置

cpp
auto qtSink = QSharedPointer<MadQtConsoleSink>::create(); qtSink->setCategoryName("myapp.network"); // 设置Qt日志分类 qtSink->setUseQtCategories(true); // 启用Qt分类

🏗️ 架构设计

┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ 日志宏系统 │───▶│ MadLogger │───▶│ MadLogSink │ │ (便捷接口) │ │ (日志记录器) │ │ (输出接口) │ └─────────────────┘ └──────────────────┘ └─────────────────┘ │ │ ▼ ▼ ┌──────────────────┐ ┌─────────────────┐ │ MadLogManager │ │ MadLogFormatter │ │ (管理器-单例) │ │ (格式化接口) │ └──────────────────┘ └─────────────────┘

核心组件说明

  • MadLogManager: 单例管理器,负责创建和管理日志记录器
  • MadLogger: 日志记录器,负责接收日志消息并分发给输出器
  • MadLogSink: 输出器接口,定义日志输出行为
  • MadLogFormatter: 格式化器接口,负责格式化日志消息
  • 日志宏系统: 提供便捷的日志记录接口

🔍 最佳实践

1. 日志级别使用建议

  • Trace: 详细的程序执行跟踪,通常只在开发阶段使用
  • Debug: 调试信息,帮助定位问题
  • Info: 一般信息,记录程序的重要状态变化
  • Warn: 警告信息,程序可以继续运行但需要注意
  • Error: 错误信息,程序遇到错误但可以恢复
  • Critical: 严重错误,程序可能无法继续正常运行

2. 性能优化建议

  • 在生产环境中设置合适的日志级别,避免输出过多调试信息
  • 使用条件日志宏避免不必要的字符串构造
  • 为不同模块创建专门的日志记录器
  • 合理设置文件输出器的刷新间隔

3. 线程安全注意事项

  • 所有日志操作都是线程安全的
  • GUI输出器会自动处理跨线程调用
  • 避免在析构函数中使用日志宏

📝 更新日志

v1.0.0

  • ✅ 基础日志系统实现
  • ✅ 控制台和文件输出器
  • ✅ 模式格式化器
  • ✅ 线程安全设计

v1.1.0

  • ✅ 添加GUI输出器(QTextEdit/QPlainTextEdit)
  • ✅ 完善日志宏系统
  • ✅ 添加性能测量功能
  • ✅ 添加作用域跟踪功能

v1.2.0

  • ✅ 添加Qt控制台输出器
  • ✅ 支持Qt日志分类
  • ✅ 完善文档和示例
  • ✅ 优化性能和内存使用

v1.3.0

  • ✅ 简化流式日志实现,移除独立的MadLogStream类
  • ✅ 优化MadLogger类,直接支持流式操作
  • ✅ 支持QStringList和Qt容器类型的流式输出
  • ✅ 删除不必要的示例文件,减少代码体积
  • ✅ 更新文档,添加流式日志使用指南
  • ✅ 提升类型安全性和性能

📄 许可证

本项目采用MIT许可证,详见LICENSE文件。

🤝 贡献

欢迎提交Issue和Pull Request来改进这个项目!

📞 联系方式

如有问题或建议,请通过以下方式联系:

  • 提交GitHub Issue
  • 发送邮件至项目维护者

MadLog - 让日志记录变得简单而强大! 🚀

本文作者:Shiny

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!