问题描述
在 macOS 本地运行 AstrBot 时,如果开启文件日志,进程退出时会稳定出现 Python multiprocessing.resource_tracker 的 semaphore 泄漏提示:
resource_tracker: There appear to be 8 leaked semaphore objects to clean up at shutdown
如果同时开启普通日志和 trace 日志,则数量会变成 16:
resource_tracker: There appear to be 16 leaked semaphore objects to clean up at shutdown
该问题不影响主功能运行,但会污染退出时的终端输出,也容易让用户误以为插件或平台适配器存在资源泄漏。
复现条件
环境:
- macOS
- Python 3.12
- AstrBot v4.25.2
配置中开启文件日志:
{
"log_file_enable": true,
"log_file_path": "logs/astrbot.log"
}
如果同时开启 trace 日志:
{
"log_file_enable": true,
"trace_log_enable": true,
"log_file_path": "logs/astrbot.log",
"trace_log_path": "logs/astrbot.trace.log"
}
启动 AstrBot 后退出进程,即可看到 warning。
实际表现
开启一个文件日志 sink 时:
resource_tracker: There appear to be 8 leaked semaphore objects to clean up at shutdown
同时开启普通日志和 trace 日志时:
resource_tracker: There appear to be 16 leaked semaphore objects to clean up at shutdown
预期表现
AstrBot 正常关闭时应 flush 并移除 Loguru sink,不应在退出阶段输出 resource_tracker semaphore warning。
初步原因分析
astrbot/core/log.py 中的文件日志 sink 使用了 Loguru 的 enqueue=True:
_loguru.add(..., enqueue=True, ...)
Loguru 在 enqueue=True 时会创建 multiprocessing 队列相关资源。当前这些 sink 在日志重配置时会被移除,但在 AstrBot 进程关闭路径中没有统一清理。
因此,当进程退出时,Python 的 multiprocessing.resource_tracker 仍能观察到未清理的 semaphore,于是输出 warning。
影响范围
- 不影响 AstrBot 主功能
- 不属于安全问题
- 属于退出阶段的资源清理 / 终端噪音问题
- 对插件作者和用户有误导性,容易被误判为插件泄漏
建议修复方向
增加统一的日志 shutdown 流程:
-
在 LogManager 中新增 shutdown():
await _loguru.complete()
- 移除 trace/file/console sinks
- 重置内部 sink id 和 configured 状态
-
在 AstrBot 正常关闭路径调用 LogManager.shutdown()
-
对 astrbot run 增加 SIGINT / SIGTERM graceful shutdown,避免进程收到信号时直接退出,导致日志清理逻辑无法执行
本地验证结果
修复后在 macOS 本地真实启动 AstrBot,并开启:
{
"log_file_enable": true,
"trace_log_enable": true
}
启动到:
随后发送 SIGTERM 关闭进程。
结果:
EXIT_CODE=0
WARNING_COUNT=0
未再出现:
resource_tracker
leaked semaphore objects
semaphore objects
SIGINT 场景也未再出现该 warning。
问题描述
在 macOS 本地运行 AstrBot 时,如果开启文件日志,进程退出时会稳定出现 Python
multiprocessing.resource_tracker的 semaphore 泄漏提示:如果同时开启普通日志和 trace 日志,则数量会变成 16:
该问题不影响主功能运行,但会污染退出时的终端输出,也容易让用户误以为插件或平台适配器存在资源泄漏。
复现条件
环境:
配置中开启文件日志:
{ "log_file_enable": true, "log_file_path": "logs/astrbot.log" }如果同时开启 trace 日志:
{ "log_file_enable": true, "trace_log_enable": true, "log_file_path": "logs/astrbot.log", "trace_log_path": "logs/astrbot.trace.log" }启动 AstrBot 后退出进程,即可看到 warning。
实际表现
开启一个文件日志 sink 时:
同时开启普通日志和 trace 日志时:
预期表现
AstrBot 正常关闭时应 flush 并移除 Loguru sink,不应在退出阶段输出
resource_trackersemaphore warning。初步原因分析
astrbot/core/log.py中的文件日志 sink 使用了 Loguru 的enqueue=True:Loguru 在
enqueue=True时会创建 multiprocessing 队列相关资源。当前这些 sink 在日志重配置时会被移除,但在 AstrBot 进程关闭路径中没有统一清理。因此,当进程退出时,Python 的
multiprocessing.resource_tracker仍能观察到未清理的 semaphore,于是输出 warning。影响范围
建议修复方向
增加统一的日志 shutdown 流程:
在
LogManager中新增shutdown():await _loguru.complete()在 AstrBot 正常关闭路径调用
LogManager.shutdown()对
astrbot run增加 SIGINT / SIGTERM graceful shutdown,避免进程收到信号时直接退出,导致日志清理逻辑无法执行本地验证结果
修复后在 macOS 本地真实启动 AstrBot,并开启:
{ "log_file_enable": true, "trace_log_enable": true }启动到:
随后发送 SIGTERM 关闭进程。
结果:
未再出现:
SIGINT 场景也未再出现该 warning。