预计阅读 6 分钟

生产 3:监控(Prometheus / Grafana / Tracing)

谁该读这一篇? 要把 SGLang 接入监控体系、定 dashboards / alerts 的 SRE。 前置阅读: 02-kubernetes.md耗时: 35 分钟 学完能: 1. 列出 SGLang 必看的"黄金 5 指标"; 2. 写一份能直接抄的 Grafana 面板 JSON; 3. 写一份 Prometheus 告警规则; 4. 接入 OpenTelemetry trace; 5. 知道哪些指标对应业务什么含义。


1. 黄金 5 指标

指标 PromQL 模板 看什么
TTFT p99 histogram_quantile(0.99, rate(sglang_e2e_first_token_latency_seconds_bucket[5m])) 用户感知"卡多久才开始打字"
TPOT p99 histogram_quantile(0.99, rate(sglang_inter_token_latency_seconds_bucket[5m])) 用户感知"打字速度"
Throughput rate(sglang_generation_tokens_total[1m]) 单副本 token/s
Cache hit rate sglang_cache_hit_rate 或 derived 前缀命中率
Queue depth sglang_num_queue_reqs 排队长度

任何 dashboard 至少要有这 5 张图。


2. SGLang 暴露的指标速查

curl localhost:30000/metrics | grep "^sglang:" | head -30

主要类别:

# 请求级别
sglang:e2e_request_latency_seconds_bucket
sglang:e2e_first_token_latency_seconds_bucket
sglang:inter_token_latency_seconds_bucket

# 计数器
sglang:num_requests_total
sglang:num_input_tokens_total
sglang:num_output_tokens_total
sglang:num_aborted_requests_total

# 状态
sglang:num_running_reqs
sglang:num_queue_reqs
sglang:num_used_tokens
sglang:cache_hit_rate
sglang:gen_throughput

# 调度器
sglang:scheduler_idle_time
sglang:prefill_tokens_per_iter
sglang:decode_batch_size

# 投机解码(如开)
sglang:spec_accept_rate
sglang:spec_avg_accepted_tokens

# MoE(如适用)
sglang:moe_expert_load
sglang:moe_imbalance_ratio
sglang:moe_alltoall_latency_ms

源码:srt/observability/srt/metrics/


3. Prometheus 抓取配置

# prometheus.yml
scrape_configs:
  - job_name: sglang
    scrape_interval: 15s
    scrape_timeout: 10s
    metrics_path: /metrics
    static_configs:
      - targets:
          - sglang-7b.llm.svc.cluster.local:30000
        labels:
          model: qwen-7b
          gpu: h100

K8s 用 Operator 的 ServiceMonitor(02-kubernetes.md §10)。


4. 告警规则(抄走)

# alerts.yml
groups:
  - name: sglang
    rules:
      - alert: SGLangTTFTHigh
        expr: histogram_quantile(0.99, rate(sglang_e2e_first_token_latency_seconds_bucket[5m])) > 1
        for: 2m
        labels: {severity: warning}
        annotations:
          summary: "SGLang TTFT p99 > 1s on {{ $labels.instance }}"

      - alert: SGLangTPOTHigh
        expr: histogram_quantile(0.99, rate(sglang_inter_token_latency_seconds_bucket[5m])) > 0.1
        for: 5m
        labels: {severity: warning}
        annotations:
          summary: "SGLang TPOT p99 > 100ms on {{ $labels.instance }}"

      - alert: SGLangCacheHitDrop
        expr: avg_over_time(sglang_cache_hit_rate[10m]) < 0.2
        for: 10m
        labels: {severity: warning}
        annotations:
          summary: "SGLang cache hit rate dropped < 20%"

      - alert: SGLangQueueBuildup
        expr: avg_over_time(sglang_num_queue_reqs[5m]) > 100
        for: 5m
        labels: {severity: critical}
        annotations:
          summary: "SGLang queue depth > 100 sustained  capacity?"

      - alert: SGLangAbortRateHigh
        expr: rate(sglang_num_aborted_requests_total[5m]) > 1
        for: 5m
        labels: {severity: critical}
        annotations:
          summary: "SGLang aborting requests on {{ $labels.instance }}"

      - alert: SGLangKVPoolFull
        expr: sglang_num_used_tokens / sglang_max_total_num_tokens > 0.95
        for: 5m
        labels: {severity: warning}
        annotations:
          summary: "KV pool > 95% used  evict storm likely"

      - alert: SGLangDown
        expr: up{job="sglang"} == 0
        for: 1m
        labels: {severity: page}
        annotations:
          summary: "SGLang instance {{ $labels.instance }} is DOWN"

      - alert: SGLangSpecAcceptRateLow
        expr: avg_over_time(sglang_spec_accept_rate[10m]) < 0.5
        for: 15m
        labels: {severity: info}
        annotations:
          summary: "Spec decoding accept rate < 0.5  negative optimization?"

