You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

133 lines
3.8 KiB

#include "loghandler.h"
#include <iostream>
#include <QDebug>
#include <QDateTime>
#include <QMutexLocker>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QTextStream>
#include <QCoreApplication>
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("?");
int index = fileName.lastIndexOf(QDir::separator());
if (index >= 0)
{
fileName = fileName.mid(index + 1);
}
const QString funcName = context.function ? QString::fromUtf8(context.function) : QStringLiteral("?");
const QString lineText = QString::number(context.line);
const QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
const QString consoleMsg = QString("%1-[%2](%3:%4,%5): %6")
.arg(timestamp, colorLevel, fileName, lineText, funcName, msg);
const QString fileMsg = QString("%1-[%2](%3:%4,%5): %6")
.arg(timestamp, level, fileName, lineText, funcName, msg);
std::cout << consoleMsg.toLocal8Bit().constData() << std::endl;
if (g_file.isOpen())
{
g_stream << fileMsg << "\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()
{
static bool installFlag = false;
if(installFlag)
return;
installFlag = true;
//获取日期
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);
}