#include "loghandler.h" #include #include #include #include #include #include #include #include #include QMutex g_mutex; QFile g_file; QTextStream g_stream; qint64 g_lastFlushMs = 0; constexpr qint64 kLogFlushIntervalMs = 1000; // 消息处理函数 void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QMutexLocker locker(&g_mutex); QString level, colorLevel; switch (type) { case QtDebugMsg: level = "DEBUG"; colorLevel = "\033[36m" + level + "\033[0m"; // 青色 break; case QtInfoMsg: level = "INFO "; colorLevel = "\033[32m" + level + "\033[0m"; // 绿色 break; case QtWarningMsg: level = "WARN "; colorLevel = "\033[33m" + level + "\033[0m"; // 黄色 break; case QtCriticalMsg: level = "ERROR"; colorLevel = "\033[31m" + level + "\033[0m"; // 红色 break; case QtFatalMsg: level = "FATAL"; colorLevel = "\033[31m" + level + "\033[0m"; // 红色 break; default: break; } // 输出到日志文件, 格式: 时间 - [Level] (文件名:行数, 函数): 消息 QString fileName = context.file ? QString::fromUtf8(context.file) : QStringLiteral("unknown"); int index = fileName.lastIndexOf(QDir::separator()); if (index >= 0) { fileName = fileName.mid(index + 1); } const QString funcName = context.function ? QString::fromUtf8(context.function) : QStringLiteral("unknown"); QString msgOut = QString("%1-[%2](%3:%4,%5): %6") .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"),colorLevel, fileName, QString(context.line), funcName, msg); std::cout << msgOut.toLocal8Bit().constData() << std::endl; if (g_file.isOpen()) { g_stream << msgOut << "\n"; const qint64 now = QDateTime::currentMSecsSinceEpoch(); if (type >= QtCriticalMsg || now - g_lastFlushMs >= kLogFlushIntervalMs) { g_stream.flush(); g_file.flush(); g_lastFlushMs = now; } } } // 给Qt安装消息处理函数 void LogHandler::installMessageHandler() { //获取日期 auto _currentDate = QDateTime::currentDateTime().toString("yyyy-MM-dd"); //打开/创建文件 auto _appDirPath = QCoreApplication::applicationDirPath(); auto _logDirPath = _appDirPath + "/logs/"; QDir _logDir(_logDirPath); if(!_logDir.exists()) _logDir.mkpath(_logDirPath); QString _logPath; for(int i = 1; i < 1000; ++i) { _logPath = _logDirPath + _currentDate + QString("_%1.log").arg(i); QFileInfo _fileInfo(_logPath); if(!_fileInfo.exists()) { break; } } g_file.setFileName(_logPath); if(!g_file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) { return; } g_stream.setDevice(&g_file); g_stream.setCodec("UTF-8"); g_lastFlushMs = QDateTime::currentMSecsSinceEpoch(); qInstallMessageHandler(messageHandler); // 给 Qt 安装自定义消息处理函数 } // 取消安装消息处理函数并释放资源 void LogHandler::uninstallMessageHandler() { QMutexLocker locker(&g_mutex); if(g_file.isOpen()) { g_stream.flush(); g_file.flush(); g_file.close(); } g_stream.setDevice(nullptr); qInstallMessageHandler(nullptr); }