Ops · Monitoring Runbook

运营监控
Prometheus + Grafana

api.oaf.world 接的 HTTP 层健康仪表盘。Prometheus 24×7 抓 /metrics、Grafana 出图;监控台只绑 127.0.0.1 不上公网,看图走 SSH 隧道。这是「省得忘」的完整流程。

请求速率错误率平均延迟状态码限流

01它是什么 · 每块面板看什么

后端 HTTP 层的健康仪表盘(和 Langfuse 互补:Langfuse 管 LLM token/成本,这里管流量/延迟/错误)。
面板看什么怎么读
请求速率各端点被调多频繁/health 稳定打底=探活;某端点突然飙高=被刷或大量调用
错误率 5xx服务端崩没崩显示「No data」= 零 5xx = 健康(没错误就没数据点,是好事不是故障)
平均延迟哪个端点慢LLM 端点(/thesis//ask 单标的//council)本就 ~20–40s;非 LLM 该在毫秒级
状态码分布200 / 404 / 5xx 占比少量 404 通常无害(favicon/未知路径);5xx 冒头才查
限流有没有被刷平时应为 0;持续 >0 说明有 IP 打满配额(每 IP 60/min,/research·/dcf 另限 10/min)
指标来自 investresearch_api/observability.py(纯 stdlib、无新依赖):ir_http_requests_total{path,method,status} · ir_http_request_duration_seconds_sum/_count{path} · ir_rate_limited_total{path}用途:发版后确认没搞坏 · 出问题定位(哪个端点慢/报错/被刷)· 看趋势。不用天天盯。

02架构

          (公网, Caddy 反代)                      (都只绑 127.0.0.1, 不上公网)
浏览器 ──► https://api.oaf.world ──► api:8000 ──/metrics──►  prometheus:9090
                                                                │ 每 30s 抓取
                                                                ▼
你的 Mac ──SSH 隧道 -L 3000/9090──► ECS ──────────────►  grafana:3000 ──查询──► prometheus
  • 三个监控容器同在 compose 项目 deploy 的网络里,故 Prometheus 用服务名 api:8000、Grafana 用 http://prometheus:9090 互访,不经公网。
  • Prometheus / Grafana 只映射到 127.0.0.1:9090 / :3000),公网访问不到 → 少一个要加固的入口。看图靠 SSH 隧道。

03一次性搭建(做一遍即可)

  1. 设 Grafana 密码(ECS)
    cd ~/InvesResearch/web-backend/deploy
    umask 077; printf 'GRAFANA_ADMIN_PASSWORD=%s\n' '换成你的强密码' >> .env  # 单引号防解析、别贴进历史
  2. 起监控叠加层(ECS,必须带 -p deploy
    docker compose -p deploy -f docker-compose.prod.yml -f monitoring/docker-compose.monitoring.yml up -d
    docker ps --format '{{.Names}}  {{.Status}}' | grep deploy   # 应见 4 个:api/caddy/prometheus/grafana
    只新增 prometheus+grafana,api/caddy 不重启。拉镜像 ~650MB,起前 df -h / 看眼余量。
  3. 验证抓取链路(ECS,等 ~40s)
    curl -sS 'http://localhost:9090/api/v1/targets' | python3 -c "import sys,json;[print(t['labels'].get('job'),t['health']) for t in json.load(sys.stdin)['data']['activeTargets']]"
    # 期望:invesresearch-api  up
  4. 让 Mac 能 SSH 进 ECS(若 ssh 报 Permission denied)。Mac 上生成并打印公钥,把它加进 ECS 的 ~/.ssh/authorized_keys
    # Mac:
    ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "" -C "my-mac"   # 已有则跳过
    cat ~/.ssh/id_ed25519.pub
    # ECS(用现有进入方式,如阿里云 Workbench):
    umask 077; mkdir -p ~/.ssh && echo '粘贴 Mac 公钥整行' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys
    (本来就有该机 .pem 则用 ssh -i 密钥.pem …,不用加公钥。)
  5. Grafana 配数据源 + 导面板(浏览器,先开隧道见第 04 节)
    • 登录 admin / 第 1 步的密码
    • Connections → Data sources → Add → Prometheus → URL http://prometheus:9090 → Save & test
    • Dashboards → New → Import → 粘 monitoring/grafana-dashboard.json 内容 → 选数据源 → Import

04日常访问(每次想看时)

采集一直在跑,隧道只为「看」。 Prometheus 每 30s 抓取、历史一直攒,和你连不连隧道无关;隧道断了只是看不到,数据不丢

# Mac 上开隧道(保持窗口开着):
ssh -L 3000:localhost:3000 -L 9090:localhost:9090 root@<你的 ECS>
# 浏览器开 http://localhost:3000 → 登录 → 看「InvesResearch API · 运营监控」
# 想看曲线动:for i in $(seq 30); do curl -s https://api.oaf.world/health >/dev/null; done
看完关掉 SSH 窗口即可。<你的 ECS> = api.oaf.world 解析到的那台主机。

05起停 · 忘密码 · 排障

起 / 停 / 状态
# 停监控(不影响 api/caddy;加 --volumes 连历史数据一并删)
docker compose -p deploy -f docker-compose.prod.yml -f monitoring/docker-compose.monitoring.yml down
忘记 Grafana 密码
grep GRAFANA_ADMIN_PASSWORD ~/InvesResearch/web-backend/deploy/.env   # 看当初设的
docker exec -it deploy-grafana-1 grafana cli admin reset-admin-password '新密码'  # 或直接重置
  • target down:确认 prometheus 与 api 同项目(都 -p deploy);docker exec deploy-prometheus-1 wget -qO- http://api:8000/metrics | head
  • 所有面板 No data:数据源 URL 必须是 http://prometheus:9090(不是 localhost);时间范围要覆盖有流量的时段。(错误率/限流平时 No data 是正常的。)
  • 隧道 Permission denied:Mac 公钥没加进 ECS,见第 03 节第 4 步。
  • 本地 3000/9090 被占:换端口,如 -L 3001:localhost:3000 再开 localhost:3001
边界:LLM token 成本不在这套(进程内 /metrics 只覆盖 HTTP 层),成本走 Langfuse。可选 IR_METRICS_TOKEN/metrics 加抓取 token。想免隧道常驻:① 保持现状(隧道按需,最安全,当前用这个)· ② grafana.oaf.world 走 Caddy 反代 + Grafana 登录 · ③ Cloudflare Tunnel。