指标与用量事件
AISIX 网关会公开聚合指标和可导出的用量事件。这些信号共同反映服务健康状况、流量趋势,以及每次请求尝试对应的模型、路由和策略结果。
选择遥测来源
请先选择与运维问题匹配的来源;需要深入调查问题时,再按请求、模型或服务提供方关联各类信号。
| 运维问题 | 首选来源 | 提供的信息 |
|---|---|---|
| 各网关实例的流量是否健康? | Prometheus 指标 | 请求速率、延迟分布、Token 和成本计数、策略结果、路由健康、缓存行为和导出器投递健康。 |
| 单个请求发生了什么? | 访问日志 | 结构化请求字段,包括状态、延迟、模型、模型服务提供方、请求 ID,以及可用时的路由结果。 |
| 调用应用可以观察到什么? | 响应头 | 受支持路由上的请求关联、缓存结果、重试时机和选中目标提示。 |
| 请求记录可以存储到哪里、如何分析或用于核算 ? | 用量事件 | 通过可观测性导出器投递的逐次尝试结果和消耗记录。 |
抓取 Prometheus 指标
AISIX 默认通过专用指标监听器在 /metrics 提供 Prometheus 指标。你可以通过启动期可观测性设置修改路径或禁用该端点。
该端点设计上不做认证。请保持专用指标监听器私有。
在启动配置中配置 Prometheus 暴露:
observability:
metrics:
prometheus:
enabled: true
path: "/metrics"
专用监听器默认绑定到 0.0.0.0:9090。如果 Prometheus 应从其他接口或端口抓取指标,请设置不同的监听地址。
抓取默认指标端点:
curl -sS "http://127.0.0.1:9090/metrics"
AISIX 会在每次抓取时发布配置状态。其他指标族会在首次观测时注册,因此流量指标可能不会在启 动后立即出现。请先发送一次模型请求,再检查 aisix_requests_total 和 aisix_tokens_consumed_total 等序列。
AISIX 使用 aisix_ 前缀输出原生指标名称。使用直方图序列计算跨网关实例的延迟百分位数,并使用请求计数器分析成功率和路由情况。精确指标名称、标签范围和 PromQL 示例请参见指标参考。
通过 observability.metrics.labels 可以选择各指标族输出的标签。配置示例、默认值和完整变量列表参见指标标签与变量。
区分请求计数与尝试计数
请求是一次调用方交互。重试或故障转移可能让一个请求产生多次用量事件尝试。部分尝试会在目标级限流或请求组装阶段停止,尚未调用模型服务提供方,因此 AISIX 在不同信号中对尝试的计量方式也不同:
| 单位 | 统计位置 | 一个样本或一行代表什么 |
|---|---|---|
| 请求 | aisix_proxy_requests_total、aisix_llm_requests_total | 一次客户端请求,状态是请求最终结束时的状态。对流式响应而言,这是流结束时的状态,可能与流开始时调用方收到的 200 不同。 |
| 尝试 | aisix_deployment_requests_total 及部署指标族 | 对某一个目标模型的一次上游调用。 |
| 发出尝试 | aisix_usage_events_emitted_total | 一次用量事件的发出 尝试,在投递队列接受或拒绝它之前计数。 |
| 尝试 | 用量事件记录,以及基于其构建的用量日志 | 一次已记录的处理尝试,包括在上游调用前停止的尝试。同一请求的各次尝试共享 request_id,并按 attempt_index 排序。 |
如果某个目标返回 502,而后备目标成功,请求计数器只记录最终返回给调用方的 200。部署计数器和用量事件则会保留失败的尝试。因此,用量日志中的 5xx 尝试数可能远高于请求指标;两者计量的单位不同。
请按各查询真正回答的问题选用:
# 最终以服务端错误结束的请求——调用方实际经历的情况。
sum(increase(aisix_proxy_requests_total{status=~"5.."}[24h]))
# 发生过故障转移、但最终仍以服务端错误结束的请求。
sum(increase(aisix_proxy_requests_total{status=~"5..", is_fallback="true"}[24h]))
# 失败的上游尝试,按目标聚合——包含后续被故障转移救回的那些。
# 这是 5xx 用量日志行数在尝试层面的对应视图,范围限于通过模型组下发的端点。
sum(increase(aisix_deployment_failure_responses_total[24h])) by (model)
# 成功救回请求的故障转移,按模型组和实际到达的目标聚合。
sum(increase(aisix_routing_successful_fallbacks_total[24h])) by (model, fallback_model)
# 用量事件的发出尝试,以及被交接队列拒绝的事件。
sum(increase(aisix_usage_events_emitted_total{status_code="5xx"}[24h]))
sum(increase(aisix_usage_event_drops_total[24h]))
# 某个成员被限流拒绝的次数。`status` 携带原始 HTTP 状态码,
# 因此无需扫描整个状态族即可定位单一故障模式。
sum(increase(aisix_usage_events_emitted_total{user_id="<member-id>", status="429"}[24h]))
# 哪些队列交接被拒绝了。队列侧的 reason 与发出计数器携带相同的模型与
# Provider Key 标签,因此该差值在按模型的粒度上同样成立,而不只是总量。
sum(increase(aisix_usage_event_drops_total{reason=~"sink_.*"}[24h])) by (model, provider_key_name)
# 网关已记录但未能投递到控制面的用量。这些样本只携带成员标签,
# 因此按成员分组,而不是按模型分组。
sum(increase(aisix_usage_event_drops_total{reason=~"send_failed|retry_budget_exhausted"}[24h])) by (reason, user_name)
比较相同的数据范围
在将两个总数视为不一致之前,请先检查它们的覆盖范围:
| 差异 | 原因 | 检查方法 |
|---|---|---|
| 抓取覆盖范围 |