feat:添加导出日志功能

This commit is contained in:
2025-09-27 11:28:30 +08:00
parent 4951fc7dd1
commit b7bf70e402
3 changed files with 68 additions and 9 deletions

View File

@@ -27,8 +27,8 @@ VERSION = $$BUILD_VERSION
isEmpty(VERSION): VERSION = 4.0.0 isEmpty(VERSION): VERSION = 4.0.0
DEFINES += APP_VERSION=\\\"'$${VERSION}'\\\" DEFINES += APP_VERSION=\\\"'$${VERSION}'\\\"
DEFINES += APP_BRANCH=\\\"'$$system(git symbolic-ref --short -q HEAD)'\\\" DEFINES += APP_BRANCH=\\\"'$$system(git symbolic-ref --short -q HEAD)'\\\"
# Disable qWarning / qDebug output in Release # Enable all log outputs in both Debug and Release modes
#CONFIG(release, debug | release): DEFINES += QT_NO_WARNING_OUTPUT QT_NO_DEBUG_OUTPUT # We want to capture all logs (INFO, DEBUG, WARNING, ERROR) for export to /tmp/spark-store
CONFIG += c++11 link_pkgconfig CONFIG += c++11 link_pkgconfig
PKGCONFIG += dtkcore dtkgui dtkwidget PKGCONFIG += dtkcore dtkgui dtkwidget
@@ -107,4 +107,4 @@ qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/durapps/$${TARGET}/bin else: unix:!android: target.path = /opt/durapps/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target !isEmpty(target.path): INSTALLS += target
DISTFILES += DISTFILES +=

View File

@@ -285,6 +285,39 @@ bool Utils::shouldDisableWebEngineSandbox()
static QFile *logFile = nullptr; static QFile *logFile = nullptr;
static QString logFilePath; static QString logFilePath;
// 自定义消息处理器捕获所有Qt日志输出
void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QByteArray localMsg = msg.toLocal8Bit();
QString level;
switch (type) {
case QtDebugMsg:
level = "DEBUG";
fprintf(stderr, "DEBUG: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtInfoMsg:
level = "INFO";
fprintf(stderr, "INFO: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtWarningMsg:
level = "WARNING";
fprintf(stderr, "WARNING: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtCriticalMsg:
level = "ERROR";
fprintf(stderr, "ERROR: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtFatalMsg:
level = "FATAL";
fprintf(stderr, "FATAL: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
abort();
}
// 写入到日志文件
Utils::writeLog(level, msg);
}
// 初始化日志系统 // 初始化日志系统
void Utils::initLogger() void Utils::initLogger()
{ {
@@ -308,6 +341,9 @@ void Utils::initLogger()
return; return;
} }
// 安装自定义消息处理器捕获所有Qt日志输出
qInstallMessageHandler(customMessageHandler);
// 写入日志头信息 // 写入日志头信息
writeLog("INFO", "Logger initialized"); writeLog("INFO", "Logger initialized");
writeLog("INFO", QString("Application started at %1").arg( writeLog("INFO", QString("Application started at %1").arg(
@@ -341,11 +377,16 @@ void Utils::writeLog(const QString &level, const QString &message)
// 导出日志 // 导出日志
bool Utils::exportLogs(const QString &targetPath) bool Utils::exportLogs(const QString &targetPath)
{ {
QString exportPath = targetPath;
if (exportPath.isEmpty()) {
exportPath = "/tmp/spark-store";
}
// 确保目标目录存在 // 确保目标目录存在
QDir dir; QDir dir;
if (!dir.exists(targetPath)) { if (!dir.exists(exportPath)) {
if (!dir.mkpath(targetPath)) { if (!dir.mkpath(exportPath)) {
writeLog("ERROR", QString("Failed to create target directory: %1").arg(targetPath)); writeLog("ERROR", QString("Failed to create target directory: %1").arg(exportPath));
return false; return false;
} }
} }
@@ -356,8 +397,8 @@ bool Utils::exportLogs(const QString &targetPath)
} }
// 复制日志文件到目标位置 // 复制日志文件到目标位置
QString targetLogPath = targetPath + QString("/spark-store_log_export_%1.log").arg( QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss");
QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss")); QString targetLogPath = exportPath + QString("/spark-store_full_log_%1.log").arg(timestamp);
bool success = QFile::copy(logFilePath, targetLogPath); bool success = QFile::copy(logFilePath, targetLogPath);
@@ -370,7 +411,23 @@ bool Utils::exportLogs(const QString &targetPath)
} }
if (success) { if (success) {
writeLog("INFO", QString("Logs exported to: %1").arg(targetLogPath)); writeLog("INFO", QString("All logs (INFO, DEBUG, WARNING, ERROR) exported to: %1").arg(targetLogPath));
// 同时创建一个简单的导出报告
QString reportPath = exportPath + QString("/export_report_%1.txt").arg(timestamp);
QFile reportFile(reportPath);
if (reportFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&reportFile);
out << "Spark Store Log Export Report\n";
out << "================================\n";
out << "Export Time: " << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") << "\n";
out << "Target Directory: " << exportPath << "\n";
out << "Log File: " << targetLogPath << "\n";
out << "Original Log: " << logFilePath << "\n";
out << "Log Levels: INFO, DEBUG, WARNING, ERROR, FATAL\n";
out << "Status: SUCCESS\n";
reportFile.close();
}
} else { } else {
writeLog("ERROR", QString("Failed to export logs to: %1").arg(targetLogPath)); writeLog("ERROR", QString("Failed to export logs to: %1").arg(targetLogPath));
} }

View File

@@ -4,6 +4,8 @@
#include <QObject> #include <QObject>
#include <QJsonObject> #include <QJsonObject>
#include <QString> #include <QString>
#include <QMessageLogContext>
#include <QtGlobal>
class Utils class Utils
{ {