feat: 提供实时日志快照
This commit is contained in:
@@ -47,6 +47,8 @@ struct LogState
|
||||
QDate activeDate;
|
||||
QString currentFilePrefix;
|
||||
bool installed = false;
|
||||
std::function<void()> updateCallback; // 回调仅投递通知,不在锁内访问界面或日志。
|
||||
QStringList recentLines; // 有界缓存最近打印内容;后台线程与界面均通过 mutex 访问。
|
||||
#if defined(MYLOGGER_TESTING)
|
||||
// 测试编译时将文件系统副作用收敛到临时目录,并用小阈值快速覆盖分卷逻辑。
|
||||
QString testLogDirectory;
|
||||
@@ -313,6 +315,13 @@ void messageHandler(QtMsgType type, const QMessageLogContext &context, const QSt
|
||||
return;
|
||||
}
|
||||
|
||||
// 只缓存最近打印,避免界面长期运行时无限增长;与文件写入共用锁。
|
||||
g_logState.recentLines.append(timestamp + QStringLiteral(" ") + msg);
|
||||
if (g_logState.recentLines.size() > 1000)
|
||||
g_logState.recentLines.removeFirst();
|
||||
if (g_logState.updateCallback)
|
||||
g_logState.updateCallback();
|
||||
|
||||
// 跨午夜时先关闭旧日期文件再按新日期选择分卷;轮转失败后的后续消息也会重试打开,
|
||||
// 这样临时磁盘或权限故障恢复后无需重启应用即可恢复文件日志。
|
||||
const QDate today = QDate::currentDate();
|
||||
@@ -416,6 +425,23 @@ bool LogHandler::isInstalled() const
|
||||
return g_logState.installed;
|
||||
}
|
||||
|
||||
// 回调的安装与清除同样持锁,确保界面销毁后后台线程不再访问接收对象。
|
||||
void LogHandler::setUpdateCallback(const std::function<void()> &callback)
|
||||
{
|
||||
QMutexLocker locker(&g_logState.mutex);
|
||||
g_logState.updateCallback = callback;
|
||||
}
|
||||
|
||||
// 快照不暴露文件句柄,后台写入和界面轮询不会并发访问 QTextStream。
|
||||
void LogHandler::snapshot(bool &active, QString &path, qint64 &bytes, QStringList &lines) const
|
||||
{
|
||||
QMutexLocker locker(&g_logState.mutex);
|
||||
active = g_logState.installed && g_logState.file.isOpen();
|
||||
path = active ? g_logState.file.fileName() : logDirectoryPath();
|
||||
bytes = active ? g_logState.currentFileBytes : 0;
|
||||
lines = g_logState.recentLines;
|
||||
}
|
||||
|
||||
#if defined(MYLOGGER_TESTING)
|
||||
// 测试目录设置在同一把锁下更新,并要求 handler 已卸载,保证没有线程持有旧目录的文件句柄。
|
||||
void LogHandlerTestAccess::setLogDirectory(const QString &directory)
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#define LOGHANDLER_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <functional>
|
||||
|
||||
#if defined(MYLOGGER_TESTING)
|
||||
#include <QString>
|
||||
@@ -31,6 +34,12 @@ public:
|
||||
// 返回本库是否仍持有并安装了 Qt 全局消息处理器,供宿主避免重复管理生命周期。
|
||||
bool isInstalled() const;
|
||||
|
||||
// 在同一把锁下读取当前文件、大小和最近日志,供界面安全轮询。
|
||||
void snapshot(bool &active, QString &path, qint64 &bytes, QStringList &lines) const;
|
||||
|
||||
// 设置轻量日志通知;回调在写入线程执行,不能访问日志处理器或界面。
|
||||
void setUpdateCallback(const std::function<void()> &callback);
|
||||
|
||||
// 返回进程内唯一实例;C++11 局部静态对象保证首次构造线程安全。
|
||||
static LogHandler& Get()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user