Prhub

#25163 Add sglang:get_loads_duration_seconds metric

原始 PR 作者 merrymercy 合并时间 2026-05-14 09:38 文件变更 3 提交数 2 评论 4 代码增减 +16 / -0

执行摘要

为 /v1/loads 端点添加 Prometheus 延迟直方图

PR body 明确指出:「Add a Histogram metric (sglang:get_loads_duration_seconds) to track the latency of /v1/loads requests」。目的是增强对负载端点延迟的可观测性,便于负载均衡和容量规划。

该 PR 变更小、影响明确,可作为可观测性增强的范例。建议精读 v1_loads.py 的 finally 块实现,学习 try/finally 埋点模式。虽然 review 建议未采纳,但整体逻辑正确,可以直接合入。

讨论亮点

gemini-code-assist[bot] 在 review 中提出了两个改进建议:

  • v1_loads.py 的 finally 块中,除了检查 mc 非空外,还应使用 hasattr(mc, 'get_loads_duration_seconds') 防止 metric 属性不存在导致 AttributeError。
  • metrics_collector.py 中注册 Histogram 时应使用 self.labels.keys() 而非 labels.keys(),以兼容 labels 参数为 None 的情况。
    这些建议均为中等优先级,但 PR 作者没有采纳,直接合并。

实现拆解

  1. 注册直方图指标:在 python/sglang/srt/observability/metrics_collector.pyTokenizerMetricsCollector.__init__ 中,新增一个 Histogram 实例 self.get_loads_duration_seconds,使用与已有指标相同的标签集,并设置细粒度的亚秒级 buckets(0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0)。

  2. 端点埋点计时:在 python/sglang/srt/entrypoints/v1_loads.pyget_loads 路由中,在方法入口处记录 time.perf_counter() 起始时间,在 try/finally 块中获取 tokenizer_manager.metrics_collector,并通过 mc.get_loads_duration_seconds.labels(**mc.labels).observe(...) 上报耗时。

  3. 测试配套修改:在 test/registered/language/test_srt_backend.pysetUpClass 中,为 sgl.Runtime 添加 enable_metrics=True 参数,使得测试服务器运行时启用指标收集,从而自动覆盖新注册的直方图。

文件 模块 状态 重要度
python/sglang/srt/entrypoints/v1_loads.py 负载端 modified 6.01
python/sglang/srt/observability/metrics_collector.py 可观测性 modified 5.39
test/registered/language/test_srt_backend.py 测试 modified 3.46

关键符号

get_loads TokenizerMetricsCollector.__init__ TestSRTBackend.setUpClass

关键源码片段

python/sglang/srt/entrypoints/v1_loads.py dependency-wiring

核心变更点:在 /v1/loads 端点中添加计时逻辑,引入 time 模块,在 try/finally 块中记录指标。

# python/sglang/srt/entrypoints/v1_loads.py ( 关键变更 )
import time # 新增:用于计时
# ...@router.get("/v1/loads")
async def get_loads(
    dp_rank: Optional[int] = None,
    include: Optional[str] = None,
    format: Optional[str] = None,
    tokenizer_manager=Depends(_get_tokenizer_manager),
):
    include_list = [s.strip() for s in include.split(",")] if include else None
​
    start = time.perf_counter() # 新增:开始计时
    try:
        load_results = await tokenizer_manager.get_loads(
            include=include_list,
            dp_rank=dp_rank,
        )
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    finally:
        # 获取 metrics collector 并上报耗时,确保异常路径也能记录
        mc = getattr(tokenizer_manager, "metrics_collector", None)
        if mc is not None:
            mc.get_loads_duration_seconds.labels(**mc.labels).observe(
                time.perf_counter() - start
            )
    # ... 剩余逻辑不变
python/sglang/srt/observability/metrics_collector.py core-logic

注册 Histogram 指标的定义,包括指标名称、文档和 buckets。

# python/sglang/srt/observability/metrics_collector.py
# 在 TokenizerMetricsCollector.__init__ 中新增(位于已有指标注册区后):
self.get_loads_duration_seconds = Histogram(
    name="sglang:get_loads_duration_seconds",
    documentation="Time spent serving /v1/loads requests (seconds).",
    labelnames=labels.keys(),
    buckets=(0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0),
    # 亚秒级桶,适合低延迟接口
)

评论区精华

缺少 hasattr 检查可能导致 AttributeError 正确性

gemini-code-assist[bot] 建议在 finally 块中额外检查 `hasattr(mc, 'get_loads_duration_seconds')`,以防 metrics collector 类型变更。

结论:PR 作者未采纳,直接合并。项目内 metric collector 统一,风险低。 · unresolved

Histogram labelnames 应使用 self.labels.keys() 正确性

gemini-code-assist[bot] 建议使用 `self.labels.keys()` 代替 `labels.keys()`,以兼容 labels 参数为 None 的情况。

结论:PR 作者未采纳,直接合并。实际调用中 labels 不会为 None。 · unresolved

风险与影响

  1. 低风险:变更仅在 /v1/loads 端点中增加了计时逻辑和指标注册,不修改核心请求处理路径。
  2. 潜在 AttributeError:未采纳 review 建议,如果 metrics_collector 对象不存在 get_loads_duration_seconds 属性,可能抛出异常。但鉴于 metrics_collector 是该项目内统一的指标采集器,风险可控。
  3. 标签键不一致:未使用 self.labels.keys(),若 labels 参数为 None 则可能引发错误,但实际调用时 labels 均由 TokenizerMetricsCollector 内部传入,不会为 None。
  1. 用户:无直接影响。新增指标仅影响 Prometheus 监控端点 /metrics,用户可通过该端点观察 /v1/loads 延迟。
  2. 系统:增加微小的内存开销(注册一个 Histogram)和运行时开销(一次 time.perf_counter() 调用),可忽略不计。
  3. 团队:丰富了监控指标,有助于排查负载均衡和调度相关问题。
review 建议未采纳 潜在 AttributeError

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论