这几天在交接工作,把之前手头的一个项目交接一下,想着增加一个日志模块,去查了一下,Qt自带的日志模块 qInstallMessageHandler
。
qInstallMessageHandler
位于<QtGlobal> - Global Qt Declarations
下边,属于全局函数。
QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)
Installs a Qt message handler which has been defined previously. Returns a pointer to the previous message handler. 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. The default message handler prints the message to the standard output under X11 or to the debugger under Windows. If it is a fatal message, the application aborts immediately. Only one message handler can be defined, since this is usually done on an application-wide basis to control debug output. To restore the message handler, call qInstallMessageHandler(0).
官方解释主要说了 qInstallMesageHandler 的作用,其实主要是是对 打印消息的控制,能控制打印的输出,调试,信息,警告,严重,致命错误等五个等级。
#include <qapplication.h>
#include <stdio.h>
#include <stdlib.h>
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QByteArray localMsg = msg.toLocal8Bit();
switch (type) {
case QtDebugMsg:
fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtInfoMsg:
fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtWarningMsg:
fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtCriticalMsg:
fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtFatalMsg:
fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
abort();
}
}
int main(int argc, char **argv)
{
qInstallMessageHandler(myMessageOutput);
QApplication app(argc, argv);
...
return app.exec();
}
日志模块思路如下:
1.读取日志配置文件,设置文件输出等级。可以用做,在正式项目中调试与日常关键信息打印。
2.Log消息输出方法--输出文本。
3.消息模块注册(个人理解)
枚举变量–设置日志等级 0~4 5个等级
enum{
Fatal = 0,
Critical,
Warning,
Info,
Debug
}LogLeaver;
int LogType = 4; //日志等级初始化设置
//初始化读取配置文件
void ReadLogInit()
{
QFile file ("./log_conf.ini");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){//判断文件是否可执行
return;
}
while (!file.atEnd()) {
QByteArray strBuf = file.readLine();
if(strBuf == "[LOG_CONFIG]\n")
{
strBuf = file.readLine();
LogType = strBuf.mid(strBuf.size()-1,1).toInt();
}
}
}
//配置文件格式
[LOG_CONFIG]
LogLeaver=4
void message_output(QtMsgType type,const QMessageLogContext &context,const QString &msg)
{
//加锁:避免对文件的同时读写
static QMutex mutex;
mutex.lock();
//读写消息
QByteArray localMsg = msg.toLocal8Bit();
//输出的字符串
QString strOutStream = "";
//case 生成要求格式日志文件,加日志等级过滤
switch (type) {
case QtDebugMsg:
if(LogType == Debug)
{
strOutStream = QString("%1 %2 %3 %4 [Debug] %5 \n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(QString(context.file)).arg(context.line).arg(QString(context.function)).arg(QString(localMsg));
}
break;
case QtInfoMsg:
if(LogType >= Info)
{
strOutStream = QString("%1 %2 %3 %4 [Info]: %5 \n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(QString(context.file)).arg(context.line).arg(QString(context.function)).arg(QString(localMsg));
}
break;
case QtWarningMsg:
if(LogType >= Warning)
{
strOutStream = QString("%1 %2 %3 %4 [Warning]: %5 \n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(QString(context.file)).arg(context.line).arg(QString(context.function)).arg(QString(localMsg));
}
break;
case QtCriticalMsg:
if(LogType >= Critical)
{
strOutStream = QString("%1 %2 %3 %4 [Critical]: %5 \n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(QString(context.file)).arg(context.line).arg(QString(context.function)).arg(QString(localMsg));
}
break;
case QtFatalMsg:
if(LogType >= Fatal)
{
strOutStream = QString("%1 %2 %3 %4 [Fatal]: %5 \n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(QString(context.file)).arg(context.line).arg(QString(context.function)).arg(QString(localMsg));
}
abort();
}
//每天生成一个新的log日志文件,文件名 yyyyMMdd.txt
QString strFileName = QString("%1.txt").arg(QDateTime::currentDateTime().date().toString("yyyyMMdd"));
QFile logfile(strFileName);
logfile.open(QIODevice::WriteOnly | QIODevice::Append);
if(strOutStream != "")
{
QTextStream logStream(&logfile);
logStream<<strOutStream<<"\r\n";
}
//清楚缓存文件,解锁
logfile.flush();
logfile.close();
mutex.unlock();
}
int main(int argc, char *argv[])
{
ReadLogInit();//读取日志等级
qInstallMessageHandler(message_output);//安装消息处理函数,依靠回调函数,重定向,全局处理
QApplication a(argc, argv);
qInfo()<<"\r\n\r\n\r\n**PCCamera start**";
//to doing......
}