Skip to content

feat(trace): add history filters and improve trace workspace - #10765

Draft
mantoujun12 wants to merge 2 commits into
AstrBotDevs:masterfrom
mantoujun12:feat/remake-trace
Draft

mantoujun12 wants to merge 2 commits into
AstrBotDevs:masterfrom
mantoujun12:feat/remake-trace

Conversation

@mantoujun12

@mantoujun12 mantoujun12 commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Tip

本 PR 主要修改了“追踪”板块,改动较多,其中包括 Dashboard Core 等,如果不满意可关闭。

Refs #10748

内容由 AI 生成


追踪页是 AstrBot 运维人员和插件开发者排查“消息从接收、插件处理、Agent 调用到响应发送”全链路的主要入口。随着系统长时间运行,追踪历史会迅速累积到数千甚至数万条,而当前过滤器只提供“有错误”“有模型调用”“有插件调用”三个复选框,其余只能依赖关键词搜索。实际排障时,用户通常先按平台、消息类型或具体会话缩小范围,再按运行状态和时间窗口定位某一次异常,例如“最近一小时内某个 QQ 群的失败请求”或“某个私聊会话中带指令调用的追踪”。旧界面无法表达这些条件,只能反复翻页并人工比对;由于筛选条件有限,分页总数也失去了参考价值,定位一条异常链路往往需要多次搜索和翻页。

在多机器人实例共用同一追踪数据库的场景下,平台维度尤其关键:旧过滤器无法区分不同机器人实例的消息,用户只能查看所有实例混在一起的记录。消息类型(群聊/私聊)和会话 UMO 同样是最常用的定位条件,前者用于快速排除无关场景,后者用于从具体会话直接钻取到对应追踪。缺少这些条件时,搜索只能依赖消息文本或插件名命中,遇到内容相似但来源不同的记录很容易误判。

运行状态与时间范围是另一类高频需求。追踪可能处于运行中、已完成或错误状态,排障时通常只关心失败链路;历史数据按保留天数累积后,用户又往往只关心最近一小时、一天或一周。把这些条件下推到服务端执行,才能保证分页总数与当前筛选一致,也避免把整库数据拉到浏览器后再过滤。同时,实时事件流必须遵守同一套条件,否则用户已经筛选了平台或状态,新的不匹配记录仍会插入列表,造成前后数据不一致。

在窄屏和移动端,目前的宽表格只能横向滚动,列多、字号小,触控操作困难;打开详情后列表被挤占,关闭按钮和键盘焦点也不够明确。此次改动希望让追踪页在手机上同样可用:用卡片列表替代横向滚动,把详情改为全屏抽屉,并补齐触控尺寸、安全区与焦点管理,让桌面端和移动端共享同一套数据与筛选逻辑。

稳定性方面,目前实时连接在重试耗尽后仍停留在“连接中”文案,用户无法判断是网络断开还是服务异常,也没有手动恢复入口。新实现把重试次数收敛到 3 次、退避上限降到 4 秒,失败后显示明确的断线提示与重试按钮,同时保留当前列表和筛选条件,避免实时连接不可用影响历史排障。

实现上遵循最小改动原则:不新增数据库表或字段,继续基于既有追踪摘要 JSON 与 UMO 属性做 SQL 过滤,旧数据仍可读取;所有新查询参数都是可选的,省略时行为与之前一致,因此不构成破坏性变更。过滤器采用“同一分组内为或、不同分组与执行条件之间为与”的语义,既符合常见筛选习惯,也允许用户同时按平台、消息类型、状态、会话和时间窗口组合定位。最终效果是:定位异常链路所需的翻页与猜测明显减少,筛选结果、分页总数与实时列表保持一致,移动端也能完成完整的查看与排障流程。

Modifications / 改动点

本次改动由两个提交组成:feat: add trace history filters 提供后端查询能力与 OpenAPI 定义,feat(dashboard): improve trace workspace and filters 完成前端过滤器、响应式布局与断线恢复。

后端与 API

文件 改动
astrbot/core/utils/trace_store.py list_traces() 新增 commands、status、platforms、message_types、umo 参数并拼入 SQL 条件;校验 start_time <= end_time 与状态枚举;commands 读取摘要中的 has_commands;平台和消息类型通过 json_extract 取出 UMO 后按段解析,列表去重且最多取 20 个;全部条件使用参数化查询。
astrbot/dashboard/api/logs.py GET /api/v1/trace/history 新增同名查询参数:status 限定 running/completed/error,platforms、message_types 接收逗号分隔列表并去除空白,umo 去除首尾空格,start_time/end_time 要求非负;时间范围倒置时返回 422,其余条件透传给 LogService。
openspec/openapi-v1.yaml 补充新查询参数的枚举、长度限制、默认值与说明,明确 start_time 为包含端点、end_time 不得早于 start_time。
dashboard/src/api/generated/openapi-v1/types.gen.ts 根据 OpenAPI 重新生成 ListTracesData,补齐新参数的类型定义。
dashboard/src/api/v1.ts traceApi.history 的入参改用生成的 ListTracesData["query"],避免手写类型与 OpenAPI 再次漂移。

