《完美Qt》之qInstallMessageHandler

1 背景

在自己項目中,之前寫好了幾個模塊,用了很多的qDebug()打印信息,後面項目經理要求有日誌輸出,以便以後出現問題方便調試,百度查了下,很容易得到自己想要的。。

2 介紹

用qInstallMessageHandler()這個全局函數就可以把qDebug(), qWarning()輸出重定向的日誌文件中,這個函數需要傳個參數,實際就是一個回調函數,格式如下`void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg),type:消息等級, context包括:文件,行號,函數名等, msg:qDebug()時傳遞的參數。

3 實現

在myMessageOutput()函數中的步驟如下
1. 在當前路徑下創建日誌目錄
2. 根據日期創建日誌文件
3. 保留七天的日誌文件
4. 拼接消息內容:msg+函數名+文件路徑+行號
5. 文本流輸入到日誌文件

    #include <QApplication>
    #include <stdio.h>
    #include <stdlib.h>
    #include <QDebug>
    #include <QFile>
    #include <QFileInfo>
    #define LOG_FILE_KEEP_NUM 7
    void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
    {
    //#1 create directory that name is log
    QDir dir("log");
    if (!dir.exists())
    {
         QDir dir;
         dir.mkdir("log");
    }

    //#2 create log file by current date ==> eg:log20170418.txt
    QString currentDate = QDateTime::currentDateTime().toString("yyyyMMdd");
    QString logName = "log" + currentDate + ".txt";
    QString logFileName = "log/" + logName;

    //#3 Keep a journal for the last one week.
    if (!QFile::exists(logFileName))
    {
        QFileInfoList fileList = dir.entryInfoList(QStringList() << "*.txt", QDir::NoFilter, QDir::Time);
        if (fileList.size() >= LOG_FILE_KEEP_NUM)
        {
            int i = 1;
            foreach(QFileInfo fileInfo , fileList)
            {
                if (i >= LOG_FILE_KEEP_NUM)
                {
                    QString fileName = fileInfo.absoluteFilePath();
                    QFile::remove(fileName);
                }
                i++;
            }
        }
    }

    QFile file(logFileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Append))
    {
        file.close();
        return ;
    }

    //#4 joint string
    QString currentDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    QString logMsg;

    switch (type)
    {
    case QtDebugMsg:
        logMsg = QString("%1: [Debug]: %2  Function: %3  File: %4  Line: %5\n").arg(currentDateTime).arg(msg).arg(context.function).arg(context.file).arg(context.line);
        break;
    case QtInfoMsg:
        logMsg = QString("%1: [Info]: %2  Function: %3  File: %4  Line: %5\n").arg(currentDateTime).arg(msg).arg(context.function).arg(context.file).arg(context.line);
        break;
    case QtWarningMsg:
        logMsg = QString("%1: [Warning]: %2 Function: %3 Line: %4 File: %5\n").arg(currentDateTime).arg(msg).arg(context.function).arg(context.file).arg(context.line);
        break;
    case QtCriticalMsg:
        logMsg = QString("%1: [Critical]: %2 Function: %3 Line: %4 File: %5\n").arg(currentDateTime).arg(msg).arg(context.function).arg(context.file).arg(context.line);
        break;
    case QtFatalMsg:
        logMsg = QString("%1: [Fatal]: %2 Function: %3 Line: %4 File: %5\n").arg(currentDateTime).arg(msg).arg(context.function).arg(context.file).arg(context.line);
        abort();
        break;
    default:
        break;
    }

    //#5 log message out to file
    QTextStream ts(&file);
    ts << logMsg;

    file.close();
    }

    int main(int argc, char *argv[])
    {
        qInstallMessageHandler(myMessageOutput);
        QApplication a(argc, argv);

        qDebug()   << "this is Debug";
        qInfo()    << "this is info";
        qWarning() << "this is warning";
        qCritical()<< "this is critical";
        qFatal("this is fatal");

        return a.exec();
    }

4 結果

執行結果

5 參考

https://blog.csdn.net/liang19890820/article/details/51838379(輸出到文件)
http://m.blog.csdn.net/liang19890820/article/details/51838096(輸出到標準錯誤)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章