Qt日志重定向qInstallMessageHandler,輸出至文件及網絡


Qt日志重定向qInstallMessageHandler,輸出至文件及網絡

https://blog.csdn.net/libaineu2004/article/details/88801336

 

Qt有Debug、Warning、Info、Critical、Fatal五種級別的調試信息。
qDebug:調試信息
qWarning:警告信息

qInfo:警告信息
qCritical:嚴重錯誤
qFatal:致命錯誤
Qt4提供了qInstallMsgHandler(Qt5:qInstallMessageHandler)對qDebug、qWarning、qCritical、qFatal等函數輸出信息的重定向處理。
qInstallMsgHandler是一個回調函數,由qDebug、qWarnng、qCritical、qFatal函數進行觸發,qDebug、qWarnng、qCritical、qFatal函數處理的消息文本會被qInstallMsgHandler所指向的回調函數截獲,允許用戶自己來處理輸出的消息文本。

一、來看官方的例子:

void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
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:");
}
QDateTime current_date_time = QDateTime::currentDateTime();
QString current_date = current_date_time.toString("yyyy-MM-dd hh:mm:ss ddd");
QString message = text.append(msg).append("(").append(current_date).append(")");

QFile file("log.txt");
file.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream text_stream(&file);
text_stream<<message<<"\r\n";
file.close();
}

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

//注冊MessageHandler
qInstallMessageHandler(outputMessage);

//打印日志到文件中
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 app.exec();
}
Qt自帶5個向外寫警告和調試文本的方法。可以把它們使用在如下目的:

qDebug():用於寫自定調試信息的輸出;
qWarning():用於報告程序中的警告和可恢復的錯誤;
qCritical():用於寫關鍵錯誤信息和報告系統錯誤;
qFatal():用於退出前簡要地描述致命錯誤消息;
qInfo():用於寫自定調試信息的輸出。
如果包含<QtDebug>頭文件,qDebug()可以當做輸出流來使用。例如:

qDebug() << "Widget" << widget << "at position" << widget->pos();
 

二、開源項目http://www.qtcn.org/bbs/read-htm-tid-85387-page-e.html使用了qInstallMessageHandler的機制,封裝了日志庫。

本人在它基礎之上,略微修改,封裝了更強大和易用的日志庫。

void Log(QtMsgType type, const QMessageLogContext &context, const QString &msg)
#endif
{
//加鎖,防止多線程中qdebug太頻繁導致崩潰
QMutex mutex;
QMutexLocker locker(&mutex);

//這里可以根據不同的類型加上不同的頭部用於區分
//Release 版本默認不包含這些信息:文件名、函數名、行數,需要在.pro項目文件加入以下代碼,加入后最好重新構建項目使之生效:
//DEFINES += QT_MESSAGELOGCONTEXT
//此外,在.pro文件定義以下的宏,可以屏蔽相應的日志輸出
//DEFINES += QT_NO_WARNING_OUTPUT
//DEFINES += QT_NO_DEBUG_OUTPUT
//DEFINES += QT_NO_INFO_OUTPUT

QByteArray localMsg = msg.toLocal8Bit();
QString content;
switch (type)
{
case QtDebugMsg:
content = QString("Debug: %1 (%2:%3, %4)\n").arg(localMsg.constData()).arg(context.file).arg(context.line).arg(context.function);
break;

case QtInfoMsg:
content = QString("Info: %1 (%2:%3, %4)\n").arg(localMsg.constData()).arg(context.file).arg(context.line).arg(context.function);
break;

case QtWarningMsg:
content = QString("Warning: %1 (%2:%3, %4)\n").arg(localMsg.constData()).arg(context.file).arg(context.line).arg(context.function);
break;

case QtCriticalMsg:
content = QString("Critical: %1 (%2:%3, %4)\n").arg(localMsg.constData()).arg(context.file).arg(context.line).arg(context.function);
break;

case QtFatalMsg:
content = QString("Fatal: %1 (%2:%3, %4)\n").arg(localMsg.constData()).arg(context.file).arg(context.line).arg(context.function);
break;

default:
content = QString("Default: %1 (%2:%3, %4)\n").arg(localMsg.constData()).arg(context.file).arg(context.line).arg(context.function);
break;
}

content = QDateTime::currentDateTime().toString("yyyy-MM-dd hh.mm.ss.zzz ") + content;

SaveLog::Instance()->save(content);
}
完整的工程源碼請下載:https://download.csdn.net/download/libaineu2004/11058474

 

三、注意事項:

1、Release 版本默認不包含這些信息:文件名、函數名、行數,需要在.pro項目文件加入以下代碼,加入后最好重新構建項目使之生效:
DEFINES += QT_MESSAGELOGCONTEXT
2、此外,在.pro文件定義以下的宏,可以屏蔽相應的日志輸出
DEFINES += QT_NO_WARNING_OUTPUT
DEFINES += QT_NO_DEBUG_OUTPUT
DEFINES += QT_NO_INFO_OUTPUT

記得把工程清除之后,再重新構建。

也可以靈活一點:

在.pro文件中加入
release:DEFINES += QT_NO_WARNING_OUTPUT \
                   QT_NO_DEBUG_OUTPUT
這樣一來,編譯debug不受影響,繼續有輸出,release的時候停止輸出。

3、如果使用的IDE是Visual Studio,那么

在VC項目配置里C/C++ /Preprocessor /Preprocessor Definitions屬性里面加入宏定義:

QT_MESSAGELOGCONTEXT

QT_NO_DEBUG_OUTPUT

QT_NO_WARNING_OUTPUT

 

四、參考文獻

https://qtdebug.com/qt-logger/ Qt 自定義日志工具

 

五、姊妹篇

《Qt日志庫Log4Qt的使用,支持文件名/行號/函數名的打印輸出》

《Spdlog日志庫的使用,支持文件名/行號/函數名的打印輸出》

============== End

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM