--- allowed-tools: Bash(wsl -- *) description: 'Command: debug-prod (imported from Claude Code)' name: cmd-debug-prod --- ## 线上排查命令 用户要求排查线上问题。根据 `$ARGUMENTS` 确定目标服务器,然后根据问题类型选择合适的操作。 ### 参数 `$ARGUMENTS` 中可能传入: - (空) — 默认排查国外服务器(OV,主节点) - `cn` — 只排查国内服务器 - `ov` — 只排查国外服务器 - `all` — 排查两台服务器 如果用户没有明确指定,**默认排查 OV 服务器**(因为 MySQL 主库在 OV)。 --- ### 服务器配置 | 节点 | SSH | docker-compose 目录 | new-api 容器名 | MySQL 容器名 | |------|-----|---------------------|---------------|-------------| | 🇨🇳 国内 CN | `root@123.57.74.135` | `/root/new-api/` | `cn-new-api` | `ov-mysql` | | 🌏 国外 OV | `root@139.180.189.205` | `/root/new-api/new-api/` | `ov-new-api` | `mysql` | **重要**:两台服务器的 MySQL 实际都在 OV(国外节点)。CN 的 SQL_DSN 指向 `ov-mysql:3306`。所以查数据库统一用 OV 的 MySQL 容器 `mysql`。 MySQL 连接:`docker exec mysql mysql -uroot -pLanqi123456 new-api -e "SQL语句"` --- ### 所有命令执行方式 **必须通过 WSL 执行**(SSH 密钥在 WSL 中): ```bash # 单条命令 wsl -- bash -c "ssh root@HOST '命令'" # 多条命令(引号嵌套复杂时用 heredoc) wsl -- bash -c "ssh root@HOST 'cmd1 && cmd2 && cmd3'" ``` --- ### 操作指南 根据用户描述的问题,选择合适的排查步骤。**不要一次性执行所有操作**,应该根据问题逐步排查。 #### 1. 服务状态检查 ```bash # 查看所有容器状态 wsl -- bash -c "ssh root@HOST 'cd COMPOSE_DIR && docker compose ps'" # 健康检查 wsl -- bash -c "ssh root@HOST 'curl -s http://localhost:3000/api/status'" # 系统资源(CPU/内存/磁盘) wsl -- bash -c "ssh root@HOST 'free -h && df -h / && docker stats --no-stream'" ``` #### 2. 应用日志 ```bash # 最近 N 行容器日志 wsl -- bash -c "ssh root@HOST 'docker logs --tail 100 CONTAINER_NAME'" # 实时跟踪日志(带超时,避免阻塞) wsl -- bash -c "ssh root@HOST 'timeout 5 docker logs --tail 50 --since 5m CONTAINER_NAME'" # 搜索特定关键词(如错误、某用户、某模型) wsl -- bash -c "ssh root@HOST 'docker logs --tail 500 CONTAINER_NAME 2>&1 | grep -i KEYWORD'" # 应用日志文件(oneapi-*.log) wsl -- bash -c "ssh root@HOST 'ls -lt COMPOSE_DIR/logs/ | head -5'" wsl -- bash -c "ssh root@HOST 'tail -100 COMPOSE_DIR/logs/oneapi-XXXX.log'" ``` #### 3. MySQL 查询 **连接方式(在 OV 服务器上执行)**: ```bash wsl -- bash -c "ssh root@139.180.189.205 'docker exec mysql mysql -uroot -pLanqi123456 new-api -e \"SQL语句\"'" ``` 注意:SQL 语句中的双引号需要用 `\"` 转义。 **常用查询模板**: ```sql -- 查用户信息 SELECT id, username, email, role, status, quota, used_quota, \`group\`, aff_code FROM users WHERE username = 'XXX'; -- 查用户最近的请求日志 SELECT id, created_at, type, model_name, quota, channel_id, content FROM logs WHERE user_id = XXX ORDER BY created_at DESC LIMIT 20; -- 查某时间段内的错误日志 SELECT id, created_at, type, content, model_name FROM logs WHERE created_at >= '2026-04-16 00:00:00' AND type = 2 ORDER BY created_at DESC LIMIT 50; -- 查渠道状态和余额 SELECT id, name, type, status, balance, used_quota, models, \`group\`, priority FROM channels WHERE status != 3; -- 查某渠道的最近请求 SELECT id, created_at, model_name, quota, content FROM logs WHERE channel_id = XXX ORDER BY created_at DESC LIMIT 20; -- 查 Token 信息 SELECT id, name, \`key\`, status, remain_quota, used_quota, expired_time FROM tokens WHERE user_id = XXX; -- 查最近的充值/支付记录 SELECT id, user_id, amount, money, trade_no, status, created_at FROM topups ORDER BY created_at DESC LIMIT 20; -- 查订阅订单 SELECT id, user_id, plan_id, status, amount, created_at FROM subscription_orders ORDER BY created_at DESC LIMIT 20; -- 查同步记录(主从同步问题) SELECT * FROM pending_sync_records ORDER BY id DESC LIMIT 20; SELECT * FROM quota_sync_logs ORDER BY id DESC LIMIT 20; -- 查 Midjourney 任务状态 SELECT id, user_id, action, status, progress, fail_reason, created_at FROM midjourneys ORDER BY created_at DESC LIMIT 20; -- 查系统配置 SELECT \`key\`, value FROM options WHERE \`key\` IN ('ServerAddress', 'TopUpLink', 'QuotaForNewUser', 'QuotaForInviter', 'QuotaForInvitee'); ``` **日志类型 (type 字段)**: - `1` — 消耗 (consume) - `2` — 充值 (recharge/topup) - `3` — 管理员操作 - `4` — 系统 #### 4. Relay 抓包日志(请求体/响应体完整记录) 对开启了 `capture_relay` 的用户,系统会将完整的请求体和响应体写入容器内文件。适用于需要查看客户端实际发送的请求体内容的场景(如验证字段是否正确、排查请求格式问题)。 **文件路径**(容器内):`/data/data/relay-capture/{YYYY-MM-DD}/{requestID}.log` ```bash # 列出某天的抓包文件(最新 20 个) wsl -- bash -c 'ssh root@HOST "docker exec CONTAINER_NAME ls -lt /data/data/relay-capture/2026-05-14/ | head -20"' # 查看特定请求的抓包内容(requestID 从日志错误行中获取) wsl -- bash -c 'ssh root@HOST "docker exec CONTAINER_NAME cat /data/data/relay-capture/2026-05-14/REQUEST_ID.log"' # 文件很大时,只看请求头 + 请求体前 2000 字节 wsl -- bash -c 'ssh root@HOST "docker exec CONTAINER_NAME head -c 2000 /data/data/relay-capture/2026-05-14/REQUEST_ID.log"' ``` **抓包文件格式**: ``` === REQUEST 2026-05-14T09:09:51.80665026Z === POST /v1/chat/completions user_id: 44 X-Forwarded-For: 184.73.225.134 User-Agent: Cursor/1.0 Content-Type: application/json ... {"stream":true,"model":"openai/gpt-5.4","messages":[...]} === RESPONSE === {"error":{"message":"field messages is required",...}} === END duration_ms=6 === ``` **使用场景**: - 客户端发送了错误格式的请求体(如用 `input` 代替 `messages`) - 需要确认请求头、User-Agent、请求体字段 - 排查特定 request ID 的完整请求/响应链路 **注意**: - 只有开启了 `capture_relay` 的用户才有抓包文件,未开启的用户查不到 - 请求体可能很大(100KB+),建议先用 `head -c` 限制输出大小 - 抓包文件名即 request ID,可从容器的 `[ERR]` 日志行中提取 #### 5. 容器内操作 ```bash # 进入容器执行命令(如检查网络连通性) wsl -- bash -c "ssh root@HOST 'docker exec CONTAINER_NAME wget -qO- http://localhost:3000/api/status'" # 重启某个服务(谨慎操作,先确认用户意图) wsl -- bash -c "ssh root@HOST 'cd COMPOSE_DIR && docker compose restart new-api'" ``` --- ### 排查流程建议 1. **先问清楚问题**:什么现象?什么时候开始的?影响哪些用户? 2. **服务状态** → 检查容器是否正常运行 3. **应用日志** → 搜索错误关键词、时间范围 4. **数据库查询** → 根据日志中的线索查相关数据 5. **Relay 抓包** → 如果日志中只有错误摘要但看不清请求体细节,检查用户是否开启了 `capture_relay`,若有则读取抓包文件查看完整请求/响应 6. **综合分析** → 给出问题原因和修复建议 ### 注意事项 - **不要执行任何写入操作**(INSERT/UPDATE/DELETE),除非用户明确要求 - MySQL 查询要加 `LIMIT`,避免返回过多数据 - 查询时间范围要合理,不要全表扫描 - 如果发现需要重启服务,先告知用户再操作 - 所有输出向用户展示时,用中文解释含义