ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

QT保存日志到文件中以及捕捉崩溃日志

QT保存日志到文件中以及捕捉崩溃日志

一、qInstallMessageHandler

QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)

qInstallMessageHandler 是 Qt 框架中用于自定义消息处理的核心函数,主要用于拦截和重定向 Qt 应用程序的日志输出(如 qDebug()qWarning() 等)。

作用机制‌:

替换 Qt 默认的消息处理器,允许开发者自定义日志输出方式(如写入文件、发送到网络等)。传入的 handler 需匹配 void(QtMsgType, const QMessageLogContext&, const QString&) 函数签名‌。

参数说明‌:

1.handler: 自定义处理函数指针,若传入 nullptr 则恢复默认处理器‌。

2.返回值:指向前一个处理器的指针,便于链式调用或恢复‌。

二、QtMessageHandler handler

void(QtMsgType, const QMessageLogContext&, const QString&) 

这是一个Qt框架中用于自定义消息处理的函数签名类型,主要用于qInstallMessageHandler注册自定义日志处理器。

参数说明:

1.QtMsgType‌

Qt定义的枚举类型,标识消息级别,包括:

QtDebugMsg:调试信息(qDebug触发)
QtInfoMsg:普通信息(qInfo触发)
QtWarningMsg:警告信息(qWarning触发)
QtCriticalMsg:严重错误(qCritical触发)
QtFatalMsg:致命错误(qFatal触发)

2. QMessageLogContext‌

包含日志上下文信息的结构体,成员包括:

file:源代码文件名
line:代码行号
function:函数名
category:日志分类(Qt5.5+支持)

3. ‌QString&‌

实际日志内容的引用,需注意线程安全处理。

三、利用glog捕捉崩溃日志

google::InstallFailureWriter(&SignalHandler);

google::InstallFailureWriter(&SignalHandler) 是 Google Glog 日志库提供的核心函数,用于注册程序崩溃时的自定义信号处理器。

功能说明

当程序触发致命错误(如 SIGSEGVSIGABRT)时,自动调用绑定的 SignalHandler 函数,将崩溃信息写入日志文件或控制台。

参数要求

SignalHandler 函数签名‌

需匹配 void(const char* data, size_t size) 格式:

data:崩溃信息的字符指针
size:信息长度

四、代码示例

 log_test.pro

QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11QMAKE_LFLAGS += -no-pie# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cpp \mainwindow.cppHEADERS += \mainwindow.hFORMS += \mainwindow.uiINCLUDEPATH += /usr/include/glog
LIBS += /usr/lib/x86_64-linux-gnu/libglog.so# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QDebug>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void on_pushButton_debug_clicked();void on_pushButton_warn_clicked();void on_pushButton_crash_clicked();private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_pushButton_debug_clicked()
{qDebug()<<"这是一条调试信息日志。";
}void MainWindow::on_pushButton_warn_clicked()
{qWarning()<<"这是一条警告信息日志。";
}void MainWindow::on_pushButton_crash_clicked()
{QVector<int> vec;qDebug()<<"第一个数据为:"<<vec.at(0);
}

main.cpp

#include "mainwindow.h"#include <QApplication>
#include <QDateTime>
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QMutex>
#include <fstream>
#include "logging.h"
#include "log_severity.h"QtMessageHandler gDefaultHandler = nullptr;
static QMutex logMutex;
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{QMutexLocker locker(&logMutex);QDateTime time = QDateTime::currentDateTime();QString strTime = time.toString("MM-dd hh:mm:ss");QString strMessage = QString("[%1] [%2:%3] %4").arg(strTime).arg(QString(context.file).split("/").last()).arg(context.line).arg(msg);QString content;switch(type){//调试信息提示case QtDebugMsg:content = QString("[调试信息] %1").arg(strMessage);break;//一般的warning提示case QtWarningMsg:content = QString("[警告信息] %1").arg(strMessage);break;//严重错误提示case QtCriticalMsg:content = QString("[严重错误] %1").arg(strMessage);break;//致命错误提示case QtFatalMsg:content = QString("[致命错误] %1").arg(strMessage);abort();default:break;}QString strPath = QCoreApplication::applicationDirPath() + "/log/";QFile runLog(strPath + "log.txt");runLog.open(QIODevice::WriteOnly | QIODevice::Append);if(runLog.size() >= 1024 * 5000){runLog.close();QString backupName = QString("log_%1.txt").arg(QDateTime::currentDateTime().toString("yyyy_MM_dd_hh_mm_ss"));QFile::copy(strPath + "log.txt", strPath + backupName);runLog.remove();QFile outFile3(strPath + "log.txt");outFile3.open(QIODevice::WriteOnly | QIODevice::Append);QTextStream ts(&outFile3);ts << content << endl;}else{QTextStream ts(&runLog);ts << content << endl;}//if(gDefaultHandler){gDefaultHandler(type, context, msg);}
}// 扑捉到程序崩溃或者中断时,把相应的信息打印到log文件和输出到屏幕。
void SignalHandler(const char* data, int size) {QString logPath = QCoreApplication::applicationDirPath() + "/log/crash/" ;//组织文件名称QString strTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");logPath = logPath + strTime + ".log";std::string glog_file = logPath.toStdString();//创建文件std::ofstream fs(glog_file, std::ios::app);//打印到文件std::string str = std::string(data, size);if (fs.is_open()) {fs.write(data, size);}fs.close();
}int main(int argc, char *argv[])
{QApplication a(argc, argv);QString path = QCoreApplication::applicationDirPath() + "/log";QString logPath = path + "/crash";QDir dir(logPath);if(!dir.exists())if(dir.mkpath(logPath))qDebug()<<"创建路径:"<<logPath;gDefaultHandler = qInstallMessageHandler(messageHandler);google::InitGoogleLogging(argv[0]);//使用glog之前必须先初始化库,仅需执行一次,括号内为程序名google::InstallFailureSignalHandler();google::InstallFailureWriter(&SignalHandler);MainWindow w;w.show();return a.exec();
}

mainwindow.ui

 运行结果

日志生成

 

返回列表