Proxy Monitor:请求日志、筛选、详情还原与导出
你已经把本地反代跑起来了,但一旦出现 401/429/500、流式中断、或者“怎么突然换了账号/换了模型”,排障就很容易变成盲猜。
这节课只讲一件事:用 Proxy Monitor 把每次调用还原成“可复盘的证据”,让你知道请求从哪来、打到哪个端点、用了哪个账号、模型有没有被映射、以及 Token 消耗大概是多少。
学完你能做什么
- 在
/monitor页面打开/暂停录制,并理解它会不会影响 Token Stats - 用搜索框、快速筛选、账号筛选,快速定位一条请求记录
- 在详情弹窗里查看并复制 Request/Response 报文,复盘失败原因
- 知道 Proxy Monitor 的数据落盘位置(
proxy_logs.db)与清空行为 - 了解当前版本“导出日志”的真实能力边界(GUI vs 后端命令)
你现在的困境
- 你只看到“调用失败/超时”,但不知道到底失败在上游、代理、还是客户端配置
- 你怀疑触发了模型映射或账号轮换,但没有证据链
- 你想复盘一条请求的完整 payload(尤其是流式/Thinking),但日志里看不到
什么时候用这一招
- 你要排查:401 鉴权失败、429 限流、5xx 上游错误、流式中断
- 你想确认:某次请求到底用了哪个账号(
X-Account-Email) - 你在做模型路由策略,想验证“客户端模型名 -> 实际映射模型名”
🎒 开始前的准备
前置条件
Proxy Monitor 记录的是“反代服务收到的请求”。所以你至少要先跑通:
- 反代服务已启动,并能访问
/healthz - 你知道当前反代的 Base URL 和端口
如果还没跑通,先看 启动本地反代并接入第一个客户端。
什么是 Proxy Monitor?
Proxy Monitor 是 Antigravity Tools 内置的“请求日志看板”。每次请求进到本地反代后,它会记录时间、路径、状态码、耗时、模型与协议,并尽量从响应里提取 Token 用量;你还能点开单条记录查看请求与响应报文,用它来复盘失败原因和路由/账号选择结果。
数据落盘位置
Proxy Monitor 的日志会写入数据目录下的 SQLite:proxy_logs.db。数据目录怎么找、怎么备份,建议先复习 首次启动必懂:数据目录、日志、托盘与自动启动。
核心思路:你需要盯住的 6 个字段
Proxy Monitor 的一条记录(后端结构体 ProxyRequestLog)里,最实用的是下面这些字段:
| 字段 | 你用它回答什么问题 |
|---|---|
status | 这次请求是成功还是失败(200-399 vs 其他) |
url / method | 你到底打到了哪个端点(例如 /v1/messages、/v1/chat/completions) |
protocol | 这是 OpenAI / Claude(Anthropic) / Gemini 哪套协议 |
account_email | 这次请求最终用了哪个账号(来自 X-Account-Email 响应头) |
model / mapped_model | 客户端请求的模型名有没有被“路由/映射”成另一个模型 |
input_tokens / output_tokens | 这次请求的 Token 用量(能提取到才有) |
先用“摘要”,需要时再点“详情”
列表页只展示摘要(不带 request/response body),点开一条记录才会去后端加载完整详情,避免列表一次性拉太多大字段。
跟我做:用一次调用跑通“监控闭环”
第 1 步:先制造一条“你确定会出现”的请求
为什么 Proxy Monitor 只记录反代服务收到的请求。先用一个最简单的请求把“有没有记录”这件事验证掉,后面才谈筛选和详情。
## 1) 探活(一定存在的端点)
curl "http://127.0.0.1:PORT/healthz"
## 2) 再请求一次 models(如果你开启了鉴权,记得加 header)
curl "http://127.0.0.1:PORT/v1/models"## 1) 探活(一定存在的端点)
curl "http://127.0.0.1:PORT/healthz"
## 2) 再请求一次 models(如果你开启了鉴权,记得加 header)
curl "http://127.0.0.1:PORT/v1/models"你应该看到:终端返回 {"status":"ok"}(或类似 JSON),以及 /v1/models 的响应(成功或 401 都行)。
第 2 步:打开 Monitor 页面并确认“录制状态”
为什么 Proxy Monitor 有“录制/暂停”开关。你需要先确认当前状态,否则你可能一直在请求,但列表永远是空的。
在 Antigravity Tools 里打开侧边栏的 API 监控看板(路由为 /monitor)。
页面顶部会有一个带圆点的按钮:
┌───────────────────────────────────────────┐
│ ● 正在录制 [搜索框] [刷新] [清除] │
└───────────────────────────────────────────┘如果你看到的是“已暂停”,点一下切换到“正在录制”。
你应该看到:按钮状态变成“正在录制”;列表里开始出现刚才的请求记录。
第 3 步:用“搜索 + 快速筛选”定位一条记录
为什么 真实排障时,你通常只记得一个片段:路径里有 messages,或者状态码是 401,或者模型名里有 gemini。搜索框就是为这种记忆设计的。
Proxy Monitor 的搜索,会把你的输入当成一个“模糊关键词”,在后端用 SQL LIKE 匹配这些字段:
urlmethodmodelstatusaccount_email
你可以试几个典型关键词:
healthzmodels401(如果你刚好制造了一个 401)
也可以点“快速过滤”按钮:仅错误 / Chat / Gemini / Claude / 绘图。
你应该看到:列表只剩下你期望的那一类请求。
第 4 步:点开详情,还原“请求报文 + 响应报文”
为什么 列表只够回答“发生了什么”。要回答“为什么”,你通常需要看完整请求/响应 payload。
点开任意一条记录,会弹出详情窗口。你可以重点检查:
协议(OpenAI/Claude/Gemini)使用模型与映射模型使用账号Token 消耗 (输入/输出)
然后用按钮复制:
请求报文 (Request)响应报文 (Response)
你应该看到:详情里有两块 JSON(或文本)预览;复制后你可以粘贴到工单/笔记里做复盘。
第 5 步:需要“从零开始复现”时,清空日志
为什么 排障时最怕“旧数据干扰判断”。清空后复现一次,成功/失败会非常清楚。
点击顶部的“清除”按钮,会弹出确认框。
这是不可逆操作
清除会删除 proxy_logs.db 里的所有记录。
你应该看到:确认后列表清空,统计数字回到 0。
检查点 ✅
- [ ] 你能在
/monitor看到自己刚发出的/healthz或/v1/models记录 - [ ] 你能用搜索框把某条记录筛出来(例如输入
healthz) - [ ] 你能点开一条记录看到请求/响应报文,并复制出来
- [ ] 你知道清空日志会直接删除所有历史记录
踩坑提醒
| 场景 | 你可能会怎么理解(❌) | 实际表现(✓) |
|---|---|---|
| "已暂停"= 完全没有监控开销 | 以为暂停后请求就不会被解析 | 暂停只影响"是否写入 Proxy Monitor 日志"。但请求/响应解析(包括流式数据的 SSE 解析)仍会发生,只是解析后的数据不被保存。Token Stats 也仍会记录(无论监控是否启用)。 |
| 二进制/大包体日志为空 | 以为是监控坏了 | 二进制请求/响应会显示为 [Binary Request Data] / [Binary Response Data]。响应体超过 100MB 会标记为 [Response too large (>100MB)];请求体超过限制则不记录。 |
| 想用 Monitor 找到“谁发起了请求” | 以为能追溯到客户端进程 | Monitor 记录的是 HTTP 层信息(方法/路径/模型/账号),不包含“调用方进程名”。你需要结合客户端自身日志或系统网络抓包定位来源。 |
| 启用监控时 Token Stats 数据异常 | 以为是统计错误 | 监控启用时,Token Stats 可能被记录两次(一次在监控函数开头,一次在异步写入数据库时)。这是当前版本的源码行为。 |
导出与长期留存:先说清楚能力边界
1) GUI 里目前能做什么
在当前版本的 Monitor UI(ProxyMonitor.tsx)里,你可以:
- 搜索/筛选/分页浏览
- 点开详情查看与复制 payload
- 清空全部日志
但 没有发现“导出按钮”(源码里未看到相关 UI)。
2) 后端已经有什么导出能力(适合二次开发)
后端 Tauri 命令提供了两种导出方式:
export_proxy_logs(file_path):把数据库里“全部日志”导出为 JSON 文件export_proxy_logs_json(file_path, json_data):把你传入的 JSON 数组美化后写入文件(要求输入必须是数组格式)
如果你要二次开发 GUI,或者写一个自己的调用脚本,可以直接复用这些命令。
3) 最朴素的“导出”:直接备份 proxy_logs.db
因为 Proxy Monitor 本质是 SQLite,你也可以把 proxy_logs.db 当成“排障证据包”一起备份(例如连同 token_stats.db)。数据目录位置见 首次启动必懂。
推荐阅读
- 想弄清模型映射:模型路由:自定义映射、通配符优先级与预设策略
- 想排查鉴权问题:401/鉴权失败:auth_mode、Header 兼容与客户端配置清单
- 想把 Monitor 与成本统计结合:下一节会讲 Token Stats(
token_stats.db)
本课小结
- Proxy Monitor 的价值是“可复盘”:记录状态码/路径/协议/账号/模型映射/Token 用量,并提供请求详情
- 搜索与快速筛选是排障入口:先缩小范围,再点详情看 payload
- 清空日志是不可逆操作;导出目前更偏向“二次开发能力”和“备份数据库文件”
下一课预告
下一课我们学习 Token Stats:成本视角的统计口径与图表解读,把“感觉贵”变成可量化的优化。
附录:源码参考
点击展开查看源码位置
更新时间:2026-01-23
| 功能 | 文件路径 | 行号 |
|---|---|---|
| Monitor 页面入口(挂载 ProxyMonitor) | src/pages/Monitor.tsx | 1-12 |
| Monitor UI:表格/筛选/详情弹窗 | src/components/proxy/ProxyMonitor.tsx | 13-713 |
| UI:读取配置并同步 enable_logging | src/components/proxy/ProxyMonitor.tsx | 174-243 |
| UI:切换录制(写入 config + set_proxy_monitor_enabled) | src/components/proxy/ProxyMonitor.tsx | 254-267 |
| UI:实时事件监听(proxy://request)与去重 | src/components/proxy/ProxyMonitor.tsx | 273-355 |
| UI:清空日志(clear_proxy_logs) | src/components/proxy/ProxyMonitor.tsx | 389-403 |
| UI:加载单条详情(get_proxy_log_detail) | src/components/proxy/ProxyMonitor.tsx | 505-519 |
| 监控中间件:抓取请求/响应、解析 token、写入 monitor | src-tauri/src/proxy/middleware/monitor.rs | 13-337 |
| ProxyMonitor:enabled 开关、写 DB、发事件 | src-tauri/src/proxy/monitor.rs | 33-194 |
| 服务端挂载监控中间件(layer) | src-tauri/src/proxy/server.rs | 183-194 |
| Tauri 命令:get/count/filter/detail/clear/export | src-tauri/src/commands/proxy.rs | 180-314 |
| SQLite:proxy_logs.db 路径、表结构与筛选 SQL | src-tauri/src/modules/proxy_db.rs | 1-416 |
| 监控设计说明(可能与实现有差异,以源码为准) | docs/proxy-monitor-technical.md | 1-53 |
关键常量:
MAX_REQUEST_LOG_SIZE = 100 * 1024 * 1024:监控中间件最大可读取的请求体(超过会读失败)MAX_RESPONSE_LOG_SIZE = 100 * 1024 * 1024:监控中间件最大可读取的响应体(用于图片等大响应)
关键函数/命令:
monitor_middleware(...):在 HTTP 层采集请求与响应,并调用monitor.log_request(...)ProxyMonitor::log_request(...):写入内存 + SQLite,并通过proxy://request事件推送摘要get_proxy_logs_count_filtered(filter, errors_only)/get_proxy_logs_filtered(...):列表页筛选与分页get_proxy_log_detail(log_id):加载单条日志的完整 request/response bodyexport_proxy_logs(file_path):导出全量日志到 JSON 文件(当前 UI 未暴露按钮)