Qt5实现qDebug日志信息写入日志文件过程

 更新时间:2022年05月09日 15:16:38   作者:xiaoyaoyou.xyz  
这篇文章主要为大家介绍了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{<!--{C}%3C!%2D%2D%20%2D%2D%3E--> //默认文件名为当前时间命名的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) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> //设置输出日志级别,小于该级别,将不会写入日志文件,默认是warning级别,即debug信息不会写入日志文件 if (type < m_LogLevel) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> return; } QString log_info; switch (type) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> 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) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> #ifndef _DEBUG //实现debug版本的时候,输出到终端;release版本的时候输出到日志文件 if ((logLevel < 0) || (logLevel > 3)) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> m_LogLevel = 1; } else {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> m_LogLevel = logLevel; } if (!logFile.isEmpty()) {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> m_LogFile = logFile; } qInstallMessageHandler(customMessageHandler); #endif }}#endif // 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);QT_LOG::logInit();
//或者
QT_LOG::logInit("log.txt", 2);

3、问题

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

在这里插入图片描述

4、结果与扩展思路

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

在这里插入图片描述

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

以上就是Qt5实现qDebug日志信息写入日志文件的详细内容,更多关于Qt5 qDebug日志信息写入文件的资料请关注脚本之家其它相关文章!

相关文章

  • 使用C++创建多个IPC机制的上层接口

    使用C++创建多个IPC机制的上层接口

    设计一个上层的IPC接口,这个接口将在未来封装底层的通信机制,这样的设计要求接口足够抽象,以便于底层实现的细节对上层用户透明,本文给大家介绍了如何使用C++创建多个IPC机制的上层接口,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • C语言实现职工管理系统

    C语言实现职工管理系统

    这篇文章主要为大家详细介绍了C语言实现职工管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • Visual Studio Code (vscode) 配置 C / C++ 环境的流程

    Visual Studio Code (vscode) 配置 C / C++ 环境的流程

    这篇文章主要介绍了Visual Studio Code (vscode) 配置 C / C++ 环境的流程,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • C语言数组元素循环右移问题及解决方法

    C语言数组元素循环右移问题及解决方法

    这篇文章主要介绍了C语言数组元素循环右移问题,本文通过多种方法给大家分享解决方案,通过实例代码讲解,对大家的工作或学习具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • Qt实现模糊匹配功能的实例详解

    Qt实现模糊匹配功能的实例详解

    对于浏览器的使用,我想大家一定不会陌生吧,输入要搜索的内容时,会出现相应的匹配信息。本文就来用Qt实现模糊匹配功能,感兴趣的可以了解一下
    2022-10-10
  • 基于C语言实现的aes256加密算法示例

    基于C语言实现的aes256加密算法示例

    这篇文章主要介绍了基于C语言实现的aes256加密算法,结合具体实例形式详细分析了C语言实现的aes256加密算法实现步骤与使用技巧,需要的朋友可以参考下
    2017-02-02
  • Pipes实现LeetCode(195.第十行)

    Pipes实现LeetCode(195.第十行)

    这篇文章主要介绍了Pipes实现LeetCode(195.第十行),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C语言基础 原码、反码、补码和移码详解

    C语言基础 原码、反码、补码和移码详解

    这篇文章主要介绍了C语言基础 原码、反码、补码和移码详解的相关资料,需要的朋友可以参考下
    2017-01-01
  • C++实用库之字节流合成器

    C++实用库之字节流合成器

    在处理跨平台的数据交换或网络通信时,字节流的重要性更加突出,不同的系统可能有不同的字节序(大端序或小端序),因此在发送和接收字节流时,可能需要考虑字节序的转换,这篇文章主要介绍了C++实用库之字节流合成器,需要的朋友可以参考下
    2024-04-04
  • C语言rewind与fseek函数之随机读写文件的用法详解

    C语言rewind与fseek函数之随机读写文件的用法详解

    这篇文章主要介绍了C语言rewind与fseek函数之随机读写文件的用法详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09

最新评论