Skip to content

feat: classify stream-failed audits as errors and add picklist filters - #860

Merged
chenyme merged 3 commits into
chenyme:mainfrom
MMortise:feature/opt-request-audit
Aug 6, 2026
Merged

feat: classify stream-failed audits as errors and add picklist filters#860
chenyme merged 3 commits into
chenyme:mainfrom
MMortise:feature/opt-request-audit

Conversation

@MMortise

@MMortise MMortise commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes a misclassification in request audit: when a request returned a 2xx response header but the stream later failed (e.g. Build response-header timeout / first-byte timeout / upstream_stream_interrupted), the audit record kept status_code = 200. As a result these failed requests were counted as successful in audit summaries, the success filter, and the dashboard, and could not be filtered out.

Backend

  • auditStatusForRecord: when 2xx headers were sent but error_code is non-empty, the stored status code becomes 0 (outside any HTTP band). Applied to both the responses path (service.go) and image/video (image.go).
  • Audit summary / dashboard: a request is now successful only when status_code is 2xx and error_code is empty; everything else counts as failed.
  • New status=other filter (status_code < 100 OR status_code >= 600) so these records can be queried directly.
  • Startup migration ensureAuditStatusCodeConstraints: relaxes the chk_request_audits_status_code CHECK to allow 0, then backfills existing 2xx+error_code records to 0. Order matters (constraint first, then backfill). The "allows zero" check is dialect-aware (SQLite BETWEEN 0 AND 599 vs PostgreSQL (status_code >= 0) AND (status_code <= 599)), idempotent on both.

Frontend (request audits page)

  • Status column: when statusCode === 0 with an error code, show an amber "error" label instead of the misleading 200; the tooltip keeps the concrete error code.
  • Status filter gains an "other error" option.
  • Key / account filters upgraded from free-text inputs to searchable, scrollable picklists reusing the existing DataTableFilters group-search pattern:
    • Keys: lists all keys, input matches and click-to-select.
    • Accounts: lists up to the first 50 matches (search re-queries the first 50).
    • The list is capped at ~5 rows and scrolls internally.
    • Accounts query no longer pins provider so accounts from any provider (grok_build / grok_web / grok_console) can be filtered.

Verification

  • Backend: 56 test packages pass; added tests for auditStatusForRecord, the other filter + summary semantics, the backfill migration idempotency, and the dialect-aware constraint check.
  • Frontend: tsc, eslint, vite build all pass.
  • Verified against a copy of a production database: 79 existing 2xx+error_code records are backfilled to 0 and become visible under the "other error" filter.

Screenshot (local acceptance run)

Status column shows the amber error label and the filter picklists for keys/accounts.

- Record status code 0 (outside any HTTP band) when 2xx headers were sent
  but the stream later failed (first-byte timeout / stream interruption),
  so audit summaries, success filters and the dashboard no longer count
  these requests as successful.
- Add an "other" status filter matching non-standard status codes; the
  startup migration backfills existing 2xx+error_code records to 0 and
  relaxes the status_code CHECK (idempotent on SQLite and PostgreSQL).
- Upgrade the key/account filters on the request audit page to searchable,
  scrollable picklists (accounts limited to the first 50 matches), reusing
  the existing DataTableFilters group-search pattern.
@MMortise

MMortise commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author
image image

@chenyme

chenyme commented Aug 6, 2026

Copy link
Copy Markdown
Owner

补充优化

根据代码审查进一步调整审计结果模型与大数据量筛选实现:

  • 保留请求真实 HTTP 状态码,不再将“2xx 响应头后流式失败”改写为 status_code = 0
  • 使用 status_code + error_code 判断最终结果:
    • 2xx 且无 error_code 计为成功
    • 2xx 后流式中断、首字节超时等计为失败
  • “其它错误”筛选可直接查询上述流式失败记录
  • 前端以 200 · 错误 展示,兼顾真实 HTTP 状态与最终执行结果
  • 移除状态码 CHECK 约束重建和历史全表回填,避免大型审计表在启动时产生锁表、磁盘放大或长时间迁移
  • 失败数量由“请求总数-成功数量”计算,减少重复聚合表达式

大账号池优化

  • 账号与密钥筛选采用服务端搜索,前端最多保留前 50 条结果,避免无限分页造成 DOM 和内存持续增长
  • 用户输入数字 ID 时自动执行内部精确查询,SQLite/PostgreSQL 均可使用主键索引
  • 保留普通数字名称的原有模糊搜索语义
  • 超出 50 条时提示继续输入关键词缩小范围
  • 账号选项包含名称、ID 和 Provider,密钥选项包含名称、ID 和前缀,避免重名歧义

界面优化

  • 筛选菜单调整为紧凑的系统级菜单样式
  • 使用无边框搜索、轻量分隔和克制的选中态
  • 名称保持单行省略,ID 与 Provider 作为次级信息
  • 移除重复分组标题和胶囊式 Provider 标签
  • 列表保持固定高度并支持内部滚动

验证

  • go test ./...
  • go vet ./...
  • pnpm lint
  • pnpm build
  • git diff --check
  • 5 万条审计记录聚合基准约 40ms,未引入启动迁移或无界内存增长

@chenyme
chenyme merged commit 558c79a into chenyme:main Aug 6, 2026
9 checks passed
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.

2 participants