5. Grafana 面板骨架

最关键的 8 个 panel:

Panel 类型 PromQL
TTFT p50/p99 Time series 见 §1
TPOT p50/p99 Time series 见 §1
Throughput Time series rate(sglang_generation_tokens_total[1m])
Cache hit rate Stat sglang_cache_hit_rate
Running / Queue Time series sglang_num_running_reqs / sglang_num_queue_reqs
KV pool used Gauge sglang_num_used_tokens / sglang_max_total_num_tokens
Spec accept rate Time series sglang_spec_accept_rate (if applicable)
Error rate Stat rate(sglang_num_aborted_requests_total[5m])

可以用 Grafana 自带 LLM dashboards(社区有 SGLang 模板)作为起点,按业务调整。


6. SLO 仪表板

业务侧关心的 SLI:

sli_ttft_p99_seconds  = histogram_quantile(0.99, rate(sglang_e2e_first_token_latency_seconds_bucket[1h]))
sli_tpot_p99_seconds  = histogram_quantile(0.99, rate(sglang_inter_token_latency_seconds_bucket[1h]))
sli_success_ratio     = (1 - rate(sglang_num_aborted_requests_total[1h]) / rate(sglang_num_requests_total[1h]))

SLO 目标:

TTFT p99 < 500 ms  目标 99% 时间满足
TPOT p99 < 50 ms   目标 99.5% 时间满足
Success > 99.9%

错误预算 = (1 - SLO_target) × 时间窗口。 错误预算用光 → 暂停新功能上线、专攻稳定性。


7. 日志聚合

SGLang 日志 → stdout → Docker / K8s 收集 → Loki / ELK。 关键日志事件:

  • [INFO] Prefill batch... / Decode batch... 周期性
  • [WARNING] ... preempt ...
  • [ERROR] ... OOM ... / ... NCCL ...
  • [INFO] Application startup complete

可以用 Loki LogQL 查关键事件:

{namespace="llm",app="sglang-7b"} |~ "preempt|OOM|abort|hang"

8. 分布式追踪(OpenTelemetry)

SGLang 支持 OTel:

--otlp-endpoint http://otel-collector:4317 \
--otlp-traces-sampler-arg 0.01      # 1% 采样

每个请求会生成一条 trace,包含:

  • TM tokenize span
  • Scheduler match_prefix span
  • Scheduler run_batch span
  • Detokenize span

接 Jaeger / Tempo 看时间分布。

业务把自己的 trace_id 通过 header 传过来,全链路串起来:

client trace_id ──HTTP header──▶ SGLang
                                    ├── 父 span: 客户端 trace_id
                                    └── 子 spans: 内部各阶段

9. 自定义指标

srt/observability/ 加:

from prometheus_client import Counter, Histogram
my_counter = Counter("sglang_custom_event_total", "Custom events", ["type"])
my_hist = Histogram("sglang_custom_latency_seconds", "Custom latency")

# 在合适位置调用
my_counter.labels(type="cache_evict").inc()
with my_hist.time():
    do_something()

/metrics 端点自动暴露。


10. 监控阅读"工作流"

每天值班的固定动作:

  1. 看 SLO 面板(TTFT / TPOT / Success)—— 红就深入。
  2. 看 Throughput / Cache hit rate / Queue —— 找趋势变化。
  3. 看 Top alerts —— 处理或抑制。
  4. 周报:错误预算 / 容量 / 异常事件。

