|
|
@ -6,63 +6,72 @@ |
|
|
#include <QDir> |
|
|
#include <QDir> |
|
|
#include <QFile> |
|
|
#include <QFile> |
|
|
#include <QFileInfo> |
|
|
#include <QFileInfo> |
|
|
#include <QTimer> |
|
|
|
|
|
#include <QTextStream> |
|
|
#include <QTextStream> |
|
|
#include <QTextCodec> |
|
|
|
|
|
#include "Singleton.h" |
|
|
|
|
|
#include <QCoreApplication> |
|
|
#include <QCoreApplication> |
|
|
|
|
|
|
|
|
QMutex g_mutex; |
|
|
QMutex g_mutex; |
|
|
//QTextStream *g_in = nullptr;
|
|
|
|
|
|
QFile g_file; |
|
|
QFile g_file; |
|
|
|
|
|
QTextStream g_stream; |
|
|
|
|
|
qint64 g_lastFlushMs = 0; |
|
|
|
|
|
constexpr qint64 kLogFlushIntervalMs = 1000; |
|
|
|
|
|
|
|
|
// 消息处理函数
|
|
|
// 消息处理函数
|
|
|
void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) |
|
|
void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) |
|
|
{ |
|
|
{ |
|
|
g_mutex.lock(); |
|
|
QMutexLocker locker(&g_mutex); |
|
|
QString level; |
|
|
QString level, colorLevel; |
|
|
|
|
|
|
|
|
switch (type) |
|
|
switch (type) |
|
|
{ |
|
|
{ |
|
|
case QtDebugMsg: |
|
|
case QtDebugMsg: |
|
|
level = "DEBUG"; |
|
|
level = "DEBUG"; |
|
|
|
|
|
colorLevel = "\033[36m" + level + "\033[0m"; // 青色
|
|
|
break; |
|
|
break; |
|
|
case QtInfoMsg: |
|
|
case QtInfoMsg: |
|
|
level = "INFO "; |
|
|
level = "INFO "; |
|
|
|
|
|
colorLevel = "\033[32m" + level + "\033[0m"; // 绿色
|
|
|
break; |
|
|
break; |
|
|
case QtWarningMsg: |
|
|
case QtWarningMsg: |
|
|
level = "WARN "; |
|
|
level = "WARN "; |
|
|
|
|
|
colorLevel = "\033[33m" + level + "\033[0m"; // 黄色
|
|
|
break; |
|
|
break; |
|
|
case QtCriticalMsg: |
|
|
case QtCriticalMsg: |
|
|
level = "ERROR"; |
|
|
level = "ERROR"; |
|
|
|
|
|
colorLevel = "\033[31m" + level + "\033[0m"; // 红色
|
|
|
break; |
|
|
break; |
|
|
case QtFatalMsg: |
|
|
case QtFatalMsg: |
|
|
level = "FATAL"; |
|
|
level = "FATAL"; |
|
|
|
|
|
colorLevel = "\033[31m" + level + "\033[0m"; // 红色
|
|
|
break; |
|
|
break; |
|
|
default: |
|
|
default: |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 输出到标准输出: Windows 下 std::cout 使用 GB2312,而 msg 使用 UTF-8,但是程序的 Local 也还是使用 UTF-8
|
|
|
|
|
|
#if defined(Q_OS_WIN) |
|
|
|
|
|
QByteArray localMsg = QTextCodec::codecForName("GB2312")->fromUnicode(msg); //msg.toLocal8Bit();
|
|
|
|
|
|
#else |
|
|
|
|
|
QByteArray localMsg = msg.toLocal8Bit(); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
// 输出到日志文件, 格式: 时间 - [Level] (文件名:行数, 函数): 消息
|
|
|
// 输出到日志文件, 格式: 时间 - [Level] (文件名:行数, 函数): 消息
|
|
|
QString fileName = context.file; |
|
|
QString fileName = context.file ? QString::fromUtf8(context.file) : QStringLiteral("unknown"); |
|
|
int index = fileName.lastIndexOf(QDir::separator()); |
|
|
int index = fileName.lastIndexOf(QDir::separator()); |
|
|
|
|
|
if (index >= 0) |
|
|
|
|
|
{ |
|
|
fileName = fileName.mid(index + 1); |
|
|
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") |
|
|
QString msgOut = QString("%1-[%2](%3:%4,%5): %6") |
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz")).arg(level) |
|
|
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"),colorLevel, fileName, QString(context.line), funcName, msg); |
|
|
.arg(fileName).arg(context.line).arg(context.function).arg(msg); |
|
|
|
|
|
std::cout << msgOut.toLocal8Bit().constData() << std::endl; |
|
|
std::cout << msgOut.toLocal8Bit().constData() << std::endl; |
|
|
QTextStream in(&g_file); |
|
|
|
|
|
in.setCodec("UTF-8"); |
|
|
if (g_file.isOpen()) |
|
|
in << msgOut << "\n"; |
|
|
{ |
|
|
// g_file.flush();
|
|
|
g_stream << msgOut << "\n"; |
|
|
g_mutex.unlock(); |
|
|
const qint64 now = QDateTime::currentMSecsSinceEpoch(); |
|
|
|
|
|
if (type >= QtCriticalMsg || now - g_lastFlushMs >= kLogFlushIntervalMs) |
|
|
|
|
|
{ |
|
|
|
|
|
g_stream.flush(); |
|
|
|
|
|
g_file.flush(); |
|
|
|
|
|
g_lastFlushMs = now; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 给Qt安装消息处理函数
|
|
|
// 给Qt安装消息处理函数
|
|
|
@ -94,19 +103,23 @@ void LogHandler::installMessageHandler() |
|
|
{ |
|
|
{ |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
// g_in = new QTextStream(&g_file);
|
|
|
|
|
|
|
|
|
g_stream.setDevice(&g_file); |
|
|
|
|
|
g_stream.setCodec("UTF-8"); |
|
|
|
|
|
g_lastFlushMs = QDateTime::currentMSecsSinceEpoch(); |
|
|
qInstallMessageHandler(messageHandler); // 给 Qt 安装自定义消息处理函数
|
|
|
qInstallMessageHandler(messageHandler); // 给 Qt 安装自定义消息处理函数
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 取消安装消息处理函数并释放资源
|
|
|
// 取消安装消息处理函数并释放资源
|
|
|
void LogHandler::uninstallMessageHandler() |
|
|
void LogHandler::uninstallMessageHandler() |
|
|
{ |
|
|
{ |
|
|
g_mutex.lock(); |
|
|
QMutexLocker locker(&g_mutex); |
|
|
if(g_file.isOpen()) |
|
|
if(g_file.isOpen()) |
|
|
{ |
|
|
{ |
|
|
|
|
|
g_stream.flush(); |
|
|
g_file.flush(); |
|
|
g_file.flush(); |
|
|
g_file.close(); |
|
|
g_file.close(); |
|
|
} |
|
|
} |
|
|
g_mutex.unlock(); |
|
|
g_stream.setDevice(nullptr); |
|
|
qInstallMessageHandler(nullptr); |
|
|
qInstallMessageHandler(nullptr); |
|
|
} |
|
|
} |
|
|
|