8.1 观测、Tracing 与调试抓手

观测、Tracing 与调试抓手#

这章解决什么问题#

这一章解决的是“当系统已经跑起来之后,出了问题先看哪里”。如果前面章节主要回答“系统怎样设计、代码在哪里”,这一章则回答“当请求异常、延迟波动、输出不稳定,或者你要定位瓶颈时,哪些 observability 和 debug 入口最值得先抓”。

这类内容不能混进前面的主线章节里讲。因为它们更多是操作层,而不是结构层。但如果完全不单独成章,读者又会在真正出问题时不知道该从 metrics、logging、trace、request dump 还是 crash dump 开始。

为什么 observability 需要独立章节#

官方 docs/advanced_features/observability.md 已经把 observability 分成三块:Production Metrics、Logging、Request Dump and Replay / Crash Dump and Replay。这种划分很有代表性,因为它说明 SGLang 并没有把“观测”理解成只有 Prometheus 指标,而是把 metrics、logs 和可复现材料都纳入观测体系。

更进一步,docs/references/production_request_trace.md 明确说 request trace 的实现落在 python/sglang/srt/observability/req_time_stats.py。这很重要,因为它把“文档层讲 tracing”与“源码层定义 request stage”连到了一起。也就是说,观测不是外围运营面板,而是 runtime 自己的一部分。

下面这张图的职责,是把 metrics、trace 和 dump / replay 这三种抓手放进同一条排障路径里。这样读者不必再靠记忆去猜“到底先看哪个”,而是能直接看出从轻量观测到重型复现的升级顺序。

flowchart TD
    A["异常 / 延迟 / 输出不稳定"] --> B["Metrics\n--enable-metrics / /metrics"]
    B --> C{"问题是整体性的\n还是个别请求?"}
    C -->|整体趋势| D["Prometheus / production_metrics"]
    C -->|单请求 / 阶段性| E["Trace\n--enable-trace / OTLP / Jaeger"]
    E --> F["req_time_stats.py\nRequestStage slices"]
    D --> G["需要更具体样本?"]
    F --> G
    G -->|是| H["Request dump / crash dump"]
    H --> I["scripts/playground/replay_request_dump.py"]
    G -->|否| J["回到对应 runtime 模块定位"]

这张图相对于段落的增量,是把“趋势问题”“阶段问题”“复现问题”拆成三个不同层次。后文再谈具体 flags 和文件路径时,读者就不会把所有调试手段混成一个平面列表。

metrics、trace、dump / replay 分别适合解决什么问题#

metrics 适合回答“系统整体现在怎么样”。docs/references/production_metrics.md 说明了 Prometheus metrics 的导出方式,docs/advanced_features/observability.md 则强调用 --enable-metrics 启动后可以通过 /metrics 暴露。对排查吞吐、队列积压、请求量变化来说,这通常是第一层信号。

trace 更适合回答“单个请求在链路里卡在哪里”。production_request_trace.md 指出可以通过 --enable-trace--otlp-traces-endpoint 打开 tracing,并把 request stage 导出到 OpenTelemetry / Jaeger。这里的关键价值不是“看图更漂亮”,而是能把 TOKENIZEAPI_SERVER_DISPATCHREQUEST_PROCESSPREFILL_FORWARDDECODE_LOOP 这些阶段拉开看。

request dump / replay 和 crash dump 则更像“把故障现场留下来”。observability.md 说明可以通过 configure_logging 配置 request dump folder,也可以用 --crash-dump-folder 保留崩溃前几分钟的请求,再用 scripts/playground/replay_request_dump.py 重放。这些能力特别适合复现难以稳定重现的问题。

调试时先用哪条路径#

一个更稳的顺序通常是:先看 metrics 确认问题是整体性的还是个别请求;如果是个别请求或阶段性延迟,再看 trace;如果 trace 还不够,就启用 request dump 或 crash dump,把问题样本重放出来。这样做的原因很简单:越往后,证据越具体,但成本也越高。

这里不要把这些工具混成一个“调试大全”。metrics 更适合回答趋势问题,trace 更适合回答阶段问题,dump / replay 更适合回答复现问题。把它们分别放回各自最擅长的场景,比在日志里盲搜关键词更有效。

本章对应哪些代码路径#

这一章最重要的锚点包括 docs/advanced_features/observability.mddocs/references/production_metrics.mddocs/references/production_request_trace.mdpython/sglang/srt/observability/req_time_stats.pypython/sglang/profiler.pyscripts/playground/replay_request_dump.py

要继续深挖,推荐顺序是:先看 observability 文档理解能力面,再看 production metrics / request trace 文档理解实际使用方式,最后回到 req_time_stats.py 看 request stage 是怎样定义出来的。这样能把“操作抓手”和“源码实现”接在一起。

小结#

这一章的核心不是列更多工具名,而是帮你建立一个排障顺序:先看 metrics,再看 trace,再决定是否进入 dump / replay。只要这个顺序清楚,扩展和维护时的调试成本就会下降很多,也更容易把观测结果映射回前面章节讲过的主链路与模块边界。