排障

English

先看 monitor 自己的 endpoint,再改 CPA 或 auth files。

如果还没启动 dashboard,可以先跑不改状态的检查:

codex-quota-monitor print-config
codex-quota-monitor doctor

doctor 会报告加载了哪个配置文件、监听端口是否可绑定、SQLite state 路径是否可写。如果本机 service 接线已经混乱,用 codex-quota-monitor init --mode user 重新生成一份干净 starter 配置。 Python 安装后,这些交互命令里的 codex-quota-monitor 可以替换成 cqm

1. Monitor 是否已经运行?

curl -fsS http://127.0.0.1:4515/healthz

预期输出:

{"ok":true}

如果失败,先看进程或 service manager:

/healthz 只表示 monitor 进程还活着;它不代表 CPA、management key、auth 文件、SQLite history 或 benchmark import 都正常。

2. 日志在哪里?

Monitor 遵循 Unix service 模型:

不要把 stderr 当稳定 API 抓取。机器可读状态应使用 /api/v1/status/api/v1/diagnostics/api/v1/alerts/api/v1/recommendations/metrics 或配置的 SQLite history database。codex-quota-benchmark 是例外:它会把实验 artifact 写到输出目录,请求保留临时 gateway 工作目录时也会包含 gateway stdout/stderr。

3. CPA 是否可达?

curl -fsS http://127.0.0.1:4515/api/v1/diagnostics | jq '.'

Diagnostics 标签页和 /api/v1/diagnostics 会拆开显示:

如果 Docker 容器访问不到宿主上的 CPA,把 CPA host 写成 host.docker.internal;Linux Docker 上还需要加:

--add-host=host.docker.internal:host-gateway

4. Management key 是否生效?

CPA management endpoints 通常要求 management key,包括 localhost 请求。前台运行时用 --management-key-file /path/to/management-key;service 和 Docker 部署时用 CODEX_QUOTA_MONITOR_MANAGEMENT_KEY_FILE。裸 CPA endpoint 的 key file 内容必须和 CPA remote-management.secret-key 明文值一致。

5. 为什么 quota 是 Unknown?

Unknown quota 通常表示 direct Codex quota sampling 不可用:

检查:

curl -fsS http://127.0.0.1:4515/api/v1/status | jq '.tabs.diagnostics'
curl -fsS http://127.0.0.1:4515/api/v1/alerts | jq '.'

如果 Diagnostics 明确说 direct quota response shape changed,只分享脱敏后的 diagnostics/alerts payload 和 package version。不要分享原始 auth files,也不要分享可能包含 credential material 的 provider 原始响应。

6. 为什么 Pool capacity 比 raw 5h 低?

默认会用 weekly remaining * 6.0 限制总 5h 容量,避免 weekly quota 接近耗尽时高估短窗口容量。

覆盖倍率:

codex-quota-monitor --weekly-to-five-hour-multiplier 8.0

关闭:

codex-quota-monitor --weekly-to-five-hour-multiplier off

Trends 和 Audit 需要可写 SQLite state database。

SQLite 写入错误会出现在 Diagnostics 标签页。

state 生命周期基础操作:

# 备份
cp /var/lib/codex-quota-monitor/history.sqlite3 /var/lib/codex-quota-monitor/history.sqlite3.bak

# 清空历史:先停服务,再删 DB
systemctl stop codex-quota-monitor
rm /var/lib/codex-quota-monitor/history.sqlite3
systemctl start codex-quota-monitor

rootless service 路径通常是 ~/.local/state/codex-quota-monitor/history.sqlite3;Docker 容器内路径通常是 /data/history.sqlite3,实际文件在绑定的 volume 里。下一次成功写入时 monitor 会重新创建 DB。

8. 为什么 dashboard 会周期性占用 CPU?

浏览器会轮询 /api/v1/status。缓存命中时响应很轻;但 refreshSeconds 到期后,monitor 会刷新 CPA management 数据、可选 direct quota samples、 dashboard snapshot,以及 SQLite-backed Trends/Stats 摘要。应按机器能力设置足够长的 refreshSeconds15s 很及时,但在 CPA pool 较大、散热受限的笔记本上可能偏吵。

SQLite history 由 historyRetentionDays 控制保留周期。删除后的页可能继续留在 database 文件里,表现为 SQLite freelist;这是文件体积压力,不等于活跃历史行数。 服务不会在 request path 自动跑 VACUUM,因为它可能阻塞 monitor。如果文件已经过大, 先备份、停服务,再由 operator 手动维护:

systemctl stop codex-quota-monitor
cp /var/lib/codex-quota-monitor/history.sqlite3 /var/lib/codex-quota-monitor/history.sqlite3.bak
sqlite3 /var/lib/codex-quota-monitor/history.sqlite3 'PRAGMA freelist_count; VACUUM;'
systemctl start codex-quota-monitor

如果不需要 Trends、ETA、Audit、Stats history 或原生历史备份,可以不传 --state-db 来关闭 SQLite history。这样本机工作量更低,但 dashboard 也会失去历史功能。

9. 什么信息可以分享?

不要分享 auth files、CPA admin keys、API keys、私有 gateway URL,或包含这些内容的完整日志。通常可以分享:

codex-quota-monitor redact 生成可分享副本:

codex-quota-monitor redact /tmp/cqm-diagnostics.json --output /tmp/cqm-diagnostics-redacted.json
codex-quota-monitor redact /path/to/history.sqlite3 --output /tmp/history-redacted.sqlite3

10. 可以绑定 0.0.0.0 吗?

只有在你同时控制 firewall,或把 dashboard 放在带鉴权的 reverse proxy 后面时才建议这么做。UI 和 /api/v1/status 设计上不会暴露 auth secret 内容,但会暴露账号 label、quota 状态、model activity 和 gateway health 这类运维元数据。

直接通过非 loopback 地址访问时,还要用 --allowed-host <域名或 IP> 放行浏览器访问用的 authority;非预期 HostOrigin 会被拒绝。 其它设备需要访问时,优先让应用继续监听 127.0.0.1,再通过 reverse proxy 暴露到外面。例如先用 basic auth 或外部 access layer 保护 proxy,再把 https://quota.example/ 转发到 http://127.0.0.1:4515/

当前支持的 reverse-proxy 拓扑是专用 hostname 的根路径。https://example/tools/quota/ 这类 path-prefix 部署不是 v1 支持范围,因为 UI 资源和浏览器 API 请求使用根相对路径。

11. 不用 Prometheus 怎么发现故障?

Prometheus 是可选项。最简单的本机检查:

curl -fsS http://127.0.0.1:4515/api/v1/alerts | jq '.ok'

systemd 示例已经包含 Restart=on-failure。system service 用 systemctl status codex-quota-monitor --no-pager,rootless user service 用 systemctl --user status codex-quota-monitor --no-pager