Qt 项目日志的完美解决方案 qDebug() + spdlog

Qt 项目日志的完美解决方案 qDebug() + spdlog

主要解决问题

1.qt项目中 使用spdlog 都要进行转化,太麻烦了。这样可以使用原本的qDebug 来进行日志输出
2.qt目前我所了解到的本身不支持把日志写到文件中,而spdlog 我认为是一个很好的库。使用他进行日志写出到文件,我觉得比较好。
3.这样融合以后,还是用我们熟悉的qDebug风格,使用宏也可以很好的修改代码
4. 如果需要更多的标记,可以再声明一个hash 进行分管理。扩展更方便
如果我哪里有问题,或者有更好的写法,请大佬留言一起沟通交流。
w:Stbz528403 欢迎交流

效果展示

效果展示

代码

#include <QCoreApplication>
#include <QDebug>
#include <QDateTime>
#include <QFileInfo>
#include <QtWidgets/QWidget>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/pattern_formatter.h"

QWidget *g_logViewerInstance; /// 我这里是一个编辑框,根据自己的实际情况进行更改。 我是全局变量
std::shared_ptr<spdlog::logger> file_logger; /// 这里是文件输出,我也是一个全局变量

/// 下面代码主要用于在一些特殊日志进行输出到文件内,或者界面上的。
#define G_Debug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, "SPECIAL").debug()
#define G_Info QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, "SPECIAL").info()
#define G_Warning QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, "SPECIAL").warning()
#define G_Critical QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, "SPECIAL").critical()

#define G_Debug_N QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, "SPECIAL").debug().noquote()
#define G_Info_N QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, "SPECIAL").info().noquote()
#define G_Warning_N QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, "SPECIAL").warning().noquote()
#define G_Critical_N QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, "SPECIAL").critical().noquote()

/// 下面代码主要是用于开发环境以及生产环境去除 日志
#ifdef QT_DEBUG
#define D_Warning_N qWarning().noquote()
#define D_Debug_N qDebug().noquote()
#define D_Info_N qInfo().noquote()
#define D_Critical_N  qCritical().noquote()

#else
#define D_Warning_N QMessageLogger().noDebug()
#define D_Debug_N QMessageLogger().noDebug()
#define D_Info_N QMessageLogger().noDebug()
#define D_Critical_N  QMessageLogger().noDebug()
#endif

void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &str) {
    // ANSI color codes
    const char *colorReset = "\033[0m";
    const char *colorType;

    QString typeStr;
    switch (type) {
        case QtDebugMsg:
            typeStr = "Debug";
            colorType = "\033[0;34m"; // Blue
            break;
        case QtWarningMsg:
            typeStr = "Warning";
            colorType = "\033[0;33m"; // Yellow
            break;
        case QtCriticalMsg:
            typeStr = "Critical";
            colorType = "\033[0;31m"; // Red
            break;
        case QtFatalMsg:
            typeStr = "Fatal";
            colorType = "\033[0;31m"; // Red
            break;
        case QtInfoMsg:
            typeStr = "Info";
            colorType = "\033[0;32m"; // Green
            break;
    }

#ifdef QT_DEBUG
    QString templateString = "%1 %2 [%3:%4] %5 %6";
#else
    QString templateString = "%1 %2 [%3:%4] %5 %6";
#endif

    auto file = QFileInfo(context.file).fileName();
    auto time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
    QString msg = templateString.arg(
            time,
            typeStr,
            file,
            QString::number(context.line),
            context.function,
            str
    );


    // 判断日志是否包含特殊标识
    bool isSpecial = context.category && QString(context.category) == "SPECIAL";
    if (isSpecial) {
        if (type > QtMsgType::QtDebugMsg and g_logViewerInstance) {
            auto gui_msg = QString("%1 %2").arg(time, str);
            // 使用 GUI 线程更新日志窗口
            QMetaObject::invokeMethod(g_logViewerInstance, "appendMessage", Qt::QueuedConnection,
                                      Q_ARG(QString, gui_msg));
        }
        // 使用 spdlog 将日志消息记录到文件
        file_logger->log(spdlog::level::from_str(typeStr.toStdString()), "{}", msg.toStdString());
    }
    // 添加颜色前缀
    msg.prepend(colorType);
    // 添加颜色后缀
    msg.append(colorReset);
    QTextStream(stdout) << msg << endl;
}

/// 初始化spdlog日志
void initLog() {
    // 获取当前日期,并将其格式化为字符串
    QString currentDate = QDateTime::currentDateTime().toString("yyyy-MM-dd");

    // 创建日志文件名,将当前日期添加到文件名中
    std::string logFileName = "logs/logfile-" + currentDate.toStdString() + ".log";
    /// 初始化 spdlog 日志接收器
    size_t max_file_size = 10 * 1024 * 1024; // 10MB
    size_t max_files = 10;
    // 创建文件日志记录器
    file_logger = spdlog::rotating_logger_mt("file_logger", logFileName, max_file_size, max_files);
    file_logger->set_level(spdlog::level::info);
    file_logger->set_formatter(std::make_unique<spdlog::pattern_formatter>("%v"));
}

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);
    initLog();
    ///> 日志初始化
    qInstallMessageHandler(customMessageHandler);
    qSetMessagePattern("[%{type}] %{function} %{file}:%{line}   %{message}");
    D_Debug_N << "测试1";
    D_Info_N << "测试1";
    D_Warning_N << "测试1";
    D_Critical_N << "测试1";

    G_Debug_N << "测试1";
    G_Info_N << "测试1";
    G_Warning_N << "测试1";
    G_Critical_N << "测试1";
    exit(1);
    return QCoreApplication::exec();
}


  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值