6.5 KiB
用量与统计
模块定位
用量与统计负责记录一次请求发生了什么,并将请求结果、实际使用的上游、Token、性能和成本整理成可查询的请求明细与汇总数据。
该模块以 CLIProxyAPI 的请求终态和最终 Usage 为事实来源,不解析客户端响应内容,也不依赖管理页面当前加载的记录。
当前能力
| 能力 | 当前实现 |
|---|---|
| 请求终态 | 记录成功、失败、拒绝和取消 |
| Token 用量 | 记录输入、输出、推理、缓存读取和缓存写入 |
| 实际执行 | 记录模型、上游 Auth ID、端点和执行信息 |
| 性能指标 | 记录首字延迟、总延迟、生成速度和缓存率 |
| 成本事实 | 保存计算结果、价格档位和 Fast 倍率 |
| 请求归并 | 将请求终态与 Usage 整理为一条可读明细 |
| 查询 | 支持服务端分页、数字页码和多条件筛选 |
| 汇总 | 提供今日指标、各用户用量和近 7 日 Token |
两类事实
CLIProxyAPI 会通过两个独立回调提供请求信息:
| 事实 | 来源 | 主要内容 |
|---|---|---|
| 请求终态 | request.complete |
Request ID、开始与结束时间、成功/失败/拒绝/取消、状态码和错误 |
| 最终用量 | usage.handle |
实际上游、模型、Token、延迟和 Usage 结果 |
这两个回调可能乱序、重复或只到达其中一个,因此数据库分别保存原始事实,再建立请求明细查询投影。管理台看到的一行是查询结果,不会为了合并展示而修改原始事实或计费账目。
请求关联与独立用量
- Request ID 用于关联一次下游请求的生命周期。
- 当前目标 CPA 的 Usage 契约不提供 Request ID 或 Execution ID;Request ID 和 Trace ID 来自独立的请求终态。
- 每条可区分的 Usage 事实分别保存,不会为了得到一条整齐记录而把多个用量相加。
- 当前契约无法保证把每次上游重试稳定标记为某个 Execution ID,因此管理台不声明这种保证。
- 没有 Usage 的拒绝、取消或失败请求仍然显示请求终态。
- 只有 Usage、暂时没有终态的记录也可以单独显示,终态到达后投影会自动更新。
系统仅在模型和请求时间足够接近且匹配关系唯一时,将 Usage 与终态合并;存在并发歧义时宁可保留为两条,也不会错误关联到其他用户的请求。
请求结果
| 结果 | 含义 |
|---|---|
succeeded |
请求正常完成 |
failed |
执行失败或上游返回错误 |
rejected |
请求在认证、权限、额度、并发、价格或路由阶段被拒绝 |
canceled |
客户端断开或请求被取消 |
如果终态尚未到达,界面根据现有 Usage 事实展示当前可确定的结果;终态到达后以请求生命周期结果补全。
明细字段
请求明细当前可以展示:
- 请求时间,以及请求终态能够提供的 Request ID 和 Trace ID;
- 用户 Key 名称;
- 客户端请求模型和实际计费模型;
- 推理强度和服务档位;
- 请求结果、HTTP 状态码和错误;
- 请求类型与端点;
- 实际上游 Auth ID、Auth Index 和认证类型;
- 首字延迟、生成速度;
- 输入、输出、推理、缓存读取、缓存写入和总 Token;
- 缓存率、成本、价格档位和 Fast 计价结果。
并非每种端点都能提供所有字段。管理接口为兼容历史数据保留 Execution ID、速度模式和客户端 IP 等可选字段,但当前目标 CPA 不提供这些值;字段无法可靠获得时保留为空,不使用猜测值。一次性 JSON/Compact 响应不展示不可比较的首字延迟和生成速度。
服务端分页
请求明细由 SQLite 分页查询,而不是先把全部历史加载到浏览器。
- 默认每页 100 条,单页上限也是 100 条。
- 默认按照请求时间和稳定记录 ID 倒序排列。
- 数字页码用于直接跳转。
- 连续上一页、下一页使用游标保持翻页稳定。
- 游标与当前全部筛选条件绑定,修改筛选后不能继续使用旧游标。
- 新请求写入时,已经打开的连续翻页不会因为列表头部变化而重复或遗漏原有记录。
当前支持的筛选条件为:
| 条件 | 说明 |
|---|---|
| 开始、结束时间 | 使用 RFC3339 时间范围 |
| 用户 Key | 按稳定 Key ID 查询 |
| 模型 | 按模型名称查询 |
| 结果 | 成功、失败、拒绝或取消 |
| 上游 | 按实际 Auth ID 查询 |
| 端点 | 例如 Responses、Compact 或 Chat |
| Request ID | 使用完整 Request ID 精确定位 |
汇总统计
汇总由数据库独立计算,不受请求明细当前页或筛选条件影响。
| 汇总 | 当前内容 |
|---|---|
| 今日总览 | 请求数、输入 Token、输出 Token、总 Token 和成本 |
| 用户汇总 | 各用户今日请求、Token、成本和最近使用时间 |
| 近 7 日趋势 | 每个自然日的总 Token |
| 单用户统计 | 累计、今日指标和最近 50 条请求 |
“今日”按照 Asia/Shanghai 自然日计算。成本只汇总已经得到有效价格计算结果的 Usage。
持久化与规模
原始请求、Usage 和轻量查询投影均保存在 SQLite。升级旧数据库时,插件会自动创建投影、回填历史数据并建立分页和筛选索引。
查询投影只保存明细检索所需的关联和排序字段,Token、成本、生命周期和账目仍以原始事实表为准。当前分页与组合筛选已按百万级记录场景设计,不要求将全部记录读入内存。
SQLite 使用单 writer 和独立读连接池:计费与事实写入保持顺序一致,管理台分页和汇总不会占用 writer。今日用户汇总只扫描当天范围,最近使用时间通过 Key 时间索引定位,不随全部历史记录线性分组扫描。
数据一致性
- Usage 插入使用内容事件标识,完全相同的重复回调不会重复记录或扣费。
- 请求终态按 Request ID 幂等更新。
- 回调乱序时,后到达的事实会重新同步查询投影。
- 失败、取消和孤立 Usage 不会为了界面整齐而被删除。
- 历史迁移只建立查询关系,不改写既有用量和计费事实。
模块边界
本模块负责:
- 请求终态与 Usage 持久化;
- 请求明细归并、分页和筛选;
- Token、成本、上游和性能展示;
- 今日、用户和每日趋势汇总。
本模块不负责:
- 用户认证、模型权限和上游选择;
- 模型价格的维护规则;
- 额度准入和余额扣减;
- 修改或重放历史请求;
- 替代上游服务提供商的正式账单。