Qt 日志输出 QMessageLogger QtMessageHandler qInstallMessageHandler()
阅读原文时间:2021年04月23日阅读:1

Qt 日志输出 QMessageLogger QtMessageHandler qInstallMessageHandler()

QtMessageHandler

首先说明这不是一个类,定义如下:
typedef void (*QtMessageHandler)(QtMsgType, const QMessageLogContext &, const QString &);
这是一个指向函数的指针,具有以下格式的用户自定义函数:
void youselfmessagehandler(qtmsgtype,const qmessagelogcontext,const QString &);

第一个参数是日志的类型,
enum QtMsgType { QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, QtInfoMsg, QtSystemMsg = QtCriticalMsg };

第二个参数是写日志的当前文件名,文件行数,和当前的函数信息类。和C语言中FILELINEFUNC 功能一样。
主要有以下成员:
*category : const char
file : const char *
function : const char *
line : int
version : int**

第三个参数就是自己写的日志信息。

qInstallMessageHandler()

qInstallMessageHandler()是对QtMessageHandler这个全局变量初始化函数。

定义如下:
Q_CORE_EXPORT QtMessageHandler qInstallMessageHandler(QtMessageHandler);

QMessageLogger

这是一个输出日志类,这个没发现有什么用,可能是屏蔽一些FILELINEFUNC信息。不用这个类同样可以直接把日志输出到文件。

例1:

log.h

#ifndef LOG_H
#define LOG_H


#include <QFile>
#include <QMessageLogger>
#include <qlogging.h>
#include <QFile>
#include <QTextStream>
#include <QDateTime>

extern QMessageLogger *gMLog;
void logSysInit(QString filePath);
void logSysInit();

//打印日志到文件中
//qDebug("This is a debug message");
//qWarning("This is a warning message");
//qCritical("This is a critical message");
//qFatal("This is a fatal message");


#endif // LOG_H

log.cpp

#include "log.h"

QFile *gFileLog=NULL;
QMessageLogger *gMLog=NULL;

char *msgHead[]={
    "Debug   ",
    "Warning ",
    "Critical",
    "Fatal   ",
    "Info    "
};

void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    QByteArray localMsg = msg.toLocal8Bit();
    QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd");

    if(gFileLog){
        QTextStream tWrite(gFileLog);

        QString msgText="%1 | %6 | %2:%3, %4 | %5\n";
        msgText = msgText.arg(msgHead[type]).arg(context.file).arg(context.line).arg(context.function).arg(localMsg.constData()).arg(current_date_time);
        //gFileLog->write(msgText.toLocal8Bit(), msgText.length());
        tWrite << msgText;
    }else{
        fprintf(stderr, "%s | %s | %s:%u, %s | %s\n", msgHead[type], current_date_time.toLocal8Bit().constData(), context.file, context.line, context.function, localMsg.constData());
    }

}




void logSysInit(QString filePath)
{
    gFileLog = new QFile(filePath);
    if (!gFileLog->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)){
        return;
    }
//初始化自定义日志处理函数myMessageOutput
    qInstallMessageHandler(myMessageOutput);
//gMLog 这个类不要也可以,执行的时候只能看一下效果。
    gMLog = new QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO);
}

void logSysInit()
{
    qInstallMessageHandler(myMessageOutput);

    gMLog = new QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO);
}

main.cpp

#include <QApplication>

#include "log.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    logSysInit("log.txt");
    //打印日志到文件中
    qDebug("This is a debug message");
    qWarning("This is a warning message");
    //qCritical("This is a critical message");
    //qFatal("This is a fatal message");
    if(gMLog){
        gMLog->debug("aaaaa");
    }
    return a.exec();
}

执行结果
Debug | 2017-01-31 20:20:31 周二 | ..\snifferLog\main.cpp:14, int qMain(int, char**) | This is a debug message
Warning | 2017-01-31 20:20:31 周二 | ..\snifferLog\main.cpp:15, int qMain(int, char**) | This is a warning message
Debug | 2017-01-31 20:20:31 周二 | ..\snifferLog\log.cpp:45, void logSysInit(QString) | aaaaa

加粗部分与上两条日志直接使用qDebug和使用gMLog->debug 效果是不一样的。