监控与统计
数据导出功能
数据导出功能
Claude Code Hub 提供多种数据导出功能,帮助你备份数据、分析使用情况和排查问题。 无论你是需要分析团队的使用模式、备份关键数据,还是深入调试特定的 API 请求,系统都提供了相应的导出工具。
导出类型概览
系统支持四种导出类型:
- 使用日志 CSV:分析用量和成本,支持丰富的筛选条件
- 数据库备份:完整 PostgreSQL 数据库导出,用于灾难恢复
- Session 请求 JSON:调试单个请求详情,包含完整请求/响应数据
- 探测日志文本:监控端点健康状态,追踪可用性历史
导出类型对比
在开始使用导出功能之前,了解每种导出类型的特点和适用场景很重要:
| 导出类型 | 格式 | 适用场景 | 最大记录数 | 访问权限 |
|---|---|---|---|---|
| 使用日志 | CSV | 用量分析、审计、成本核算 | 10,000 | 管理员:全部,用户:仅自己 |
| 数据库备份 | PostgreSQL .dump | 灾难恢复、数据迁移、全量备份 | 无限制 | 仅管理员 |
| Session 请求 | JSON | 调试、问题排查、请求分析 | 单次请求 | 仅管理员 |
| 探测日志 | 纯文本 | 端点监控、健康趋势分析 | 全部(过滤后) | 仅管理员 |
每种导出类型都有其特定的用途。CSV 导出适合在电子表格软件中分析数据; 数据库备份是完整的 PostgreSQL 转储,需要使用专门的工具恢复; Session 请求导出提供了单个请求的完整上下文;探测日志则帮助你了解供应商端点的历史可用性。
使用日志 CSV 导出
功能概述
使用日志导出功能允许你将请求记录导出为 CSV 格式,便于在 Excel、 Google Sheets 或其他数据分析工具中进行深度分析。这是了解系统使用情况、 优化成本和排查问题的重要工具。
导出的 CSV 文件包含了每个请求的完整元数据,包括时间、用户、供应商、 模型、Token 使用量、成本等关键信息。你可以使用这些数据进行各种分析, 比如按用户统计使用量、分析不同模型的调用频率、追踪成本趋势等。
访问路径
要使用使用日志导出功能:
- 登录管理后台
- 进入 Dashboard > 使用日志
- 在筛选器区域配置你想要的筛选条件
- 点击 导出 CSV 按钮
- 等待文件生成并自动下载
导出过程是同步的,文件会直接下载到你的浏览器默认下载目录。
导出流程
当你点击导出按钮时,系统会执行以下步骤:
- 身份验证:验证你的登录状态和会话有效性
- 权限检查:如果你是管理员,可以导出全部数据;如果你是普通用户, 只能导出自己的数据
- 筛选应用:将你当前设置的所有筛选条件应用到查询
- 数据查询:从数据库获取匹配的记录,最多 10,000 条
- CSV 生成:将数据转换为安全的 CSV 格式,包含 UTF-8 BOM 头
- 文件下载:浏览器创建 Blob 对象并触发文件下载
整个过程通常在几秒内完成,具体时间取决于数据量和网络速度。
CSV 文件结构
导出的 CSV 文件包含以下列:
| 列名 | 说明 | 示例 |
|---|---|---|
| 时间 | ISO 8601 格式时间戳 | 2026-01-29T10:30:00.000Z |
| 用户 | 用户名称 | admin |
| 密钥 | API Key 名称 | production-key |
| 供应商 | 供应商名称(被拦截请求为空) | anthropic-main |
| 模型 | 实际使用的模型 | claude-3-5-sonnet-20241022 |
| 原始模型 | 重定向前的模型名称 | claude-3-opus |
| 端点 | API 端点 URL | /v1/messages |
| 状态码 | HTTP 响应状态 | 200 |
| 输入 Token | 输入 token 数量 | 1500 |
| 输出 Token | 输出 token 数量 | 3200 |
| 缓存写入 5m | 5 分钟缓存创建 token | 0 |
| 缓存写入 1h | 1 小时缓存创建 token | 0 |
| 缓存读取 | 缓存读取 token | 1200 |
| 总 Token | 所有 token 总和 | 5900 |
| 成本(USD) | 请求成本(美元) | 0.0156 |
| 耗时(ms) | 请求耗时(毫秒) | 2450 |
| Session ID | 会话标识符 | sess_abc123 |
| 重试次数 | 供应商切换次数 | 0 |
这些列涵盖了分析使用情况所需的所有关键信息。你可以使用这些信息计算 每个用户或 API Key 的总成本,分析不同模型的使用模式,或者识别异常 的响应时间。
安全特性
CSV 公式注入防护
导出的 CSV 文件会自动转义可能触发公式执行的字符(如 =、+、-、@、 \t、\r`)。这些字符会被添加单引号前缀,防止在 Excel 或其他电子表格 软件中打开时执行恶意代码。
这是重要的安全措施,因为恶意构造的数据可能包含类似 =CMD|' /C calc'!A0 的公式,在打开时会执行系统命令。
筛选条件
导出支持丰富的筛选条件,帮助你精确获取需要的数据:
| 筛选条件 | 说明 | 示例 |
|---|---|---|
| 用户 | 特定用户的请求 | 选择用户 "admin" |
| 密钥 | 特定 API Key 的请求 | 选择密钥 "prod-key" |
| 供应商 | 特定供应商的请求 | 选择 "anthropic-main" |
| Session ID | 精确匹配 Session ID | "sess_abc123" |
| 开始时间 | 时间范围起始(毫秒时间戳) | 1706515200000 |
| 结束时间 | 时间范围结束(毫秒时间戳) | 1706601600000 |
| 状态码 | 特定 HTTP 状态码 | 200、429、500 |
| 排除 200 | 只显示非 200 状态码的请求 | 启用 |
| 模型 | 特定模型 | claude-3-sonnet |
| 端点 | 特定 API 端点 | /v1/messages |
| 最小重试次数 | 供应商切换次数过滤 | 1(至少切换过一次) |
筛选提示
所有筛选条件会同时生效(AND 逻辑)。时间筛选使用毫秒时间戳, 确保跨时区的一致性。如果你需要导出特定时间段的数据,建议使用 时间范围筛选来限制数据量。
使用场景示例
场景 1:分析特定用户的成本
- 设置用户筛选器为目标用户
- 设置时间范围为过去 30 天
- 导出 CSV
- 在 Excel 中使用数据透视表汇总成本列
场景 2:识别失败的请求
- 启用 "排除 200" 筛选器
- 添加状态码 500 筛选
- 按供应商分组查看哪些供应商出错最多
场景 3:分析缓存命中率
- 导出包含缓存相关列的数据
- 计算(缓存读取 Token / 总 Token)的比率
- 按供应商比较缓存效率
场景 4:追踪特定 Session 的所有请求
- 在 Session 监控页面找到目标 Session ID
- 回到使用日志页面,粘贴 Session ID 到筛选器
- 导出该 Session 的所有请求记录
- 分析请求序列、响应时间和成本变化
场景 5:监控供应商切换情况
- 设置最小重试次数为 1
- 按供应商分组导出数据
- 分析哪些供应商经常导致故障转移
- 评估供应商的稳定性
数据库备份导出
功能概述
数据库备份功能允许管理员导出完整的 PostgreSQL 数据库,用于灾难恢复、 数据迁移或离线分析。这是一个管理员专用功能,需要谨慎使用。
与 CSV 导出不同,数据库备份是数据库级别的操作,会导出所有表的结构 和数据(可以选择排除日志表)。备份文件使用 PostgreSQL 自定义格式, 需要使用 pg_restore 工具恢复。
访问路径
要使用数据库备份功能:
- 使用管理员账号登录
- 进入 系统设置 > 数据管理
- 选择备份选项(是否排除日志数据)
- 点击 导出数据库备份 按钮
- 等待文件下载完成
备份选项
包含日志数据:导出完整数据库,包括所有 message_request 表的数据。 适合完整的灾难恢复场景。
排除日志数据:导出除 message_request 表数据外的所有内容, 但保留表结构。这会产生更小的备份文件,适合日常配置备份。
技术实现
数据库备份使用 PostgreSQL 的 pg_dump 工具,采用自定义格式(-Fc):
- 压缩格式:自定义格式经过压缩,比纯 SQL 导出更小
- 流式传输:数据通过流式传输直接发送到客户端,不占用服务器内存
- 分布式锁:使用 Redis 或内存锁防止并发备份操作
- 自动清理:临时文件和锁资源保证被清理
备份过程使用 Node.js 的 ReadableStream 实现流式传输,即使对于大型 数据库也能高效处理。
导出流程
用户点击导出
↓
验证管理员权限
↓
尝试获取分布式锁(Redis 或内存回退)
↓
执行 pg_dump 命令
↓
流式传输数据到客户端
↓
释放分布式锁(保证执行)
错误处理
| 错误场景 | HTTP 状态码 | 错误信息 | 解决方案 |
|---|---|---|---|
| 未登录 | 401 | Unauthorized | 重新登录 |
| 非管理员 | 401 | Unauthorized | 使用管理员账号 |
| 并发备份冲突 | 409 | Another admin is performing backup | 等待 5 分钟后重试 |
| 数据库连接失败 | 503 | Service Unavailable | 检查数据库状态 |
| 导出失败 | 500 | Internal Server Error | 查看服务器日志 |
备份文件命名
备份文件使用以下命名格式:
backup_YYYY-MM-DDTHH-mm-ss.dump
例如:backup_2026-01-29T14-30-25.dump
时间戳使用本地时间,便于识别备份的创建时间。
恢复备份
备份文件可以使用 pg_restore 命令恢复:
# 恢复完整备份
pg_restore -h localhost -U postgres -d claude_code_hub \
-v backup_2026-01-29T14-30-25.dump
# 仅恢复表结构(排除数据)
pg_restore -h localhost -U postgres -d claude_code_hub \
--schema-only -v backup_2026-01-29T14-30-25.dump
# 恢复特定表
pg_restore -h localhost -U postgres -d claude_code_hub \
-t users -t keys -v backup_2026-01-29T14-30-25.dump
恢复注意事项
恢复备份会覆盖现有数据。在生产环境执行恢复操作前, 务必先备份当前数据。建议在测试环境先验证备份文件的完整性。
Session 请求导出
功能概述
Session 请求导出功能允许管理员导出单个请求的完整详情,包括请求头、 请求体、响应头和响应体。这对于深度调试、问题排查和请求分析非常有用。
当你需要了解某个特定请求为什么会失败,或者想分析请求的具体内容时, 这个功能提供了完整的上下文信息。
访问路径
要使用 Session 请求导出功能:
- 使用管理员账号登录
- 进入 Dashboard > Session 监控
- 点击 Session ID 进入详情页
- 在消息列表中找到目标请求
- 点击请求查看详情弹窗
- 点击 导出请求 按钮
导出内容
导出的 JSON 文件包含以下字段:
{
"sessionId": "sess_abc123",
"sequence": 1,
"meta": {
"model": "claude-3-5-sonnet-20241022",
"providerId": 1,
"timestamp": "2026-01-29T10:30:00Z"
},
"headers": {
"authorization": "Bearer sk-...",
"content-type": "application/json"
},
"body": {
"model": "claude-3-5-sonnet-20241022",
"messages": [...],
"max_tokens": 4096
},
"specialSettings": {
"headerModifications": [...],
"bodyModifications": [...]
}
}
各字段说明:
sessionId:所属 Session 的标识符sequence:请求在 Session 中的序号meta:请求的元数据,包括模型、供应商、时间戳headers:完整的请求头信息body:请求体内容specialSettings:应用的请求过滤器修改记录
文件命名格式
- 有序列号:
session-{sessionId前8位}-seq-{序列号}-request.json - 无序列号:
session-{sessionId前8位}-request.json
例如:session-a1b2c3d4-seq-1-request.json
探测日志导出
功能概述
探测日志导出功能允许管理员下载端点健康探测的日志记录。系统会定期向 配置的供应商端点发送探测请求,记录响应时间和状态。这些日志对于监控 供应商可用性和排查连接问题非常有价值。
访问路径
要使用探测日志导出功能:
- 使用管理员账号登录
- 进入 Dashboard > 可用性监控
- 点击目标端点卡片进入详情页
- 在探测终端面板中查看实时日志
- 点击 下载日志 按钮
导出格式
探测日志以纯文本格式导出,每行一条记录:
[HH:mm:ss] OK 200 45ms
[HH:mm:ss] FAIL 502 120ms Connection timeout
[HH:mm:ss] OK 200 38ms
格式说明:
[HH:mm:ss]:探测时间(24 小时制)OK/FAIL:探测结果(成功或失败){statusCode}:HTTP 状态码(失败时显示-){latency}:响应延迟(毫秒){errorMessage}:错误信息(仅失败时显示)
筛选导出
导出的日志会应用当前的筛选条件:
- 时间范围:只导出选定时间范围内的日志
- 状态筛选:可只导出成功或失败的探测记录
- 最大行数:受
maxLines参数限制(默认 100 行,最多 1000 行)
文件命名格式
probe-logs-YYYY-MM-DD.txt
例如:probe-logs-2026-01-29.txt
权限控制
角色权限矩阵
系统的导出功能有严格的权限控制,确保数据安全:
| 功能 | 管理员 | 普通用户 |
|---|---|---|
| 数据库备份 | ✅ | ❌ |
| 全部使用日志 CSV | ✅ | ❌ |
| 自己的使用日志 CSV | ✅ | ✅ |
| Session 请求导出 | ✅ | ❌ |
| 探测日志导出 | ✅ | ❌ |
| 使用筛选器 | 全部 | 受限(强制 userId) |
权限实现
使用日志权限控制示例:
const finalFilters =
session.user.role === "admin"
? { ...filters, page: 1, pageSize: 10000 }
: { ...filters, userId: session.user.id, page: 1, pageSize: 10000 };
普通用户的 userId 筛选器会被强制设置为当前用户 ID,无法查看其他用户的数据。 这是在后端强制执行的,无法通过修改前端参数绕过。
分布式锁机制
为什么需要锁
数据库备份操作使用分布式锁来防止并发冲突:
- 数据一致性:避免同时导入和导出导致数据损坏或不一致
- 资源保护:防止多个管理员同时执行备份操作,消耗过多服务器资源
- 故障恢复:锁有过期时间(TTL),防止因进程崩溃导致的死锁
锁的实现
系统使用两层锁策略,确保在各种部署环境下都能正常工作:
第一层:Redis 分布式锁
- 使用 Lua 脚本确保锁的原子性获取和释放
- 锁 TTL:5 分钟(300,000 毫秒)
- 支持多实例部署,跨实例同步锁状态
- 锁键名:
database:backup:lock
第二层:内存锁回退
- 当 Redis 不可用时自动降级使用
- 基于 Node.js Map 实现
- 定期清理过期锁(每分钟)
- 单机部署时同样有效
锁的生命周期
获取锁
↓
执行备份操作
↓
流式传输数据
↓
完成/错误/取消
↓
释放锁(保证执行)
锁的释放通过 MonitoredStream 包装器保证,无论流是正常完成、 出错还是被取消,锁都会被释放。
Fail-Open 策略
当 Redis 不可用时,系统会自动降级到内存锁。如果是单机部署, 内存锁同样有效;如果是多实例部署,各实例的锁相互独立, 这意味着在 Redis 不可用时,多个实例可能同时进行备份操作。
限制与约束
CSV 导出限制
| 限制项 | 值 | 说明 |
|---|---|---|
| 最大记录数 | 10,000 | 硬编码限制,防止内存溢出 |
| 导出格式 | CSV only | 不支持 Excel 原生格式 |
| 内存使用 | 中等 | 数据加载到内存后生成 CSV |
| 超时时间 | 30 秒 | 受服务器配置限制 |
| 编码 | UTF-8 | 包含 BOM 头,Excel 兼容 |
如果你需要导出超过 10,000 条记录,建议:
- 使用更小的时间范围分批导出
- 或者直接使用数据库备份功能
数据库备份限制
| 限制项 | 值 | 说明 |
|---|---|---|
| 并发操作 | 1 | 分布式锁限制,同时只能有一个备份 |
| 访问权限 | 仅管理员 | 严格的角色检查 |
| 数据库类型 | PostgreSQL | 使用 pg_dump 工具 |
| 环境要求 | DSN 变量 | 必须配置数据库连接字符串 |
| 锁超时 | 5 分钟 | 超过后自动释放 |
Session 请求导出限制
| 限制项 | 值 | 说明 |
|---|---|---|
| 访问权限 | 仅管理员 | 角色检查 |
| 导出粒度 | 单次请求 | 不是整个 Session |
| 数据依赖 | Redis/存储 | 需要请求数据已被存储 |
| 数据保留 | 配置依赖 | 取决于 STORE_SESSION_MESSAGES 设置 |
探测日志导出限制
| 限制项 | 值 | 说明 |
|---|---|---|
| 访问权限 | 仅管理员 | 角色检查 |
| 时间范围 | 依赖配置 | 取决于探测历史保留策略 |
| 数据粒度 | 单次探测 | 每次探测一条记录 |
| 筛选依赖 | 前端状态 | 导出时应用当前可见筛选 |
故障排查
导出失败常见问题
问题:CSV 导出无响应或超时
可能原因和解决方案:
- 筛选条件过于宽泛,返回数据量太大 → 缩小时间范围或添加更多筛选条件
- 网络连接不稳定 → 检查网络连接后重试
- 浏览器 JavaScript 被禁用 → 启用 JavaScript
- 浏览器控制台报错 → 查看开发者工具中的错误信息
问题:数据库备份提示 "Another admin is performing backup"
可能原因和解决方案:
- 确实有其他管理员正在进行备份 → 等待 5 分钟后重试
- 之前的备份异常终止,锁未释放 → 等待 5 分钟让锁自动过期
- Redis 中的锁状态异常 → 联系系统管理员手动清理
问题:Session 请求导出按钮不可用
检查清单:
- 确认你是管理员身份(普通用户无此权限)
- 确认请求数据已加载完成(等待加载指示器消失)
- 确认该 Session 的请求数据已存储(取决于系统配置)
- 确认没有错误状态(错误时无法导出)
问题:导出文件损坏或无法打开
解决方案:
- CSV 文件使用 UTF-8 编码,确保使用支持的工具打开(推荐 Excel、 Google Sheets 或文本编辑器)
- 数据库备份需要 PostgreSQL 的
pg_restore工具,无法直接查看 - JSON 文件使用标准 JSON 格式,可用任何文本编辑器或 JSON 查看器打开
- 检查文件是否完整下载(网络中断可能导致文件截断)
问题:探测日志导出为空
可能原因和解决方案:
- 当前筛选条件下没有探测记录 → 调整时间范围或清除筛选条件
- 端点尚未配置探测 → 在供应商设置中启用探测功能
- 探测数据已过期被清理 → 检查系统配置的探测数据保留时间
问题:导出的 CSV 中文显示乱码
解决方案:
- CSV 文件使用 UTF-8 with BOM 编码,Excel 应该能正确识别
- 如果仍显示乱码,尝试使用 "数据 > 从文本/CSV 导入" 功能
- 在导入向导中明确选择 UTF-8 编码
- 或者使用 Google Sheets、LibreOffice 等替代工具打开
日志追踪
导出操作会记录结构化日志,便于排查问题:
数据库导出日志:
database_export_initiated:导出开始database_export_lock_conflict:锁冲突database_export_error:导出错误database_export_lock_release_error:锁释放失败
pg_dump 日志:
pg_dump_start:进程启动pg_dump_complete:完成pg_dump_error:执行错误pg_dump_cancelled:被取消
锁操作日志:
backup_lock_acquired:锁获取成功backup_lock_conflict:锁冲突backup_lock_released:锁释放成功backup_lock_fallback_to_memory:降级到内存锁
最佳实践
使用日志分析
定期导出:建议每周导出一次使用日志用于趋势分析, 每月导出完整数据用于成本核算
筛选技巧:使用时间范围和状态码筛选快速定位问题。 例如,筛选状态码 500 可以找到所有服务器错误
成本分析:使用 Excel 的数据透视表分析各供应商成本占比, 识别成本优化机会
异常检测:导出非 200 状态码的请求,分析错误模式和频率
趋势对比:导出不同时间段的数据进行对比分析, 识别使用量增长趋势或异常波动
供应商评估:定期导出各供应商的使用数据, 评估性能、成本和可靠性,优化供应商配置
数据库备份策略
定期备份:设置定时任务每日备份(排除日志数据), 保持配置数据的安全
全量备份:每周进行一次包含日志的完整备份, 保留历史请求数据
备份验证:定期测试备份文件的可恢复性, 确保在灾难发生时能正常恢复
异地存储:将备份文件复制到安全的异地存储, 防止单点故障导致数据丢失
保留策略:根据数据重要性和存储成本制定备份保留策略, 定期清理过期备份
备份加密:对于包含敏感数据的备份,考虑使用加密存储 或加密传输到远程位置
自动化脚本:使用 cron 作业或系统定时任务自动化备份流程, 减少人工操作风险
Session 调试
问题复现:导出异常 Session 的请求详情, 在本地环境中复现问题
对比分析:对比正常和异常请求的差异, 识别导致问题的关键因素
安全分享:导出前检查是否包含敏感信息(如 API Key、 用户凭证等),必要时进行脱敏处理
协作排查:将导出的 JSON 分享给团队成员, 便于协作分析和问题定位
版本控制:对于关键问题的调试数据,考虑将导出文件 纳入版本控制或问题追踪系统,便于后续参考
自动化分析:编写脚本自动分析导出的请求数据, 识别常见问题和异常模式
技术实现细节
CSV 生成实现
CSV 导出使用自定义的 generateCsv 函数实现,主要特点:
function generateCsv(logs: UsageLog[]): string {
const headers = [
"时间", "用户", "密钥", "供应商", "模型", "原始模型",
"端点", "状态码", "输入 Token", "输出 Token",
"缓存写入 5m", "缓存写入 1h", "缓存读取",
"总 Token", "成本(USD)", "耗时(ms)",
"Session ID", "重试次数"
];
const rows = logs.map(log => [
log.createdAt,
log.userName,
log.keyName,
// ... 其他字段
]);
return [headers, ...rows].map(row =>
row.map(escapeCsvField).join(",")
).join("\n");
}
关键特性:
- UTF-8 BOM 头(
\uFEFF)确保 Excel 正确识别编码 - 字段转义处理包含逗号、引号、换行符的情况
- 公式注入防护前缀危险字符
流式备份架构
数据库备份使用 Node.js ReadableStream 实现流式传输:
const stream = new ReadableStream({
start(controller) {
pgProcess.stdout.on("data", (chunk: Buffer) => {
controller.enqueue(new Uint8Array(chunk));
});
pgProcess.on("close", (code: number | null) => {
if (code === 0) {
controller.close();
} else {
controller.error(new Error(`pg_dump failed: ${code}`));
}
});
},
cancel() {
pgProcess.kill();
}
});
这种架构的优势:
- 内存占用恒定,不受数据库大小影响
- 支持取消操作(用户关闭下载时终止 pg_dump)
- 实时传输,无需等待整个备份完成
临时文件管理
数据库导入导出过程中使用临时文件,系统通过 temp-file-manager 模块确保文件被正确清理:
- 正常清理:操作完成后立即删除
- 异常清理:连接断开或进程崩溃时清理
- 定期清理:每小时清理超过 6 小时的过期文件
安全与合规
数据隐私
导出功能涉及敏感数据,使用时请注意:
- 访问控制:严格遵守角色权限,不要分享导出文件给未授权人员
- 数据脱敏:在分享或存储导出文件前,考虑删除或替换敏感字段
- 传输安全:确保导出文件通过安全渠道传输,避免中间人攻击
- 存储安全:导出文件应存储在安全位置,设置适当的文件权限
合规要求
根据你的组织合规要求,可能需要:
- 记录所有导出操作(谁在什么时间导出了什么数据)
- 定期审计导出文件的使用情况
- 对导出文件进行加密存储
- 设置导出文件的最大保留期限
审计日志
系统会记录以下导出相关操作:
- 谁执行了导出操作
- 导出类型和时间
- 筛选条件(对于 CSV 导出)
- 操作结果(成功/失败)
性能考虑
导出对系统的影响
不同导出类型对系统性能的影响:
| 导出类型 | 性能影响 | 建议 |
|---|---|---|
| CSV 导出 | 中等 | 避免在高峰时段导出大量数据 |
| 数据库备份 | 高 | 在低峰时段执行,使用排除日志选项 |
| Session 导出 | 低 | 对系统性能影响很小 |
| 探测日志导出 | 低 | 对系统性能影响很小 |
优化建议
- 分批导出:对于大量数据,使用筛选条件分批导出
- 定时导出:使用自动化脚本在系统低峰时段执行导出
- 监控资源:导出期间监控系统资源使用情况
- 流式处理:数据库备份使用流式传输,减少内存占用