新增查询参数

参数 取值 / 约束 行为
commands 布尔,默认 false 仅返回摘要中 has_commands=1 的追踪,即包含指令处理器调用。
status running / completed / error running 匹配 state='running';completed 匹配非运行中且 has_errors=0;error 匹配 has_errors=1。
platforms 逗号分隔,最大 1024 字符,最多 20 个去重值 按 UMO 第一段(平台实例 ID)匹配,组内为“或”。
message_types 逗号分隔,最大 512 字符,最多 20 个去重值 按 UMO 第二段(消息类型)匹配,组内为“或”。
umo 精确匹配,最大 1024 字符 按完整会话 UMO 过滤。
start_time / end_time Unix 秒,非负整数;start_time <= end_time 按追踪开始时间过滤,包含端点;倒置时返回 422。

前端

文件 / 区域 改动
dashboard/src/components/shared/TraceDisplayer.vue:过滤器面板 由单一复选框列表改为分组侧栏:平台多选(数据来自 conversationApi.filterOptions() 的机器人列表,显示平台图标)、群聊/私聊多选按钮、运行状态下拉、会话 UMO 选择器(复用现有 UmoSelector)、执行条件(有错误/有模型调用/有插件调用/有指令调用)以及时间范围(全部/1 小时/24 小时/7 天/30 天)。过滤器按钮显示活动条件数量,重置 一次清空全部分组,提示文案说明“组内为或、组间为与”。
同文件:查询与实时流 新条件全部传给 /trace/history;搜索或任意筛选变化后 250ms 防抖、回到第 1 页并重新请求。hasActiveServerFilters 同时覆盖搜索与全部筛选,实时事件只在第一页且无活动筛选时插入新追踪;已有追踪的增量更新仍会合并,并统一经过客户端条件过滤,避免筛选后列表混入不匹配记录。
同文件:响应式与移动端 视口宽度 ≤640px 时用卡片列表替代 datatable,卡片展示状态、平台、时间、消息、分类标签、UMO、发送人、时长与 Spans,并提供条数范围、每页条数和分页器;工具栏改为两行网格,工具栏按钮与执行条件复选项的触控高度提升到 44px,列表和详情底部适配 env(safe-area-inset-bottom)。
同文件:详情与过滤器浮层 通过 ResizeObserver 监听工作区与列表宽度:详情在可用宽度不足 1340px 时改为浮层,过滤器在不足 900px 时改为浮层;浮层带遮罩、role="dialog"/aria-modal、Tab 焦点循环、Escape 关闭与关闭后的焦点恢复,宽屏桌面仍保持左右分栏。
同文件:连接状态与错误提示 SSE 最大重试从 10 次降为 3 次,退避上限从 30 秒降为 4 秒;重试耗尽后工具栏显示“连接已断开”,页面顶部显示可重试的警告条,retryConnection() 重置计数并重新连接,连接恢复后清除失败状态。历史请求失败的错误条新增“刷新”按钮并复用加载状态。
同文件:视觉与表格 表格列宽收紧(状态 96、平台 64、时间 152、时长 96、类型 180、发送人 110、Spans 64),状态 chip 改为轻量状态徽章,时间、时长与 Spans 使用等宽数字;统一圆角与控件 CSS 变量,补充容器查询,并扩展减少动态效果偏好下的处理。
dashboard/src/views/TracePage.vue 页面底部 padding 改为 max(8px, env(safe-area-inset-bottom)),窄屏为 max(6px, env(safe-area-inset-bottom)),适配带手势条的移动设备。
dashboard/src/i18n/locales/{zh-CN,en-US,ja-JP,ru-RU}/features/trace.json 新增 filters.commands/status/anyStatus/messageTypes/umo/execution/timeRange/anyTime/lastHour/lastDay/lastWeek/lastMonth/noPlatforms、history.connectionLost、controls.connectionLost,并更新 filters.hint 的组合规则说明;四种语言的 key 保持一致。

过滤器组合语义

分组 组内规则 与其他分组
平台 多选,命中任意一个即可 与其他分组同时满足
消息类型 群聊/私聊可多选,命中任意一个即可 与其他分组同时满足
运行状态 单选 与其他分组同时满足
会话 UMO 精确匹配 与其他分组同时满足
执行内容 错误、模型、插件、指令可多选,需全部满足 与其他分组同时满足
时间范围 单选预设窗口,按请求时的当前时间计算起点 与其他分组同时满足
关键词搜索 服务端 search LIKE 匹配消息、会话、插件等信息 与上述条件同时满足

测试与文档

文件 改动
tests/unit/test_trace_store.py 为样本追踪补充 handler_category 与 has_commands 等字段,新增对 commands、status、platforms、message_types、umo 过滤结果的断言。
tests/test_fastapi_v1_dashboard.py 扩展 /api/v1/trace/history 用例,同时传入全部新增参数并断言 200、total 正确;新增 start_time=2&end_time=1 返回 422 的用例。
docs/zh/use/webui.md、docs/en/use/webui.md 本分支未修改。现有追踪章节仍描述旧的三个过滤器、80px 平台列和“窄屏横向滚动”;合并前需要同步新过滤器分组、移动端卡片布局、详情浮层与断线重连说明。

