Qt5将qDebug等日志信息写入日志文件

Qt5将qDebug等日志信息写入日志文件


1、思路

其实Qt提供了将日志写入文件的方式,是以接口的形式提供的,我们只需要按照我们的需求完成回调函数和我们自己的接口即可。

为方便调用,我们一般直接写到log.h中即可。

  • 1、创建log.h
  • 2、根据我们自己的需求完成回调函数
  • 3、根据需求封装外部调用函数并注册回调函数

2、代码

我这里按照我的需求,当接口传递日志文件名和等级时使用传递的文件存储日志,否则以精确到当前时间为文件名创建日志文件。

提供给外部的调用函数包含日志文件名和日志等级两个接口,可以不传递,直接使用默认值。

Log.h

#ifndef LOG_H
#define LOG_H

#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QMutex>

//选择屏幕打印还是输出到文件可以根据这个宏控制或者控制函数调用位置都可以
//#define _DEBUG

//默认调试级别为warning,即小于warning级别的都不会写入日志文件
//只有release版本的时候,才会输出到日志,debug版本正常输出到终端。
namespace QT_LOG
{
    //默认文件名为当前时间命名的log文件
    static int m_LogLevel = 1;
    static QString m_LogFile = QString("%1.log").arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmss"));
    QMutex m_LogMutex;

    void customMessageHandler(QtMsgType type , const QMessageLogContext &context , const QString &msg)
    {
        //设置输出日志级别,小于该级别,将不会写入日志文件,默认是warning级别,即debug信息不会写入日志文件
        if (type < m_LogLevel)
        {
            return;
        }

        QString log_info;
        switch (type)
        {
        case QtDebugMsg:
            log_info = QString("%1[Debug]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
            break;

        case QtWarningMsg:
            log_info = QString("%1[Warning]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
            break;

        case QtCriticalMsg:
            log_info = QString("%1[Critical]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
            break;

        case QtFatalMsg:
            log_info = QString("%1[Fatal]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
            abort();

        case QtInfoMsg:
            log_info = QString("%1[Info]:").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
            break;
        }
        log_info += QString(context.file) + QString(context.line) + QString("%1").arg(msg);

        //为了线程安全
        m_LogMutex.lock();

        QFile outFile(m_LogFile);
        outFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
        QTextStream ts(&outFile);
        ts << log_info << endl;
        outFile.close();

        m_LogMutex.unlock();
    }

    //默认调试级别为warning及以上才会写入日志文件,默认log文件名为程序启动时间命名的log文件
    void logInit(QString logFile = "", int logLevel = 1)
    {
        #ifndef _DEBUG  //实现debug版本的时候,输出到终端;release版本的时候输出到日志文件
            if ((logLevel < 0) || (logLevel > 3))
            {
                m_LogLevel = 1;
            }
            else
            {
                m_LogLevel = logLevel;
            }

            if (!logFile.isEmpty())
            {
                m_LogFile = logFile;
            }

            qInstallMessageHandler(customMessageHandler);
        #endif
    }
}

#endif // LOG_H

调用,包含头文件后直接调用参数即可:

QT_LOG::logInit();
//或者
QT_LOG::logInit("log.txt", 2);

3、问题

可能不通Qt版本提供的回调函数有差异,我们通过qInstallMessageHandler进行源码查看,看下回调函数的样式,实现对应的回调函数进行测试即可:

在这里插入图片描述

4、结果与扩展思路

这个是我使用我上面封装的函数后生成的日志文件,每一次启动创建一个,暂时没有考虑定时分割创建新文件等问题,如果有需求可以调整回调函数进行调试:

在这里插入图片描述

针对上面的日志我们还可以加一些定时任务或者直接通过内存数据库通过线程安全的方式直接存储到数据库中,这样便于分布式存储和分析操作日志。

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Qt 中,可以使用 QDebug 和 qInstallMessageHandler 函数将日志写入文件。具体步骤如下: 1. 创建一个 QFile 对象,用于写入日志文件。例如: ```cpp QFile file("log.txt"); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return; ``` 2. 定义一个自定义的消息处理函数,用于将日志信息写入文件中。例如: ```cpp void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QByteArray localMsg = msg.toLocal8Bit(); switch (type) { case QtDebugMsg: fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtInfoMsg: fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtWarningMsg: fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtCriticalMsg: fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtFatalMsg: fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); abort(); } QTextStream out(&file); out << QString("[%1] %2\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(msg); out.flush(); } ``` 该函数将日志信息按照指定的格式写入文件中。 3. 在 main 函数中调用 qInstallMessageHandler 函数,将自定义的消息处理函数设置为全局的消息处理函数。例如: ```cpp int main(int argc, char *argv[]) { QApplication a(argc, argv); QFile file("log.txt"); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return -1; qInstallMessageHandler(myMessageOutput); // ... return a.exec(); } ``` 这样,所有的日志信息都会被重定向到 log.txt 文件中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昵称系统有问题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值