资讯动态

Headroom Proxy 指标技术指南:Prometheus 与 OpenTelemetry 双端点的指标体系、PromQL 实践与 Dashboard 避坑

发布时间:2026/9/7 17:36:28 来源:尧图企业网站定制
Headroom Proxy 指标技术指南Prometheus 与 OpenTelemetry 双端点的指标体系、PromQL 实践与 Dashboard 避坑【免费下载链接】headroomCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.项目地址: https://gitcode.com/GitHub_Trending/head/headroom本文围绕 Headroom 代理的官方指标指南 docs/metrics-technical-guide.md 展开系统讲解GET /metricsPrometheus与 OTLP/HTTPOpenTelemetry两套监控端点的定位差异覆盖节省量、延迟、缓存、流量健康度、订阅窗口、节省归因和压缩内部六大面板的完整指标表与可直接复制的 PromQL并结合 headroom/proxy/prometheus_metrics.py 与 headroom/observability/metrics.py 的源码说明每个指标在代码中的产生位置与口径差异。读完后你能独立完成为 Headroom 代理搭建 Prometheus/Grafana 面板、配置多租户 OTel 导出并规避五类最常见的 Dashboard 失真问题。两套端点先分清 Prometheus 与 OTel 的分工Headroom 代理默认监听:8787提供两个观测面端点获取方式适用场景Prometheus—GET /metrics始终开启无需任何配置下面所有指标都从这里开始OpenTelemetry— OTLP/HTTPHEADROOM_OTEL_METRICS_ENABLED1pip install headroom-ai[proxy,otel]同样的数据但指标名为点分风格并额外支持按租户维度的标签两套端点的关键差异命名不同Prometheus 使用headroom_tokens_saved_total且时间类指标以毫秒为单位OTel 使用headroom.proxy.tokens.saved时间以秒为单位。下文各面板均同时列出两套名称。覆盖口径不同以节省 token这一核心指标为例Prometheus 侧的headroom_tokens_saved_total只统计压缩不含工具 schema 延迟加载而 OTel 的headroom.proxy.tokens.saved两者都包含。源码可以直接印证这一点在 headroom/observability/metrics.py 的record_proxy_request()中self._proxy_saved_tokens.add(compression_saved tool_schema_saved, attrs)把压缩节省与工具 schema 节省合并记入headroom.proxy.tokens.saved而 Prometheus 侧在 headroom/proxy/prometheus_metrics.py 中明确注释tokens_saved_total是 message compression only工具 schema 节省单独存放在tool_search_saved_total以避免工具字节从不改变 tok_before/tok_after造成的口径混淆。/metrics路由本身实现得非常薄见 headroom/proxy/server.py直接调用proxy.metrics.export()并返回text/plain; version0.0.4导出格式由 headroom/proxy/prometheus_metrics.py 的export()方法拼装。OTel 的运行时状态则挂在/stats端点上otel: get_otel_metrics_status()headroom/proxy/server.py这也解释了文末用curl -s localhost:8787/stats | jq .otel验证的做法。节省量面板从 hero 数字开始headroom.proxy.tokens.savedOTel是头条数字。它已经合并了压缩 工具 schema 延迟加载两部分——不需要再叠加任何其他项。指标含义headroom.proxy.tokens.savedOTelHeadroom 拦在请求之外的输入 token 总量。压缩 工具节省合并后的 hero 数字headroom.proxy.savings.usd{source}OTel节省金额美元按层拆分compression、tool_schema、output_shaping、provider_cache。求和得总额headroom_persistent_savings_tokens_saved_total与上面相同的 tokens-saved 口径但在代理重启后仍然保留。用于累计节省类磁贴headroom_persistent_savings_compression_savings_usd_total累计节省金额跨重启持久化headroom_tokens_input_total实际发往上游的输入 token压缩后。是计算压缩率的分子/分母之一headroom_tokens_output_totalProvider 返回的输出 token配套 PromQL# Hero 磁贴每秒节省的 token 数 rate(headroom_tokens_saved_total[5m]) sum(rate(headroom_savings_attributed_tokens_total{sourcetool_search,realizedtrue}[5m])) # 上下文缩减百分比 100 * rate(headroom_tokens_saved_total[5m]) / clamp_min(rate(headroom_tokens_input_total[5m]) rate(headroom_tokens_saved_total[5m]), 1) # 累计磁贴跨重启保留 headroom_persistent_savings_tokens_saved_total headroom_persistent_savings_compression_savings_usd_totalPrometheus 侧的一个陷阱headroom_tokens_saved_total只包含压缩漏掉了工具 schema 延迟加载。OTel 的headroom.proxy.tokens.saved两者都算。所以上面的查询把tool_search那一项加回来了。在工具密集的负载上这个缺口会相当大。源码层面headroom_persistent_savings_*一组磁贴并非内存累加而是从持久化的SavingsTracker快照中取lifetime段读出headroom/proxy/prometheus_metrics.py这正是它们能跨重启存活的原因同一机制也决定了它们依赖持久卷——若HEADROOM_WORKSPACE_DIR未落在持久卷上部署即清零见五个会搞坏 Dashboard 的问题第 1 条。延迟面板均值可用分位数缺失Prometheus 侧所有耗时指标均以毫秒为单位并暴露为_sum/_count/_min/_max四件套均值用rate(sum)/rate(count)计算。这与源码结构一一对应headroom/proxy/prometheus_metrics.py 中latency_*、overhead_*、ttfb_*各自维护sum_ms / min_ms / max_ms / count四个字段。指标含义headroom_overhead_ms_*Headroom 自身增加的耗时handler 入口 → 压缩结束不含 LLM 调用。这就是这个东西本身花了我们多少时间的数字headroom_latency_ms_*请求总时长包含 provider 往返headroom_ttfb_ms_*上游首字节时间TTFB。仅流式请求headroom_stage_timing_ms_*{path,stage}handler 内部时间去向——compression_first_stage、upstream_connect、memory_context等headroom_transform_timing_ms_*{transform}单个压缩 transform 的耗时。用于定位慢 transform# Headroom 附加开销均值ms rate(headroom_overhead_ms_sum[5m]) / rate(headroom_overhead_ms_count[5m]) # 端到端耗时均值ms rate(headroom_latency_ms_sum[5m]) / rate(headroom_latency_ms_count[5m]) # 最慢的阶段 top5 topk(5, rate(headroom_stage_timing_ms_sum[5m]) / rate(headroom_stage_timing_ms_count[5m]))没有分位数可用。/metrics上没有直方图桶OTel 侧的直方图虽然存在如 headroom/observability/metrics.py 中headroom.proxy.request.duration、headroom.proxy.overhead.duration、headroom.proxy.ttfb.duration三个 histogram但使用的是默认桶所有请求都落进同一个桶histogram_quantile()会返回无意义值。均值是可靠的。如果今天就要真实的 p95/p99用headroom perfCLI。另外每个_sum必须除以它自己的_count。overhead 和 TTFB 只在大于 0 时才采样记录——源码中是if overhead_ms 0/if ttfb_ms 0才recordheadroom/observability/metrics.py因此它们的 count 天然小于 latency 的 count。stage 级指标的双标签设计也有源码依据stage_timing_sum以(path, stage)元组为键目的是让同一个指标名区分例如openai_responses_ws的upstream_connect与anthropic_messages的upstream_connectheadroom/proxy/prometheus_metrics.py。缓存面板分清命中、写放大与 cache bust指标含义headroom_provider_cache_hit_requests_total{provider}读取了 provider prompt cache 的请求数headroom_provider_cache_requests_total{provider}存在任意缓存活动的请求数。这才是命中率的分母headroom_cache_read_tokens_total{provider}从缓存读出的 token享折扣的那部分headroom_cache_write_tokens_total{provider}写入缓存的 token这部分要付溢价headroom_cache_write_ttl_tokens_total{provider,ttl}按 TTL 拆分的缓存写入——5m对比1hheadroom_uncached_input_tokens_total{provider}完全未命中缓存的输入 tokenheadroom_cache_bust_total因压缩破坏已缓存前缀的请求数。应当长期接近零headroom_cache_miss_attribution_total{provider,reason}缓存前缀未命中的原因——ttl_expiry、prefix_change、unknown# 按 provider 的缓存命中率 sum by (provider) (rate(headroom_provider_cache_hit_requests_total[5m])) / sum by (provider) (rate(headroom_provider_cache_requests_total[5m])) # 压缩正在破坏缓存——这个数字升高就该告警 rate(headroom_cache_bust_total[5m])不要用headroom_requests_cached_total当命中率。它把 provider 的 prompt cache 和 Headroom 自己的响应 cache 混进同一个布尔值两边都不代表。源码中缓存统计按 provider 分桶维护每个 provider 默认一个含cache_read_tokens、cache_write_tokens、cache_write_5m/1h_tokens、hit_requests即cache_read 0的请求、bust_count等键的结构headroom/proxy/prometheus_metrics.py注释里同时给出了各 provider 的缓存经济学差异——Anthropic cache_read0.1x / cache_write1.25xOpenAI cache_read0.5x 且无写入惩罚Google 约 0.1x 且有存储费Bedrock 无缓存指标。miss 归因的 reason 值来自 prefix_tracker 的MISS_*常量用于区分空闲超过缓存生命周期考虑换更长 TTL和可缓存前缀内容变了headroom/proxy/prometheus_metrics.py。流量与健康面板指标含义headroom_requests_total处理的请求数。无标签headroom_requests_by_provider{provider}按 provider 的流量分布——anthropic、openai、gemini、bedrock…headroom_requests_by_model{model}按模型的流量分布。不同 model 上限 1024 个超出部分归入modelotherheadroom_requests_failed_total上游 5xx 错误headroom_requests_rate_limited_total被Headroom 自身限流器拒绝的请求不是上游 429headroom_compression_failed_total{reason}压缩失败——timeout或error。因失败开放fail-open流量继续走但节省悄悄停了。值得配告警headroom_compression_quarantine_total{event}连续超时后压缩被隔离禁用——activated、skipped、releasedheadroom_inbound_requests_active在途请求数gauge。统计所有 HTTP 请求包括/metrics本身headroom_active_ws_sessions存活的 Codex WebSocket 会话数gauge# 失败率 rate(headroom_requests_failed_total[5m]) / clamp_min(rate(headroom_requests_total[5m]) rate(headroom_requests_failed_total[5m]), 1) # 节省悄悄停摆按原因分组 sum by (reason) (rate(headroom_compression_failed_total[5m])) # 流量构成 sum by (provider) (rate(headroom_requests_by_provider[5m]))两个细节有源码背书model 标签的基数上限来自 headroom/telemetry/context.py 的MAX_DISTINCT_MODELS 1024record_request首次触顶时折叠为modelother且只告警一次headroom/proxy/prometheus_metrics.py压缩失败计数器特意区分timeout与error注释说明这样能判断是压缩预算太紧还是真 bugheadroom/proxy/prometheus_metrics.py。Anthropic 订阅面板仅在 Anthropic OAuth/订阅账号下有效。OTel 独有gauge无标签。指标含义headroom.subscription.5h_utilization_pct5 小时限流窗口已用比例0–100headroom.subscription.7d_utilization_pct7 天窗口的同一比例headroom.subscription.5h_seconds_to_reset距 5 小时窗口重置的秒数headroom.subscription.7d_seconds_to_reset距 7 天窗口重置的秒数headroom.subscription.overage_usd已消耗的超额用量额度美元这五个 gauge 在 OTel 侧实现为create_observable_gauge 回调headroom/observability/metrics.py由record_subscription_window()从订阅追踪器的 state 字典回填数值只在extra_usage开启时更新overage_usdheadroom/observability/metrics.py。归因面板节省到底来自哪里指标含义headroom_savings_attributed_tokens_total{source,realized}按命名来源拆分的节省 token。sourcetool_search即工具 schema 延迟加载headroom_savings_attributed_usd_total{source,realized}按来源拆分的节省金额。gauge可能为负——不要对它rate()headroom_savings_attribution_events_total{source,realized}每个来源贡献了多少次headroom_waste_signal_tokens_total{signal}在输入中检测到的浪费模式——json_bloat、base64、repetition、reread等。这是诊断信号不是节省量这些行是用来解释头条数字的永远不要把它们加到总节省上。Prometheus 导出端对归因行也刻意做了类型区分headroom_savings_attributed_usd_total被声明为# TYPE ... gauge并标注 may be negativeheadroom/proxy/prometheus_metrics.pyOTel 侧对应的是create_up_down_counterheadroom/observability/metrics.py。压缩内部指标指标含义headroom.compression.tokens.inputOTel进入压缩流水线的 tokenheadroom.compression.tokens.outputOTel出来的 tokenheadroom.compression.tokens.savedOTel差值。仅压缩层的 pipeline 视角headroom.compression.runsOTel流水线执行次数。注意按 pipeline run 计不是按请求计headroom.compression.pipeline.durationOTel秒流水线耗时headroom.compression.transforms{transform}OTel哪些 transform 被触发了。高基数——在 collector 端丢弃或聚合这些指标由record_pipeline_run()一次写入tokens 前/后差值、pipeline 耗时、每个 transform 一行、每个 stage 一行跳过pipeline_total与_前缀内部键、以及 waste signal 明细headroom/observability/metrics.py。五个会搞坏 Dashboard 的问题只有节省计数器能跨重启存活。60 个 Prometheus 指标族中有 55 个在代理重启时归零。只有headroom_persistent_savings_*持久且要求HEADROOM_WORKSPACE_DIR位于持久卷上——否则每次部署都会重置。任何地方都没有分位数。用均值。见延迟面板一节。headroom_latency_ms对流式请求的计时方式不同。流式请求的计时起点在压缩之后所以端到端是latency overhead非流式则只有latency。不要把两者混在同一个面板里。5xx 会抹掉它自己的节省。上游失败的请求会从所有节省与 token 计数器中剔除。Provider 故障期间节省率会显得异常漂亮而吞吐在跌——这是假象。设置了代理 token 时/metrics需要鉴权。配置了HEADROOM_PROXY_TOKEN后任何非 loopback 的抓取器都必须发送Authorization: Bearer token。loopback 永远豁免。文档里提到、但代码里不存在的指标如果面板返回空值多半是这个原因。下面这些名字出现在对外文档中但代码并不产生它们headroom_compression_ratio·headroom_latency_seconds及_bucket·headroom_cache_hits_total·headroom_cache_misses_total·headroom_cost_usd_total·headroom_requests_total上的modeoptimize标签另外仓库自带的 examples/grafana/headroom-dashboard.json 的所有面板都过滤了pool和hook两个没有任何指标会产生的标签——对应下拉框会永远是空的其余指标名本身是正确的。导入该 dashboard 后需先移除这两处过滤条件。配置参考# Prometheus —— 什么都不用做GET /metrics 始终开启 # OpenTelemetry pip install headroom-ai[proxy,otel] export HEADROOM_OTEL_METRICS_ENABLED1 export HEADROOM_OTEL_METRICS_ENDPOINThttps://otel.corp.example/v1/metrics export HEADROOM_OTEL_METRICS_HEADERSauthorizationBearer XXX export HEADROOM_OTEL_RESOURCE_ATTRIBUTESservice.instance.id$HOSTNAME变量默认值说明HEADROOM_OTEL_METRICS_ENABLED0总开关HEADROOM_OTEL_METRICS_EXPORTERotlp_http或console。不存在 gRPC exporterHEADROOM_OTEL_METRICS_ENDPOINT未设置原样传递——不会自动拼接/v1/metricsHEADROOM_OTEL_METRICS_HEADERS未设置kv,k2v2格式HEADROOM_OTEL_METRICS_EXPORT_INTERVAL_MS10000导出间隔HEADROOM_OTEL_SERVICE_NAMEheadroom-proxy服务名HEADROOM_OTEL_RESOURCE_ATTRIBUTES未设置请在这里设置service.instance.id——Headroom 不会替你做多副本会互相撞用curl -s localhost:8787/stats | jq .otel验证当前 OTel 配置。这些环境变量并非文档口径而是直接由 headroom/observability/metrics.py 的OTelMetricsConfig.from_env()解析总开关_parse_bool(os.environ.get(HEADROOM_OTEL_METRICS_ENABLED), defaultFalse)接受1/true/yes/on与0/false/no/off大小写不敏感。Exporter 白名单未知取值会打 warning 并回落到otlp_http——源码里只有console与otlp_http两个分支configure_otel_metrics()对后者构造OTLPMetricExporter并原样传入endpoint与headers再挂到PeriodicExportingMetricReader上headroom/observability/metrics.py。Headers 解析按逗号拆分再按第一个拆键值空值与无的片段静默丢弃_parse_key_value_pairsheadroom/observability/metrics.py。导出失败不致命若未安装 OTel SDKconfigure_otel_metrics()只记录一条 warningInstall headroom-ai[otel]…并返回 no-op 兼容的 meterheadroom/observability/metrics.py。多租户标签register_otel_metric_attribute_provider()可以把请求级属性tenant、team、成本中心等附加到每个 OTel 数据点。上限为16 个属性、每个 256 字符——对应源码常量_MAX_DYNAMIC_ATTRIBUTES 16与_MAX_DYNAMIC_ATTRIBUTE_LENGTH 256headroom/observability/metrics.py。该 seam 的设计约束值得注意provider 在请求上下文中执行、必须返回无内容的标量标签且失败的 provider 会被静默忽略保证观测层不会打断流量headroom/observability/metrics.py同时动态属性的优先级刻意低于正式维度标签provider/model/source 等见_attrs()的合并逻辑headroom/observability/metrics.py。离线air-gapped部署HEADROOM_OFFLINE1会关闭全部出站流量——匿名用量信标默认是开启的、更新检查、以及模型下载。进一步深入仓库内的相关入口指标导出的完整拼装逻辑headroom/proxy/prometheus_metrics.py 的export()含标签转义防注入细节_escape_label_value防止单个畸形 model 名 500 掉整个 scrapeheadroom/proxy/prometheus_metrics.py。OTel 指标注册与记录入口headroom/observability/metrics.pyHeadroomOtelMetrics各类 instrument 与record_*方法。端点挂载headroom/proxy/server.py/metrics与:8787/stats中的.otel状态段headroom/proxy/server.py。行为验证测试tests/test_prometheus_label_escaping.py、tests/test_prometheus_obs_counters.py、tests/test_proxy_cache_ttl_metrics.py、tests/test_persistent_metrics.py、tests/test_observability_metrics.py。官方配套 dashboard导入前记得删除pool/hook过滤examples/grafana/headroom-dashboard.json。适用前提再强调一遍以上指标名、单位Prometheus 毫秒 / OTel 秒与默认值均以当前仓库代码为准/metrics始终开启OTel 需要额外安装headroom-ai[proxy,otel]并显式打开总开关需要分位数p95/p99时应使用headroom perfCLI 而非依赖/metrics。【免费下载链接】headroomCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.项目地址: https://gitcode.com/GitHub_Trending/head/headroom创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价