qt实现将相关信息输出到日志文件

前言

在开发工作中,程序在使用时,出现错误问题,对于用户来说,查看日志信息,来初步排查问题是很有必要的


注意:我这里是windows环境的写法,linux的路径和命令有些不同,linux环境的同学不可直接照搬


6.15更新:

在网上还看到通过调用qInstallMessageHandler安装消息处理程序,这是官方文档对消息处理程序的介绍,即我们可以自定义qDebug,qInfo时打印什么信息,信息打印到哪里。代码放在文末

image-20220615150820871


直接上代码:

.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui {
    
     class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    
    
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    static int WriteLog(QString errInfo);

private:
    Ui::MainWindow *ui;
};


#endif // MAINWINDOW_H

.cpp文件

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QCoreApplication>
#include <QDir>
#include <QProcess>
#include <QDebug>
#include <QDateTime>
#include <QFile>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    
    
    ui->setupUi(this);
    WriteLog("---success---直播功能设置成功");
    WriteLog("----infos----正在向数据库插入信息......");
    WriteLog("---warning---无挂载信息");
    WriteLog("----error----/etc/lancoo/rec-server.ini文件不存在");
}

MainWindow::~MainWindow()
{
    
    
    delete ui;
}

//主要代码
int MainWindow::WriteLog(QString info)
{
    
    
    QString localApplicationDirPath = QCoreApplication::applicationDirPath();		//可执行程序所在目录
    QString log_file;

    QString log_dir=localApplicationDirPath+"/log";
    QDir dir(log_dir);
    //cmd中创建文件需要使用\,使用/报错
    log_dir.replace("/","\\");
    if(!dir.exists())
    {
    
    
        //创建在可执行程序所在目录创建log文件
        system(QString(" mkdir %1").arg(log_dir).toStdString().data());
        qDebug()<<log_dir;
    }

    QDateTime current_date_time =QDateTime::currentDateTime();
    QString date = current_date_time.toString("yyyy-MM-dd");
    //在c++中\表示转义,\\才为字符\
    
    log_file=log_dir+"\\"+"log_"+date+".txt";

    //保存原文件的内容,直接write会把原内容覆盖掉
    QFile file_read(log_file);
    file_read.open(QIODevice::ReadOnly);
    QByteArray file_readAll = file_read.readAll();
    file_read.close();

    //向文件中写入信息
    QFile file_write(log_file);
    if(file_write.open(QIODevice::WriteOnly)){
    
    
        file_write.write(file_readAll.data());
        QString temp_info;
        temp_info+="[";
        temp_info+=current_date_time.toString("yyyy-MM-dd hh:mm:ss");
        temp_info+="] ";
        temp_info+=info;
        temp_info+="\r\n";    //换行符,linux为\n
        file_write.write(temp_info.toStdString().data());
    }
    file_write.close();
    return 
}

看主要代码即可,将其定义为静态方法是为了在别的类中也能很方便地调用

log文件在可执行程序所在目录下

注意:qt将编译文件和源文件分开管理,通过影子构建的方式,可执行文件大概率在别的目录。如果这里勾选了,则到对应目录下找可执行程序,如果这里没勾选,择取代码源文件目录下找

image-20220613213520623

image-20220613213347876

image-20220613213404847


在自定义writeLog的基础上我们来自定义消息处理程序:

将自定义的函数myMessageOutput写在main.cpp中,消息处理程序的安装写在main()方法中,这样全局所有类的qDebug都可以将信息直接打印到日志文件中。注释掉qInstallMessageHandler(myMessageOutput);或者qInstallMessageHandler(0)来回复消息处理程序

#include "mainwindow.h"

#include <QApplication>
#include <QDateTime>
#include <QDir>
#include <QFile>
#include <QMutex>
#include <QTextStream>
#include <QDebug>

void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
 {
    
    
    // 加锁
        static QMutex mutex;
        mutex.lock();

        QByteArray localMsg = msg.toLocal8Bit();

        QString strMsg("");
        switch(type)
        {
    
    
        case QtDebugMsg:
            strMsg = QString("----Debug----");
            break;
        case QtInfoMsg:
            strMsg = QString("----Infos----");
            break;
        case QtWarningMsg:
            strMsg = QString("---Warning---");
            break;
        case QtCriticalMsg:
            strMsg = QString("---Critical---");
            break;
        case QtFatalMsg:
            strMsg = QString("----Fatal----");
            break;
        }

        // 设置输出信息格式
        QString strDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        QString strMessage = QString("[%1] %5 %6\t-------------File:%2  Line:%3  Function:%4  ")
                .arg(strDateTime).arg(context.file).arg(context.line).arg(context.function).arg(strMsg).arg(localMsg.constData());

        //获取可执行程序所在目录
        QString localApplicationDirPath = QCoreApplication::applicationDirPath();
        QString log_file;
        QString log_dir=localApplicationDirPath+"/log";
        QDir dir(log_dir);
        //cmd中创建文件需要使用\,使用/报错
        log_dir.replace("/","\\");
        if(!dir.exists())
        {
    
    
            //创建在可执行程序所在目录创建log文件
            system(QString(" mkdir %1").arg(log_dir).toStdString().data());
        }

        QDateTime current_date_time =QDateTime::currentDateTime();
        QString date = current_date_time.toString("yyyy-MM-dd");
        //在c++中\表示转义,\\才为字符"\"
        log_file=log_dir+"\\"+"log_"+date+".txt";

        // 输出信息至文件中(读写、追加形式)
        QFile file(log_file);
        file.open(QIODevice::ReadWrite | QIODevice::Append);
        QTextStream stream(&file);
        stream << strMessage << "\r\n";
        file.flush();
        file.close();

        // 解锁
        mutex.unlock();
 }

int main(int argc, char *argv[])
{
    
    
    // 安装消息处理程序
    qInstallMessageHandler(myMessageOutput);

    QApplication a(argc, argv);
    MainWindow w;
    qDebug("This is a debug message.");
    qInfo("This is a info message.");
    qWarning("This is a warning message.");
    qCritical("This is a critical message.");
    w.show();
    return a.exec();
}

这样在发行版的程序中就可以直接通过日志文件来排查错误信息了

运行结果:

image-20220615151447629


码字不易,如果这篇博客对你有帮助,麻烦点赞收藏,非常感谢!有不对的地方,可以评论区交流。

猜你喜欢

转载自blog.csdn.net/weixin_44092851/article/details/125267572