兼容性说明

  • 所有新增查询参数均为可选,未传入时查询行为与改动前一致,不构成破坏性变更。

  • 未新增数据库表或字段,继续读取既有追踪摘要与 UMO 属性;旧追踪若摘要缺少 has_commands 或 astrbot.umo,按指令、平台或消息类型过滤时不会被命中,但列表展示与详情查看仍沿用既有逻辑,不受影响。

  • 新增前端文案已同步四种语言,未引入新的运行时或构建依赖。

  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

运行截图

更改后的界面如下:

image

过滤器菜单:

image image

选择会话来源(单选):

image

过滤展示结果:

image

详细信息:

image image

移动端展示:

image image image

连接断开:

image image

重新连接:

image

验证步骤

  1. 运行追踪存储单元测试,覆盖新增过滤条件、状态枚举与查询结果数量。
  2. 运行 Dashboard API 路由测试,携带全部新增查询参数请求 /api/v1/trace/history,并验证非法时间范围返回 422。
  3. 执行前端 TypeScript 类型检查与四种语言的 i18n key 一致性检查。
  4. 对 Python 代码执行 ruff check。

测试结果

本次以自动化测试日志与静态检查结果作为验证证据。

检查项 命令 结果
追踪存储单元测试 .venv/Scripts/python.exe -m pytest tests/unit/test_trace_store.py -q 32 passed in 4.37s
追踪 API 路由测试 .venv/Scripts/python.exe -m pytest tests/test_fastapi_v1_dashboard.py -q -k trace 5 passed, 171 deselected, 1 warning in 6.31s
前端类型检查 cd dashboard && pnpm exec vue-tsc --noEmit 通过(无错误输出)
i18n key 检查 cd dashboard && pnpm i18n:check PASS;zh-CN、en-US、ru-RU、ja-JP 均为 4376 个 leaf key,key 集完全一致
Python lint .venv/Scripts/ruff.exe check . All checks passed!

单元测试新增断言覆盖:

  • commands=True 仅命中带指令处理器的追踪,结果为 1 条。
  • status=running/completed/error 分别命中 1/2/1 条,覆盖运行中、已完成和无错误结束、错误结束三种状态。
  • platforms=["qq"] 命中 4 条,platforms=["telegram"] 命中 0 条。
  • message_types=["Group"] 命中 4 条,message_types=["FriendMessage"] 命中 0 条。
  • umo="qq:Group:123" 精确命中 4 条。

API 测试同时传入 status=completed、platforms=qq,telegram、message_types=FriendMessage、umo=qq:FriendMessage:session:user、commands=true、start_time/end_time,返回 200 且 total=1;新增的倒置时间范围请求返回 422。

说明:ruff format --check 对 tests/test_fastapi_v1_dashboard.py、tests/unit/test_trace_store.py 提示的格式差异在 master 上同样存在,属于既有问题;本分支新增的测试代码未引入新的格式差异,ruff check 全部通过。


Checklist / 检查清单

  • 😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
    / 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。

  • 👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
    / 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。

  • 📚 I checked the affected WebUI instructions and screenshots in docs/zh and docs/en against the changed navigation, page structure, and labels, and updated them in this PR (or explained why no documentation update is needed). For renamed, moved, or merged entry points, I included an old entry → new entry mapping in the documentation and changelog.
    / 我已对照变化后的 WebUI 入口、页面结构和术语,核对并在本 PR 中更新 docs/zh 和 docs/en 的相关操作说明与截图(或说明无需更新文档的原因)。入口改名、移动或合并时,已在文档和 changelog 中补充 旧入口 → 新入口 对照。

  • 🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
    / 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到 requirements.txt 和 pyproject.toml 文件相应位置。

  • 😮 My changes do not introduce malicious code.
    / 我的更改没有引入恶意代码。

Summary by Sourcery

Improve trace history investigation with richer filtering, responsive workspace behavior, and reliable live-connection recovery.

New Features:

  • Add server-side trace history filters for command handling, status, platform, message type, session UMO, and time range.
  • Expand the trace workspace with grouped filters, responsive mobile cards, adaptive detail and filter panels, and improved accessibility interactions.

Bug Fixes:

  • Keep filtered history, pagination, and live trace updates consistent when search or server-side filters are active.
  • Provide clear connection-loss feedback and manual SSE recovery after retry exhaustion.

Enhancements:

  • Improve trace workspace presentation with compact status badges, responsive layouts, touch-friendly controls, safe-area support, and focus management.
  • Align the trace API client and OpenAPI definitions with the expanded history query parameters.
  • Add localized labels for the new filters and connection states across supported languages.

Tests:

  • Extend trace storage and Dashboard API tests to cover the new filters and invalid time ranges.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant