Description / 描述
背景 / 问题
当前 AstrBot 所有插件与核心共用同一个全局 logger(logging.getLogger("astrbot")):
astrbot/__init__.py:logger = logging.getLogger("astrbot")
- 插件作者通过
from astrbot.api import logger 获取的就是这个全局 logger(见 docs/zh/dev/star/plugin.md:请务必使用 from astrbot.api import logger 来获取日志对象)。
Star 基类(astrbot/core/star/base.py)内部也是 logger = logging.getLogger("astrbot")。
LogManager.configure_logger()(astrbot/core/log.py)直接对这个共享 logger 调用 logger.setLevel(level)。
这意味着无法针对单个插件单独调整日志等级。作者想临时观察某个插件的 debug 细节时,目前只有三种方案,但三者皆有明显缺陷:
方案 1:开启全局 DEBUG level
直接把全局日志等级调到 DEBUG。
- 🔴 缺陷:会导致所有插件、核心、以及第三方库的 raw 信息一起涌入日志,海量噪声把真正想看的信息淹没,排查效率极差。
方案 2:插件自己写 debug 开关,用 INFO 级别打印
在插件里自己实现一个 debug 配置开关,然后在需要的地方 if self.debug: logger.info(...)。
- 🔴 缺陷:产生大量冗余的
if 判断代码,不够优雅;本质上是在应用层重新发明日志分级,使得 logger 自带的 level 设计被架空。
方案 3:插件运行时动态 logger.setLevel(...)
插件在运行时对共享 logger 调用 setLevel。
- 🔴 缺陷:由于是同一个全局 logger 实例,A 插件改了 level 会直接影响 B 插件乃至核心,插件之间状态互相干涉,稳定性差、行为不可预测。
提议 / 期望行为
为每个插件提供独立的 logger(例如以插件 ID / 模块路径作为 logger name 的 child logger),并允许插件独立设置自身 logger 的 level,互不干扰。
这样带来的收益:
- 插件作者只需在需要展示细节的地方直接使用
logger.debug(...),无需反复写 if debug: 判断,代码更优雅,也让 logger 的 level 分级机制回归其本来的设计意图。
- 想分析某个插件行为时,只调高该插件自己的 logger level 到 DEBUG 即可,不会污染全局日志,也不会淹没其他插件/核心的输出。
- 每个插件的 level 相互隔离,动态调整不会像现在这样产生插件间的状态串扰,稳定性更好。
- 日志行中已有
plugin_tag(见 _LoguruInterceptHandler / 各 sink 的 format),天然适合按插件维度做过滤与分级。
可选的实现方向(供参考,非硬性要求)
- 基于 child logger:在
Star 基类或插件加载流程中,为插件生成 logging.getLogger(f"astrbot.plugin.{plugin_id}") 之类的独立 logger,并让 from astrbot.api import logger 在插件上下文中拿到的是该插件专属 logger(或额外暴露 self.logger)。
- 现有
LogManager.GetLogger(log_name=...) 已经支持按名字获取并挂载 loguru intercept handler,可复用。
- 需要注意
propagate 与 handler 的挂载关系,避免重复输出。
- 每插件 level 配置 + WebUI 支持:在插件配置或 WebUI「管理行为」中允许为单个插件设置日志等级,
PluginManager.load() 时读取并应用到该插件的独立 logger。
- 保持向后兼容:核心仍使用
astrbot logger;插件默认继承一个合理的默认等级(如 INFO),仅在作者显式开启时降到 DEBUG。
相关代码位置
astrbot/__init__.py — 全局 logger = logging.getLogger("astrbot")
astrbot/api/__init__.py — 对外导出 logger
astrbot/core/star/base.py — Star 基类中的 logger = logging.getLogger("astrbot")
astrbot/core/log.py — LogManager.GetLogger() / configure_logger() / set_queue_handler() 等
astrbot/core/star/star_manager.py — PluginManager.load() 插件加载流程(可在此处为插件注入独立 logger 并应用 level)
docs/zh/dev/star/plugin.md — 现有「请使用 from astrbot.api import logger」的开发者指引,需同步更新
Use Case / 使用场景
插件作者在调试/分析单个插件行为时:
- 只想看某一个插件的 debug 细节,而不希望开启全局 DEBUG 后被其他插件和核心的海量日志淹没。
- 希望在代码里直接写
logger.debug(...),不必再为每条调试日志包裹 if self.debug: 判断,减少冗余代码。
- 多个插件同时运行时,某个插件调整自身日志等级不应影响其他插件的日志行为,避免动态
setLevel 造成的插件间状态干涉与不稳定。
典型操作流程(期望):在 WebUI 或插件配置中,把目标插件的日志等级设为 DEBUG → 只有该插件输出 debug 日志 → 排查完毕改回 INFO,全程不影响其他插件与核心。
Willing to Submit PR? / 是否愿意提交PR?
Code of Conduct
Description / 描述
背景 / 问题
当前 AstrBot 所有插件与核心共用同一个全局 logger(
logging.getLogger("astrbot")):astrbot/__init__.py:logger = logging.getLogger("astrbot")from astrbot.api import logger获取的就是这个全局 logger(见docs/zh/dev/star/plugin.md:请务必使用from astrbot.api import logger来获取日志对象)。Star基类(astrbot/core/star/base.py)内部也是logger = logging.getLogger("astrbot")。LogManager.configure_logger()(astrbot/core/log.py)直接对这个共享 logger 调用logger.setLevel(level)。这意味着无法针对单个插件单独调整日志等级。作者想临时观察某个插件的 debug 细节时,目前只有三种方案,但三者皆有明显缺陷:
方案 1:开启全局 DEBUG level
直接把全局日志等级调到 DEBUG。
方案 2:插件自己写 debug 开关,用 INFO 级别打印
在插件里自己实现一个
debug配置开关,然后在需要的地方if self.debug: logger.info(...)。if判断代码,不够优雅;本质上是在应用层重新发明日志分级,使得 logger 自带的 level 设计被架空。方案 3:插件运行时动态
logger.setLevel(...)插件在运行时对共享 logger 调用
setLevel。提议 / 期望行为
为每个插件提供独立的 logger(例如以插件 ID / 模块路径作为 logger name 的 child logger),并允许插件独立设置自身 logger 的 level,互不干扰。
这样带来的收益:
logger.debug(...),无需反复写if debug:判断,代码更优雅,也让 logger 的 level 分级机制回归其本来的设计意图。plugin_tag(见_LoguruInterceptHandler/ 各 sink 的 format),天然适合按插件维度做过滤与分级。可选的实现方向(供参考,非硬性要求)
Star基类或插件加载流程中,为插件生成logging.getLogger(f"astrbot.plugin.{plugin_id}")之类的独立 logger,并让from astrbot.api import logger在插件上下文中拿到的是该插件专属 logger(或额外暴露self.logger)。LogManager.GetLogger(log_name=...)已经支持按名字获取并挂载 loguru intercept handler,可复用。propagate与 handler 的挂载关系,避免重复输出。PluginManager.load()时读取并应用到该插件的独立 logger。astrbotlogger;插件默认继承一个合理的默认等级(如 INFO),仅在作者显式开启时降到 DEBUG。相关代码位置
astrbot/__init__.py— 全局logger = logging.getLogger("astrbot")astrbot/api/__init__.py— 对外导出loggerastrbot/core/star/base.py—Star基类中的logger = logging.getLogger("astrbot")astrbot/core/log.py—LogManager.GetLogger()/configure_logger()/set_queue_handler()等astrbot/core/star/star_manager.py—PluginManager.load()插件加载流程(可在此处为插件注入独立 logger 并应用 level)docs/zh/dev/star/plugin.md— 现有「请使用from astrbot.api import logger」的开发者指引,需同步更新Use Case / 使用场景
插件作者在调试/分析单个插件行为时:
logger.debug(...),不必再为每条调试日志包裹if self.debug:判断,减少冗余代码。setLevel造成的插件间状态干涉与不稳定。典型操作流程(期望):在 WebUI 或插件配置中,把目标插件的日志等级设为 DEBUG → 只有该插件输出 debug 日志 → 排查完毕改回 INFO,全程不影响其他插件与核心。
Willing to Submit PR? / 是否愿意提交PR?
Code of Conduct