feat: harden logger lifecycle and add tests

This commit is contained in:
2026-07-13 13:22:10 +08:00
parent 95a8067342
commit 62ed176bdd
8 changed files with 799 additions and 190 deletions
+48 -6
View File
@@ -1,13 +1,37 @@
#ifndef LOGHANDLER_H
#ifndef LOGHANDLER_H
#define LOGHANDLER_H
#include <QObject>
#include <QtCore/qglobal.h>
class Q_DECL_EXPORT LogHandler
#if defined(MYLOGGER_TESTING)
#include <QString>
#endif
// 公用库在动态库、源码嵌入和静态链接三种场景下使用不同导出声明,
// 避免消费者把库符号错误标记为导出符号;源码嵌入模式由 MyLogger.pri 定义 MYLOGGER_STATIC。
#if defined(MYLOGGER_STATIC)
# define MYLOGGER_EXPORT
#elif defined(MYLOGGER_LIBRARY)
# define MYLOGGER_EXPORT Q_DECL_EXPORT
#else
# define MYLOGGER_EXPORT Q_DECL_IMPORT
#endif
// 进程级 Qt 消息处理器封装类,负责把 qDebug 等全局日志安全地写入本地文件。
// 同一进程只能安装一个 Qt 消息处理器,因此宿主应把其安装和卸载权交给同一处生命周期管理代码。
class MYLOGGER_EXPORT LogHandler
{
public:
void installMessageHandler(); // 给Qt安装消息处理函数
void uninstallMessageHandler(); // 取消安装消息处理函数并释放资源
// 安装全局消息处理器并打开当天日志;目录或文件不可用时返回 false,调用者可在恢复权限后重试。
bool installMessageHandler();
// 卸载当前处理器、恢复安装前的处理器并同步落盘;重复调用不会影响已经恢复后的状态。
void uninstallMessageHandler();
// 返回本库是否仍持有并安装了 Qt 全局消息处理器,供宿主避免重复管理生命周期。
bool isInstalled() const;
// 返回进程内唯一实例;C++11 局部静态对象保证首次构造线程安全。
static LogHandler& Get()
{
static LogHandler m_logHandler;
@@ -15,7 +39,25 @@ public:
}
private:
LogHandler() {};
// 禁止外部构造,确保文件句柄和 Qt 全局 handler 只由唯一实例管理。
LogHandler() = default;
};
#if defined(MYLOGGER_TESTING)
// 仅测试构建可见的访问类,用于把文件系统和分卷阈值隔离到临时目录;
// 正式库不定义该宏,因此不会向宿主程序暴露运行时配置接口。
class LogHandlerTestAccess
{
public:
// 设置测试专用日志目录;调用前必须卸载 handler,避免正在写入的文件被切换。
static void setLogDirectory(const QString &directory);
// 覆盖单文件分卷阈值;传入非正数时恢复正式库的 10 MiB 默认值。
static void setMaxLogFileBytes(qint64 bytes);
// 清除测试覆盖项,恢复正式库默认路径和分卷阈值。
static void reset();
};
#endif
#endif // LOGHANDLER_H