qt5 log

7 篇文章 0 订阅

背景:

一般情况下,我们调试版本会在code里面添加一些qDebug来帮助我们修改代码。

但是当我们的软件版本发布出去,用户告诉我们软件使用出问题了,并且我们在自己的实验室无法复现问题怎么办?

这个时候怎么依靠我们之前在代码里面添加的qDebug呢?

只要用户动动小手,改个配置文件就会把原来代码里面的log输出到一个txt里,然后送给我们分析问题。

方法:

首先,我们使用帮助文档看下Qt5的这个方法

[cpp]  view plain  copy
  1. QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)  
我们可以看到下面信息。

[cpp]  view plain  copy
  1. #include <qapplication.h>  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4.   
  5. void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)  
  6. {  
  7.     QByteArray localMsg = msg.toLocal8Bit();  
  8.     switch (type) {  
  9.     case QtDebugMsg:  
  10.         fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);  
  11.         break;  
  12.     case QtInfoMsg:  
  13.         fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);  
  14.         break;  
  15.     case QtWarningMsg:  
  16.         fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);  
  17.         break;  
  18.     case QtCriticalMsg:  
  19.         fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);  
  20.         break;  
  21.     case QtFatalMsg:  
  22.         fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);  
  23.         abort();  
  24.     }  
  25. }  
  26.   
  27. int main(int argc, char **argv)  
  28. {  
  29.     qInstallMessageHandler(myMessageOutput);  
  30.     QApplication app(argc, argv);  
  31.     ...  
  32.     return app.exec();  
  33. }  

显而易见,它给我们举了个例子,告诉我们怎么使用,并且也详细描述了。

The message handler is a function that prints out debug messages, warnings, critical and fatal error messages. The Qt library (debug mode) contains hundreds of warning messages that are printed when internal errors (usually invalid function arguments) occur. Qt built in release mode also contains such warnings unless QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during compilation. If you implement your own message handler, you get total control of these messages.

我们只需要把他的信息保留到txt文件中就可以了。

同时在代码里面定义个宏,

[cpp]  view plain  copy
  1. #ifndef QT_DEBUG  
  2.     installReleaseMsgHandler();  
  3. #endif  
Debug模式在QtCreater里面显示,Release模式编译输出文件流。

注意:

如果Release模式下,在软件运行输出日志到txt的时候,用户这时关闭软件,我们必须要有个关闭txt文件的操作。

这个时候你需要了解下 这个函数

[cpp]  view plain  copy
  1. void qAddPostRoutine(QtCleanUpFunction ptr)  
Adds a global routine that will be called from the  QCoreApplication  destructor. This function is normally used to add cleanup routines for program-wide functionality.

以上基本就可以满足我们的要求了。

下来请赏脸看下我写的例子:

[cpp]  view plain  copy
  1. #include <QApplication>  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <QCoreApplication>  
  5. #include <QSettings>  
  6. #include <QDebug>  
  7. #include <QTime>  
  8. #include <QDir>  
  9.   
  10. #define _TIME_ qPrintable(QTime::currentTime().toString("hh:mm:ss:zzz"))  
  11.   
  12. static FILE *q_fileStream = NULL;  
  13. static int   g_logLevel   = 0;  
  14.   
  15. enum TraceLevel  
  16. {  
  17.     TL_NULL = 0,  
  18.     TL_CRIT,  
  19.     TL_ERRO,  
  20.     TL_WARN,  
  21.     TL_INFO  
  22. };  
  23.   
  24. static const int g_TraceLevel [] = { TL_INFO, TL_WARN, TL_ERRO, TL_CRIT, TL_NULL };  
  25.   
  26. static void SoftWareShutDown ()  
  27. {  
  28.     if (NULL != q_fileStream)  
  29.     {  
  30.         qDebug("Close log file.");  
  31.         fclose (q_fileStream);  
  32.         q_fileStream = NULL;  
  33.     }  
  34. }  
  35.   
  36. void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)  
  37. {  
  38.     Q_UNUSED(type);  
  39.     QByteArray localMsg = msg.toLocal8Bit();  
  40.     if (g_logLevel && q_fileStream)  
  41.     {  
  42.         int iLevel = g_TraceLevel[type];  
  43.         if (g_logLevel < iLevel)  
  44.         {  
  45.             return;  
  46.         }  
  47.   
  48.         fprintf (q_fileStream, "%s: %s (%s:%u, %s)\n", _TIME_, localMsg.constData(), context.file, context.line, context.function);  
  49.         fflush (q_fileStream);  
  50.     }  
  51. }  
  52.   
  53. static void installMsgHandler(QString strLogFile)  
  54. {  
  55.     QByteArray byteArrayLogFile = strLogFile.toLatin1();  
  56.   
  57.     if (NULL != q_fileStream)  
  58.     {  
  59.         fclose (q_fileStream);  
  60.         q_fileStream = NULL;  
  61.     }  
  62.   
  63.     q_fileStream = fopen (byteArrayLogFile.constData (), "w+");  
  64.     if (NULL != q_fileStream)  
  65.     {  
  66.         qDebug("Opened log file.");  
  67.         qInstallMessageHandler(myMessageOutput);  
  68.     }  
  69.     else  
  70.     {  
  71.         qDebug("Failed to open log file.");  
  72.     }  
  73. }  
  74.   
  75. static void installReleaseMsgHandler ()  
  76. {  
  77.     QString strAppPath = QCoreApplication::applicationDirPath();  
  78.     QString strIniFile = strAppPath + "/RunInfo.ini";  
  79.     QString strLogFile = strAppPath + "/log.txt";  
  80.     QSettings pSettings(strIniFile, QSettings::IniFormat);  
  81.     g_logLevel = pSettings.value("TraceSet/TraceLevel", 1).toInt();  
  82.     installMsgHandler (strLogFile);  
  83. }  
  84.   
  85. int main(int argc, char *argv[])  
  86. {  
  87.     QApplication a(argc, argv);  
  88. #ifndef QT_DEBUG  
  89.     bool bAddQuitFunc = false;  
  90.     installReleaseMsgHandler();  
  91.     if (!bAddQuitFunc)  
  92.     {  
  93.         qAddPostRoutine (SoftWareShutDown);  
  94.         bAddQuitFunc = true;  
  95.     }  
  96. #endif  
  97.     Window w;  
  98.     w.show();  
  99.     return a.exec();  
  100. }  

运行顺序:

1. 判断是否为Release

2. installReleaseMsgHandler     // 初始化 ini信息,和log文件位置

3. installMsgHandler                  // 打开文件,并调用 qInstallMessageHandler

4. myMessageOutput                // 根据之前 读取的log等级 按照要求输出log
5. qAddPostRoutine                  // 检测软件是否关闭,调用关闭文件函数

6. SoftWareShutDown              // 关闭文件


同时说明下,我的RunInfo.ini文件信息

就两行

[TraceSet]
TraceLevel=4

平时为1 ,当我们需要打log的时候改为4(全部信息,qDebug/qWarning/qCritical/qInfo),改为3的时候....自己试试吧。


上面代码的CSDN链接:http://download.csdn.net/detail/c3060911030/9464986

主要 ini文件要放置正确位置,在运行目录下。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值