Qt打印Log日誌到文件

簡介

寫軟件時有時候需要記錄日誌到文件,方便查看軟件運行信息和排查問題,Qt有自己的日誌打印功能,實現Qt日誌功能需要用到下面的函數,其中Qt4和Qt5的函數有區別;

  • QtMessageHandler qInstallMsgHandler(QtMessageHandler handler) //Qt4函數
  • QtMessageHandler qInstallMessageHandler(QtMessageHandler handler) //Qt5函數

上面的函數是用來打印調試信息,警報信息,危險信息和致命信息的。當Qt有內部錯誤產生時,Qt調試庫會打印幾百種警報信息(通常是異常的函數參數),Qt以發佈模式編譯也會包含這些警報信息,除非在編譯的時候設置了QT_NO_WARNING_OUTPUT 和QT_NO_DEBUG_OUTPUT 。消息打印在X11 下默認輸出在標準輸出,在Windows模式輸出在調試器。如果是輸出的致命錯誤消息,程序會立刻退出。
z在一個程序中只能定義一個消息管理者,如果要恢復消息管理, 調用qInstallMessageHandler(0)。

在 main函數中加入下面的調用函數:

#if QT_VERSION < 0x050000
        qInstallMsgHandler(logMessageOutputQt4); //Qt4
#else
        qInstallMessageHandler(logMessageOutputQt5); //Qt5        
#endif

Qt4打印,需要自己加入文件名,函數名和行號:

qDebug("[%s] [%s] [%d] This is a debug message", __FILE__, __FUNCTION__, __LINE__);
    qDebug("[%s] [%s] [%d] This is a warning message", __FILE__, __FUNCTION__, __LINE__);
    qDebug("[%s] [%s] [%d] This is a critical message", __FILE__, __FUNCTION__, __LINE__);
    qDebug("[%s] [%s] [%d] This is a fatal message", __FILE__, __FUNCTION__, __LINE__);

Qt5打印,打印的文件名、函數名和行號在下面的消息處理函數中獲得:

qDebug("This is a debug message");
qWarning("This is a warning message");
qCritical("This is a critical message");
qFatal("This is a fatal message");

Qt4消息處理函數定義

void logMessageOutputQt4(QtMsgType type, const char *msg)
{
    static qint64 max = 10485760; //10 * 1024 * 1024;
    if (QString("%1").arg(msg).contains("QWSLock")) {
        return;
    }
    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:");
        abort();
    default:
        break;
    }
    QString message = QString("[%1] %2 %3").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(text).arg(msg);

    QFile file("/home/sun/rootnfs/myqttest/log4.txt");
    if (file.size() > max) { //超過指定大小時截取文件
        file.rename("/home/sun/rootnfs/myqttest/tmp.txt");
        QFile logfile("/home/sun/rootnfs/myqttest/log4.txt");

        file.open(QIODevice::ReadWrite);
        logfile.open(QIODevice::ReadWrite);
        qint64 nresult = 4194304; //4 * 1024 * 1024;
        file.seek(file.size() - nresult);
        char lbuffer[256];
        int count;
        while ((count = file.read(lbuffer, 256)) == 256) {
            logfile.write(lbuffer, count);
        }
        logfile.write(message.toLatin1(), message.count());
        file.close();
        file.remove();
        logfile.close();
    } else {
        QTextStream text_stream(&file);
        file.open(QIODevice::ReadWrite | QIODevice::Append);
        text_stream << message << endl;
        file.flush();
        file.close();
    }
    mutex.unlock();
}

打印效果

[2017-05-11 16:15:46] Debug: [qttest/main.cpp] [main] [13] This is a debug message
[2017-05-11 16:15:46] Warning: [qttest/main.cpp] [main] [14] This is a warning message
[2017-05-11 16:15:46] Critical: [qttest/main.cpp] [main] [15] This is a critical message

Qt5消息處理函數定義

void logMessageOutputQt5(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    static qint64 max = 10485760;//10 * 1024 * 1024;
    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:");
        abort();
    default:
        break;
    }
    QString message = QString("[%1] %2 [%3] [%4] [%5] %6").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
            .arg(text).arg(context.file).arg(context.function).arg(context.line).arg(msg);

    QFile file("/home/sun/rootnfs/myqttest/log5.txt");
    if (file.size() > max) { //超過指定大小時截取文件
        file.rename("/home/sun/rootnfs/myqttest/tmp.txt");
        QFile logfile("/home/sun/rootnfs/myqttest/log5.txt");

        file.open(QIODevice::ReadWrite);
        logfile.open(QIODevice::ReadWrite);
        qint64 nresult = 4194304; //4 * 1024 * 1024;
        file.seek(file.size() - nresult);
        char lbuffer[256];
        int count;
        while ((count = file.read(lbuffer, 256)) == 256) {
            logfile.write(lbuffer, count);
        }
        logfile.write(message.toLatin1(), message.count());
        file.close();
        file.remove();
        logfile.close();
    } else {
        QTextStream text_stream(&file);
        file.open(QIODevice::ReadWrite | QIODevice::Append);
        text_stream << message << endl;
        file.flush();
        file.close();
    }
    mutex.unlock();
}

打印效果

[2017-05-11 16:15:46] Debug: [../qttest/main.cpp] [int main(int, char**)] [13] This is a debug message
[2017-05-11 16:15:46] Warning: [../qttest/main.cpp] [int main(int, char**)] [14] This is a warning message
[2017-05-11 16:15:46] Critical: [../qttest/main.cpp] [int main(int, char**)] [15] This is a critical message
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章