1. 程式人生 > >Qt5如何輸出日誌輸出檔案(最全最新的框架方法)

Qt5如何輸出日誌輸出檔案(最全最新的框架方法)

Qt5如何輸出日誌輸出檔案目錄

描述

最近用到了Qt5的日誌輸出功能模組,現記錄一下,途中還遇見一些release版本日誌輸出不顯示行號的問題。

迴歸正題:在Qt開發過程當中經常使用qDebug等一些輸出來除錯程式,但是到了正式釋出的時候,都會被註釋或者刪除,採用日誌輸出來代替。

做過專案的童鞋可能都使用過日誌功能,以便有異常錯誤能夠快速跟蹤、定位,Qt也提供的類似的機制。之前用Qt4做專案時使用的是Qt::qInstallMsgHandler(),到了Qt5,使用了新的Qt::qInstallMessageHandler()來替代,詳情請檢視Qt助手(C++ API changes)。

助手中在C++ API changes中提到:Qt::qDebug()、Qt::qWarning()、Qt::qCritical()、Qt::qFatal()被改變為巨集來跟蹤原始碼的訊息來源。被列印的資訊可以被配置(用於預設訊息處理程式),通過設定該新的環境變數QT_MESSAGE_PATTERN。Qt::qInstallMsgHandler()已過時,因此建議使用Qt::qInstallMessageHandler()來代替。

日誌級別

  • qDebug:除錯資訊
  • qWarning:警告資訊
  • qCritical:嚴重錯誤
  • qFatal:致命錯誤

官方示例

在這裡插入圖片描述

需求(目的):生成log.txt日誌檔案,記錄詳細日誌資訊(包括等級、所在檔案、所在行號、描述資訊、產生時間等),以便於快速跟蹤、定位。

程式碼實現

#define FILEName "logger.txt"
class MessageHandler: public QObject{

    Q_OBJECT
public:
    explicit MessageHandler(QObject *parent = nullptr)
    {
        Q_UNUSED
(parent); //註冊MessageHandler qInstallMessageHandler(MessageHandler::outputMessage); } private: static void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg) { static QMutex mutex; mutex.lock(); QString text;
switch(type) { case QtDebugMsg: text = QString("Debug:"); break; case QtWarningMsg: text = QString("Warning:"); break; case QtCriticalMsg: text = QString("Critical:"); break; case QtFatalMsg: text = QString("Fatal:"); break; case QtInfoMsg: text = QString("Info:"); break; } QString context_info = QString("File:(%1) Line:(%2)").arg(QString(context.file)).arg(context.line); QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd"); QString current_date = QString("(%1)").arg(current_date_time); QString message = QString("%1 %2 %3 %4").arg(text).arg(context_info).arg(msg).arg(current_date); QString logPath ; #if defined (Q_OS_ANDROID) QStringList stringList = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation); // qInfo()<<"當前獲取到的stringList = "<<stringList; logPath = stringList.at(stringList.length() - 1); int indexPosition = logPath.lastIndexOf("/"); if(indexPosition != -1) { logPath = logPath.mid(0, indexPosition); if(!isDirExist(logPath+"/YYM")) { qInfo("Failed to create log directory."); } else { logPath = logPath+"/YYM"; } } #else logPath = HelpClass::getCurrentTempDataDir()+"/Logger"; HelpClass::isDirExist(logPath); // qInfo()<<"當前獲取到的stringList = "<<logPath; #endif QString date = QDateTime::currentDateTime().toString("yyyy-MM-dd"); logPath = logPath +QString("/logger(%1).txt").arg(date); // qInfo()<<"LogPath = "<<logPath; QFile file(logPath); file.open(QIODevice::WriteOnly | QIODevice::Append); QTextStream text_stream(&file); text_stream.setCodec("UTF-8"); text_stream << message << "\r\n"; file.flush(); file.close(); mutex.unlock(); } }; #endif // MESSAGEHANDLER_H

使用方法:
在main裡面呼叫即可

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
 
    MessageHandler *message = new MessageHandler;

    //列印日誌到檔案中
        qDebug("This is a debug message");
        qWarning("This is a warning message");
        qCritical("This is a critical message");
        qFatal("This is a fatal message");
    return a.exec();
}

在這裡插入圖片描述

注意!注意!注意!(重要的事情說三遍)

Release版本的輸出卻沒有檔案資訊、行數等資訊,如圖。

Release輸出
在這裡插入圖片描述
原因是:檔案資訊、行數等資訊在Release版本預設捨棄。我們只要在.pro檔案定義一個巨集

DEFINES += QT_MESSAGELOGCONTEXT

DEFINES += QT_MESSAGELOGCONTEXT
然後,重新qmake,編譯(有可能要刪除掉之前編譯的中間檔案),就可以在Release版本中正確輸出日誌資訊,如圖。
在這裡插入圖片描述