Qt自定义日志系统

QLog

更多精彩内容
👉个人内容分类汇总 👈

1、为什么需要日志?

只有在程序出问题以后才会知道打一个好的日志有多么重要
  • 当程序出现问题了,然后不是稳定复现的问题。怎么办法?
  • 当前程序出现问题了,当前环境不支持调试。例如:例如线上远程环境。
  • 当程序出现问题了,你不知道用户进行了哪些意想不到的奇葩操作
  • 在程序开发时输出日志是一个非常好的习惯,在qt中输出日志信息很多人都是使用一个QTextEdit显示就完了,或者加上点击按键保存到txt里,这种方式使得日志模块与程序耦合度非常高,使用也非常不方便,保存的日志信息也不完整,这就导致想通过日志获取需要的信息时常常找不到有效信息;
  • 这就需要在程序中使用一个低耦合,使用方便、日志信息完整的日志系统,qt可以使用很多C++的日志库,但是引入第三方库也比较麻烦;
  • 这里就可以直接将QDebug的日志信息输出到日志文件中,无需引入第三方库,使用也非常简单。

2、实现方式

  • 通过qInstallMessageHandler安装日志处理函数,获取QDebug的日志信息,然后保存、显示。

3、实现功能

  • 可选择日志显示到文本窗口并保存、不显示只保存两种使用方式;
  • 选择显示日志级别;
  • 可设置不同级别日志显示颜色;
  • 支持将日志信息保存到纯文本Log文件中;
  • 支持将日志信息保存到纯文本CSV文件中,便于阅读、查找和分类日志信息,可用于将CSV中的日志信息导入数据库;
  • 支持按12小时、24小时、按文件大小、日志行数创建新日志文件;
  • 无任何第三方依赖,支持任意编译器,任意系统;
  • 保留日志存储接口、日志显示接口,便于后续扩展日志存储、显示方式,如存储到数据库等;
  • 模块完全基于QDebug,与程序所有功能基本0耦合,非常便于程序开发。
  • 输出日志信息包含时间、日志级别、日志出自哪个文件、哪个函数、哪一行、日志内容

4、演示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5、主要代码

#include "loginput.h"
#include "head.h"


QtMessageHandler messageHandle;
LogInput::LogInput(QObject *parent) : QObject(parent)
{
    LogConfig::init();
    qRegisterMetaType<QtMsgType>("QtMsgType");

    messageHandle = qInstallMessageHandler(LogInput::myMessageOutput);          // 安装日志处理函数(这里需要使用非成员函数或者静态成员函数)
}

LogInput::~LogInput()
{
    qInstallMessageHandler(0);       // 还原
}

LogInput* LogInput::m_log = nullptr;
LogInput *LogInput::getInstance()
{
    if(nullptr == m_log)
    {
        static QMutex mutex;
        QMutexLocker locker(&mutex);
        if(nullptr == m_log)
        {
            m_log = new LogInput();
        }
    }
    return m_log;
}


void LogInput::myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    QByteArray localMsg = msg.toLocal8Bit();
    switch (type) {
    case QtDebugMsg:
      break;
    case QtInfoMsg:
      break;
    case QtWarningMsg:
      break;
    case QtCriticalMsg:
      break;
    case QtFatalMsg:
      break;
    }
    if(!msg.isEmpty())
    {
        const char *file = context.file ? context.file : "";
        const char *function = context.function ? context.function : "";
        emit m_log->logData(type, QTime::currentTime(), file, function, context.line, msg);
    }

    messageHandle(type, context, msg);                  // 输出到控制台
}

6、源代码

gitee
github

7、崩溃定位

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
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 文件中。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

mahuifa

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

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

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

打赏作者

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

抵扣说明:

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

余额充值