前言
在开发工作中,程序在使用时,出现错误问题,对于用户来说,查看日志信息,来初步排查问题是很有必要的
注意:我这里是windows环境的写法,linux的路径和命令有些不同,linux环境的同学不可直接照搬
6.15更新:
在网上还看到通过调用qInstallMessageHandler安装消息处理程序,这是官方文档对消息处理程序的介绍,即我们可以自定义qDebug,qInfo时打印什么信息,信息打印到哪里。代码放在文末
直接上代码:
.h文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
static int WriteLog(QString errInfo);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
.cpp文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QCoreApplication>
#include <QDir>
#include <QProcess>
#include <QDebug>
#include <QDateTime>
#include <QFile>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
WriteLog("---success---直播功能设置成功");
WriteLog("----infos----正在向数据库插入信息......");
WriteLog("---warning---无挂载信息");
WriteLog("----error----/etc/lancoo/rec-server.ini文件不存在");
}
MainWindow::~MainWindow()
{
delete ui;
}
//主要代码
int MainWindow::WriteLog(QString info)
{
QString localApplicationDirPath = QCoreApplication::applicationDirPath(); //可执行程序所在目录
QString log_file;
QString log_dir=localApplicationDirPath+"/log";
QDir dir(log_dir);
//cmd中创建文件需要使用\,使用/报错
log_dir.replace("/","\\");
if(!dir.exists())
{
//创建在可执行程序所在目录创建log文件
system(QString(" mkdir %1").arg(log_dir).toStdString().data());
qDebug()<<log_dir;
}
QDateTime current_date_time =QDateTime::currentDateTime();
QString date = current_date_time.toString("yyyy-MM-dd");
//在c++中\表示转义,\\才为字符\
log_file=log_dir+"\\"+"log_"+date+".txt";
//保存原文件的内容,直接write会把原内容覆盖掉
QFile file_read(log_file);
file_read.open(QIODevice::ReadOnly);
QByteArray file_readAll = file_read.readAll();
file_read.close();
//向文件中写入信息
QFile file_write(log_file);
if(file_write.open(QIODevice::WriteOnly)){
file_write.write(file_readAll.data());
QString temp_info;
temp_info+="[";
temp_info+=current_date_time.toString("yyyy-MM-dd hh:mm:ss");
temp_info+="] ";
temp_info+=info;
temp_info+="\r\n"; //换行符,linux为\n
file_write.write(temp_info.toStdString().data());
}
file_write.close();
return
}
看主要代码即可,将其定义为静态方法是为了在别的类中也能很方便地调用
log文件在可执行程序所在目录下
注意:qt将编译文件和源文件分开管理,通过影子构建的方式,可执行文件大概率在别的目录。如果这里勾选了,则到对应目录下找可执行程序,如果这里没勾选,择取代码源文件目录下找
在自定义writeLog的基础上我们来自定义消息处理程序:
将自定义的函数myMessageOutput写在main.cpp中,消息处理程序的安装写在main()方法中,这样全局所有类的qDebug都可以将信息直接打印到日志文件中。注释掉qInstallMessageHandler(myMessageOutput);或者qInstallMessageHandler(0)来回复消息处理程序
#include "mainwindow.h"
#include <QApplication>
#include <QDateTime>
#include <QDir>
#include <QFile>
#include <QMutex>
#include <QTextStream>
#include <QDebug>
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
// 加锁
static QMutex mutex;
mutex.lock();
QByteArray localMsg = msg.toLocal8Bit();
QString strMsg("");
switch(type)
{
case QtDebugMsg:
strMsg = QString("----Debug----");
break;
case QtInfoMsg:
strMsg = QString("----Infos----");
break;
case QtWarningMsg:
strMsg = QString("---Warning---");
break;
case QtCriticalMsg:
strMsg = QString("---Critical---");
break;
case QtFatalMsg:
strMsg = QString("----Fatal----");
break;
}
// 设置输出信息格式
QString strDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
QString strMessage = QString("[%1] %5 %6\t-------------File:%2 Line:%3 Function:%4 ")
.arg(strDateTime).arg(context.file).arg(context.line).arg(context.function).arg(strMsg).arg(localMsg.constData());
//获取可执行程序所在目录
QString localApplicationDirPath = QCoreApplication::applicationDirPath();
QString log_file;
QString log_dir=localApplicationDirPath+"/log";
QDir dir(log_dir);
//cmd中创建文件需要使用\,使用/报错
log_dir.replace("/","\\");
if(!dir.exists())
{
//创建在可执行程序所在目录创建log文件
system(QString(" mkdir %1").arg(log_dir).toStdString().data());
}
QDateTime current_date_time =QDateTime::currentDateTime();
QString date = current_date_time.toString("yyyy-MM-dd");
//在c++中\表示转义,\\才为字符"\"
log_file=log_dir+"\\"+"log_"+date+".txt";
// 输出信息至文件中(读写、追加形式)
QFile file(log_file);
file.open(QIODevice::ReadWrite | QIODevice::Append);
QTextStream stream(&file);
stream << strMessage << "\r\n";
file.flush();
file.close();
// 解锁
mutex.unlock();
}
int main(int argc, char *argv[])
{
// 安装消息处理程序
qInstallMessageHandler(myMessageOutput);
QApplication a(argc, argv);
MainWindow w;
qDebug("This is a debug message.");
qInfo("This is a info message.");
qWarning("This is a warning message.");
qCritical("This is a critical message.");
w.show();
return a.exec();
}
这样在发行版的程序中就可以直接通过日志文件来排查错误信息了
运行结果:
码字不易,如果这篇博客对你有帮助,麻烦点赞收藏,非常感谢!有不对的地方,可以评论区交流。