不要追着每个 spike,关注趋势 + p99。


11. 小结

  • 黄金 5 指标:TTFT / TPOT / Throughput / Cache hit / Queue。
  • Prometheus 抓 /metrics,告警规则按上面抄。
  • Grafana 面板 8 个 panel 是基础。
  • OpenTelemetry 让全链路 trace 可达。
  • 业务 SLI/SLO 单独建面板,错误预算管理上线节奏。

12. 自检

  1. TTFT 突增但 TPOT 平稳,可能原因?
答案 TTFT 反映 prefill + 排队,TPOT 反映 decode 步时。TPOT 不变说明 GPU forward 性能正常。 TTFT 突增原因: (1) **排队**:waiting_queue_size 涨——流量突增 / 容量不够。 (2) **prompt 突然变长**:业务侧改 system prompt / RAG 带更多 context;prefill 算力翻倍。 (3) **cache_hit_rate 跌**:突然命中率从 60% → 10%,每请求都从零 prefill。 (4) **chunked prefill 触发**:长 prompt 被切多轮,TTFT 累计多步。 (5) **新流量进未 warmup 副本**:K8s 扩容新 Pod 还没沉淀 cache。 优先查 (1) 和 (3)。
  1. Cache hit rate 跌到 0.1,先看哪个指标?
答案 按优先级: (1) **`sglang_num_used_tokens` / `sglang_max_total_num_tokens`**:KV pool 是否 95%+,evict 频繁;是的话 hit rate 跌是因为 cache 留不住。 (2) **业务方变更**:问业务有没改 prompt 模板(最常见,加 timestamp / random salt)。 (3) **router 路由策略**:是否从 cache-aware 切到 round-robin / 重启了 router。 (4) **新业务上线**:新 prompt 模板还没 warmup。 (5) **`/flush_cache` 误调用**:管理 API 被误触。 先看 (1) 排除显存压力,再排查 (2) (3)。
  1. 错误预算用尽时该怎么办?
答案 按 Google SRE 规范分级处理: - **用尽 50%**:Yellow,关注但仍正常发布。 - **用尽 100%(错误预算耗尽)**:Red,**冻结新功能上线**,所有变更需对外解释、必须是降低错误率的修复;不允许新增风险。 - **持续超额**:升级到 OKR / 产品决策层面,可能要(a) 调 SLO(更宽松,承认能力上限);(b) 加投资(更多副本 / 更好硬件);(c) 砍业务(降需求)。 预算耗尽不是"系统挂了",是"承诺与现实差距过大"的信号;要么改承诺要么投资改进。
  1. OTel 1% 采样会丢什么信息?
答案 1% 头部采样的影响: (1) **长尾不可见**:p99 / p999 由 1% 中的 1%(万分之一)支撑,1% 采样后 p99 完全 unreliable。 (2) **罕见事件遗漏**:每天才几次的特定 tool call 失败、特定模型 OOM 等,可能根本采不到。 (3) **关联请求断链**:业务有 multi-step agent,一步采样到、下一步没采到,trace 链条断。 (4) **错误请求采样率不偏**:错误请求占比 < 1% 时几乎不会被采到,看不到错误 trace。 优化:**tail-based sampling**——先全采,根据响应结果决定是否保留(错误 / 慢请求 100% 留,正常请求 1% 留);OTel Collector 支持。
  1. KV pool 95% 是不是该立刻扩容?
答案 不一定,先看是不是稳态。 95% **稳态**:实际就是 sweet spot——KV pool 充分利用,cache 沉淀好,hit rate 高。这是健康的"满载",不需要扩容(扩反而降利用率)。 95% **持续涨 + waiting_queue 涨**:才是真过载,evict 频繁、新请求等不到 slot;扩容。 95% **突发**:可能业务突增 / 长 prompt 涌入,看后续趋势再决定。 判断口诀:**KV pool 利用率 + waiting queue 长度 一起看**。pool 满 + queue 短 = 健康;pool 满 + queue 长 = 过载。

13. 下一步

上游源码:sglang/python/sglang/srt/observability/sglang/python/sglang/srt/metrics/