Qt 日志信息设计
分享心得,共享成功。
第一次写博客,难免会存在一些问题,大家见谅。
一、 原理
- 核心思想:qInfo(),qDebug(),qWarning(),qCritical(),qFatal() 输出重定向。
- 函数 Q_CORE_EXPORT QtMessageHandler qInstallMessageHandler(QtMessageHandler);
- QtMessageHandler:消息处理函数,详见Qt帮助,该函数主要用来处理及输出日志信息。
【注】
- 若要取消warning输出,可设置QT_NO_WARNING_OUTPUT;若要取消debug输出,可设置QT_NO_DEBUG_OUTPUT。具体方法为在pro文件中添加DEFINES += QT_NO_WARNING_OUTPUT;
- 日志类型主要有info,debug,warning,critical,fatal。对应的方法为qInfo(),qDebug(),qWarning(),qCritical(),qFatal()。
如:qDebug()<<"debug info...";
二、具体代码:
1. 日志信息系统初始化
#define _App_Log
#define _LOG_PATH "gui.log"
QFile myApp::logfile(_LOG_PATH);//static
void myApp::MesgOutPutInit()
{
if(!myApp::logfile.open(QIODevice::Append))
{
qCritical("File open failed!");//log file open failed
//Processing function
}
qInstallMessageHandler(myApp::myAppMesgHandler);
}
#endif
2. 日志信息消息处理函数:
#ifdef _App_Log
void myApp::myAppMesgHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) //static
{
static QMutex mutex;
mutex.lock();
QTextStream logstream(&myApp::logfile);
QString logtime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
QString logstr,logtype;
switch (type)
{
case QtInfoMsg:
logtype = "Info";
break;
case QtDebugMsg:
logtype = "Debug";
break;
case QtWarningMsg:
logtype = "Waring";
break;
case QtCriticalMsg:
logtype = "Critical";
break;
case QtFatalMsg:
logtype = "Fatal";
break;
default:
logtype = "Unknown";
break;
}
logstr = QString("[%1] [%2] %3(%4):line %5 %6;\n").arg(logtype).arg(logtime)\
.arg(context.file).arg(context.function).arg(QString::number(context.line)).arg(msg);
logstream << logstr;
myApp::logfile.flush();
mutex.unlock();
return;
}
#endif
踩坑记录
- 条件编译,日志处理一般属于附加功能,对于可有可无的功能,我们最好添加条件编译,方便添加或去掉该功能模块。
- 对于myApp::logfile.flush();一句,确保文件刷新,如果CPU占用率较高,或者某些情况下,文件可能会没有写入,在我们项目中出现概率还挺高。(项目不好做啊,任何没考虑到的情况都将成为噩梦…)
- 对于日志文件需要进行管理,实际应用中一般会将debug信息关闭,另外文件需要及时清除,否则可能会特别大,甚至影响设备性能。
- 日志信息输出格式可以根据自己的需求进行更改优化,添加一定的格式类似于XML,可以方便日志信息的解读。
- 文件如果在初始化打开,那么对象析构时需要添加文件关闭的操作。
- 为了避免一些不要的影响,建议对象析构时添加qInstallMessageHandler(0)。
- 一般在系统设计时,加锁可以避免同时对文件进行操作,但也可能会造成效率问题,慎重。
三. 日志信息处理思路:
- 完善的日志信息处理,不仅仅是记录信息,通常软件运行过程中必要的提醒是必不可少的,即需要监视日志及解读日志;
- 对于日志的监测可以采用“信号+槽”、“状态变量+轮询”的方式,我在此处使用第二种方式,且状态变量使用共享内存进行保存;
- 对于日志的解读可以采用解读文件(带一定的格式)、信息索引(建立错误信息的字典,当发生错误时保存的也是索引);
- 对于日志的维护,删除操作。(日志不删,内存忧伤。)