指标参考
AISIX 以 Prometheus 文本格式公开运行指标。Prometheus 服务器或其他兼容采集器可抓取这些指标,用于仪表盘、告警和 PromQL 查询。
默认在专用监听器上启用 Prometheus 指标。默认启动配置如下:
observability:
metrics:
prometheus:
enabled: true
addr: 0.0.0.0:9090
path: /metrics
Prometheus 从此监听器抓取 GET /metrics。
指标端点按设计不需要认证。请确保该监听器仅对监控网络开放。
每次抓取端点时,AISIX 都会公开配置状态。其他指标系列会在 AISIX 首次记录相应活动时注册,因此流量指标可能不会在启动后立即出现。请通过代理发送请求,然后再次抓取,即可看到相应序列。
下方目录列出默认标签。有关按指标增减标签的配置及所有支持的变量,参见指标标签与变量。
指标目录
搜索指标名称、描述、标签和值,或按指标系列和类型筛选目录。 展开条目即可查看详细信息。
- 指标
- 85
- 系列
- 12
指标类型
持续累加并在进程重启前只增不减的值,例如请求总数或 Token 总数。使用 rate() 计算其变化速率。
可增可减的当前值,例如活跃请求数或剩余配额。
按可配置分桶统计的观测值。计算百分位数前,可以聚合 _bucket、_sum 和 _count 序列。
由各网关实例计算分位数的观测值。摘要也公开 _sum 和 _count,但其分位数无法跨实例聚合。
请求指标
跟踪请求结果以及代理当前正在处理的工作。
详细请求标签
所有面向客户端的路由都会记录本族:模型端点、/v1/models、OAuth protected-resource 发现文档、MCP、A2A 及其 Agent Card、文件、批处理和微调路由、realtime 会话,以及透传路由。网关在认证阶段以 401 或 403 拒绝的请求同样计入,model="unresolved",覆盖以这种方式认证调用方的所有路由:模型端点、/v1/models、文件、批处理和微调路由、MCP 和 A2A。/livez 和 /readyz 探针不计入。/v1/models、发现文档、Agent Card 和认证拒绝,1.7.1 及更早版本不计入。
本族的每个计数器都是每次客户端请求采样一次,其 status 是请求最终结束时的状态。对流式响应而言,这是流结束时的状态——调用方中途离开为 499,上游中断或超时为 502 或 504——并且样本在流结束时采集,因此在一批长流进行期间,rate() 会滞后大约一个流的时长。1.5.0 及更早版本在响应开始时以调用方收到的 200 对流式请求采样,透传路由除外。第一个目标失败、随后由回退目标成功处理的请求,在这里只是一个 status="200" 样本;它所恢复的那次失败在本族中完全没有体现。统计上游尝试请使用部署指标,查看单次尝试请使用用量日志。
对于三个详细请求计数器,stream 记录客户端是否请求流式响应。is_fallback 记录请求是否由回退目标处理,并且不会出现在延迟指标中。
provider_key_name 和 user_name 是对应 ID 的可读名称。每个名称与其 ID 一一对应,因此不会增加新的序列维度。在控制面提供名称前,user_name 为 unknown。
详细请求计数器还支持 api_key_name 和 team_name,即认证所用 API Key 及其团队的显示名称。二者都不是默认标签:需将其加入 observability.metrics.labels 中该指标族的标签列表。没有显示名称的 API Key、或网关尚未收到其名称的团队,报告为 unknown;重命名会产生新的序列。1.5.0 及更早版本不输出该标签。
失败请求与成功请求携带相同的 provider、upstream_model 和 Provider Key 标签,因此仅凭本族指标即可计算按 Provider 或按 Provider Key 的失败率。这些上游标签记录请求最后选定的目标:在重试或回退场景下,即调用方最终收到其错误的那次尝试。只有当请求从未选定任何目标时它们才为 unknown,例如模型不存在、被输入护栏拦截、被预算拒绝,或请求体在派发前即被拒绝。
inbound_protocol 是由标准化端点推导出的有界协议类型集合。Anthropic 协议端点报告 anthropic;/mcp、/a2a 及 A2A Agent Card、/v1/realtime 和 /passthrough_route 分别报告 mcp、a2a、realtime 和 passthrough;其余网关端点报告 openai。在途请求仪表使用相同的值。
upstream_protocol 是该协议对的另一半:AISIX 与实际处理该请求的上游通信时所使用的协议。它按照与请求转发相同的规则从所选目标的 Provider Key 解析得出,因此报告的是请求实际被转换成的传输格式——openai、anthropic、bedrock、vertex 或 azure-openai;当请求完全没有选中上游时报告 unknown。同时按两个标签分组即可区分原生流量与跨协议转换流量,参见区分跨协议转换流量。
请勿用 provider 代替 upstream_protocol。provider 是开放的厂商字符串,同一厂商可以通过不同的适配器接入,因此从厂商名到协议的 PromQL 映射需要手工维护,并且会对所有自定义厂商和 OpenAI 兼容厂商给出错误结果。
endpoint 始终是标准化的路由模板,而不是原始请求路径。带路径参数的路由会合并为一条序列,例如 /v1/batches/:id、/v1/videos/:id 和 /mcp/{server};/passthrough/ 下的路径使用 /passthrough_route,无法识别的路径报告为 other。两个发现文档分别为 /.well-known/oauth-protected-resource 和 /.well-known/oauth-protected-resource/mcp;A2A Agent Card 为 /a2a/{agent}/.well-known/agent-card.json,与 /a2a 的 Agent 调用分开。
aisix_requests_total 。描述:兼容性序列中的代理请求结果,覆盖的端点范围最广。 。类型:counter 。标签数量:4 个标签
标签
provider, model, status, outcomeoutcome 的值
success, client_error, rate_limited, upstream_errorsuccess 表示 HTTP 200–399;client_error 表示除 429 外的 HTTP 400–499;rate_limited 表示所有 HTTP 429(网关限流、预算拒绝或上游自己返回的 429);其他所有状态均映射为 upstream_error。
行为
A2A Agent 调用使用 provider="a2a" 和 model="a2a"。
PromQL 示例
sum(rate(aisix_requests_total[5m])) by (outcome)aisix_llm_requests_total 。描述:模型推理请求的结果,包括成功和失败的请求。 。类型:counter 。标签数量:16 个标签
标签
endpoint, inbound_protocol, upstream_protocol, provider, model, upstream_model, provider_key_id, provider_key_name, api_key_id, team_id, user_id, user_name, stream, is_fallback, status, outcomeinbound_protocol 的值
openai, anthropic, realtime, passthroughupstream_protocol 的值
openai, anthropic, bedrock, vertex, azure-openai, unknown网关与上游通信所使用的协议,与 inbound_protocol 相互独立。unknown 表示该请求没有选中任何上游——在转发前被拒绝,或是不调用模型的路由。
stream 的值
false, trueis_fallback 的值
false, trueoutcome 的值
success, client_error, rate_limited, upstream_errorsuccess 表示 HTTP 200–399;client_error 表示除 429 外的 HTTP 400–499;rate_limited 表示所有 HTTP 429(网关限流、预算拒绝或上游自己返回的 429);其他所有状态均映射为 upstream_error。
行为
覆盖调用模型的端点:聊天补全、补全、消息、Token 计数、响应、向量嵌入、重排序、/v1/systemone 和 /v1/decisions、音频、图像生成和编辑、视频和 realtime 会话。未调用模型的请求只计入 aisix_proxy_requests_total,包括 MCP 工具调用、A2A Agent 调用和 Agent Card、不透明的透传中继、文件、批处理和微调管理路由、/v1/models,以及 OAuth 发现文档。
当 AISIX 把透传路由请求的协议识别为某个模型端点所服务的协议(聊天、Anthropic Messages、响应、补全、向量嵌入、图像生成或编辑、重排序)时,该请求会以 endpoint="/passthrough_route" 计入此处。其 model 是请求正文中的 model 归一到已配置模型名称后的值,未命中任何模型时为 unresolved,正文没有 model 时为 unknown;其 upstream_model 为 unknown。同一 model 也用于它在代理请求指标族中的样本。其他透传请求(包括 DashScope 原生正文)只计入代理指标族,model="passthrough"。1.6.0 及更早版本不发射,它们把所有透传请求只计入代理指标族。
在分发前被拒绝的请求(例如请求体过大)会计入其目标端点,因此端点成功率的分母包括这些失败。
aisix_proxy_requests_total 。描述:所有代理流量(包括模型推理和其他流量)的详细请求结果。 。类型:counter 。标签数量:16 个标签
标签
endpoint, inbound_protocol, upstream_protocol, provider, model, upstream_model, provider_key_id, provider_key_name, api_key_id, team_id, user_id, user_name, stream, is_fallback, status, outcomeinbound_protocol 的值
openai, anthropic, mcp, a2a, realtime, passthroughupstream_protocol 的值
openai, anthropic, bedrock, vertex, azure-openai, unknown网关与上游通信所使用的协议,与 inbound_protocol 相互独立。unknown 表示该请求没有选中任何上游——在转发前被拒绝,或是不调用模型的路由。
stream 的值
false, trueis_fallback 的值
false, trueoutcome 的值
success, client_error, rate_limited, upstream_errorsuccess 表示 HTTP 200–399;client_error 表示除 429 外的 HTTP 400–499;rate_limited 表示所有 HTTP 429(网关限流、预算拒绝或上游自己返回的 429);其他所有状态均映射为 upstream_error。
行为
每次客户端请求采样一次,携带请求最终结束时的状态。请求内部的重试和故障转移不会增加样本,因此这个计数器回答的是「调用方发起了多少请求、各自如何结束」,而不是「网关向上游发起了多少次调用」。
aisix_proxy_failed_requests_total 。描述:结果不为 success 的代理请求子集。 。类型:counter 。标签数量:16 个标签
标签
endpoint, inbound_protocol, upstream_protocol, provider, model, upstream_model, provider_key_id, provider_key_name, api_key_id, team_id, user_id, user_name, stream, is_fallback, status, outcomeinbound_protocol 的值
openai, anthropic, mcp, a2a, realtime, passthroughupstream_protocol 的值
openai, anthropic, bedrock, vertex, azure-openai, unknown网关与上游通信所使用的协议,与 inbound_protocol 相互独立。unknown 表示该请求没有选中任何上游——在转发前被拒绝,或是不调用模型的路由。
stream 的值
false, trueis_fallback 的值
false, trueoutcome 的值
client_error, rate_limited, upstream_errorclient_error 表示除 429 外的 HTTP 400–499;rate_limited 表示所有 HTTP 429(网关限流、预算拒绝或上游自己返回的 429);其他所有状态均映射为 upstream_error。
aisix_proxy_in_flight_requests 。描述:代理当前正在处理的请求,按标准化端点和入站协议分组。 。类型:gauge 。标签数量:2 个标签
标签
endpoint, inbound_protocolinbound_protocol 的值
openai, anthropic, mcp, a2a, realtime, passthrough行为
MCP 请求使用 inbound_protocol="mcp";聚合网关使用 endpoint="/mcp",按服务器划分的端点使用 endpoint="/mcp/{server}"。A2A 调用使用 endpoint="/a2a" 和 inbound_protocol="a2a"。获取 Agent Card 使用 endpoint="/a2a/{agent}/.well-known/agent-card.json";1.7.1 及更早版本将其报告为 endpoint="/a2a"。
标准化为 endpoint="/passthrough_route" 的请求使用 inbound_protocol="passthrough"。
PromQL 示例
sum(aisix_proxy_in_flight_requests) by (endpoint, inbound_protocol)aisix_proxy_client_cancelled_requests_total 。描述:调用方在网关发送响应头前断开连接的请求。 。类型:counter 。标签数量:4 个标签
标签
endpoint, model, provider_key_id, provider_key_name行为
这些请求不会产生正常结果,因此不会出现在其他请求计数器中。网关会在此处记录它们,并在访问日志中以状态码 499 记录。
该指标速率上升通常意味着调用方在等待首个 Token 时放弃。可按 model 拆分该序列,并与同一模型的 aisix_llm_time_to_first_token_seconds 对比。
model 是调用方请求的模型,Provider Key 标签标识请求当时正在等待的目标。若调用方在网关解析出它们之前就断开连接(例如仍在上传请求体时),这三个标签均为 unknown。
本指标刻意不包含其他请求计数器的调用方身份、状态码和结果标签。被取消的请求没有状态码,通常也 没有团队或用户信息,这些维度在每个样本上都会是 unknown。
调用方在响应头发送后断开连接的情况不计入此处。该请求已经产生正常结果和用量事件。
PromQL 示例
sum(rate(aisix_proxy_client_cancelled_requests_total[5m])) by (endpoint, model)aisix_proxy_request_body_limit_rejections_total 。描述:因超过 proxy.request_body_limit_bytes 而被拒绝的请求,按网关结束读取被拒绝请求体的方式分组。 。类型:counter 。标签数量:3 个标签
标签
endpoint, inbound_protocol, outcomeinbound_protocol 的值
openai, anthropic, mcp, a2a, realtime, passthroughoutcome 的值
completed, cap_reached, timeout, client_read_errorcompleted 表示调用方发送了声明的完整请求体,因此可以读取 413 响应。cap_reached 和 timeout 表示网关先停止接收请求体;client_read_error 表示调用方在发送请求体时断开连接。这三种情况下,调用方通常会看到连接关闭,而不是收到响应。
行为
网关会读取并丢弃被拒绝请求的请求体,以便调用方在同一连接上接收 413。该读取操作有上限,outcome 用于报告其结束方式。
除 completed 外,任何结果的占比上升都表示调用方看到的是连接关闭,而不是 413 响应。匹配的 aisix::body_limit 日志条目会记录同一 request_id 的声明大小、配置上限和已读取字节数。
这里只统计声明的 Content-Length 超过上限的请求。采用分块传输且超过上限的请求会在读取时被拒绝,没有可比的 outcome,并以状态码 413 出现在 aisix_requests_total 中。
PromQL 示例
sum(rate(aisix_proxy_request_body_limit_rejections_total[5m])) by (endpoint, inbound_protocol, outcome)aisix_auth_decisions_total 。描述:API Key、JWT 和缺少凭证路径上的调用方身份认证决策。 。类型:counter 。标签数量:3 个标签
标签
method, result, reasonmethod 的值
api_key, jwt, noneresult 的值
allowed, denied行为
允许请求的 reason 为 none。被拒绝请求使用有限集合中的原因,例如 missing_credentials、unknown_key、key_expired、jwt_bad_signature、jwt_untrusted_issuer 或 jwt_identity_unmapped。
PromQL 示例
sum(rate(aisix_auth_decisions_total{result="denied"}[5m])) by (method, reason)延迟指标
检查单个网关的延迟,或跨网关实例聚合直方图分桶。
延迟聚合与标签
跨网关实例的服务级仪表盘和告警应使用直方图,因为可在调用 histogram_quantile() 前聚合其 _bucket、_sum 和 _count 序列。摘要用于检查单个网关实例预先计算的分位数。摘要分位数无法跨实例聚合,因此不要对其取平均值。
每个直方图都有自己的分桶边界,因为两种分布不同:端到端延迟从毫秒级开始,而首个 Token 时间不可能快于生成 Token 的上游。两组边界均可配置。env_id 是已配置的环境 ID:AISIX Enterprise 和 AISIX Cloud 会为托管网关设置它,通过 etcd 配置的 AISIX OSS 网关也可以显式设置;未设置时其值为 unknown。status_class 为 2xx、3xx、4xx、5xx 或 other。为控制分桶序列数量,不包含按密钥和按用户的标签;这些维度请使用用量分析。
两个耗时摘要、aisix_llm_time_to_first_token_seconds 和两个直方图,在 observability.metrics.labels 中加入该指标族的标签列表后,还支持 api_key_name 和 team_name,即认证所用 API Key 及其团队的显示名称。二者都不是默认标签。没有显示名称的 API Key、或网关尚未收到其名称的团队,报告为 unknown;重命名会产生新的序列。1.5.0 及更早版本不输出该标签。
aisix_request_duration_seconds 。描述:兼容性序列中各代理端点的请求持续时间。流式 HTTP 响应 记录整个流,并以流结束时的状态记录;1.5.0 及更早版本只记录到响应开始为止。realtime 记录 WebSocket 会话关闭前的完整持续时间。 。类型:summary 。标签数量:3 个标签
标签
provider, model, status行为
摘要分位数由各 AISIX 实例计算,无法跨实例聚合。
aisix_llm_request_duration_seconds 。描述:模型推理端点的详细请求持续时间。流式 HTTP 响应记录整个流,并以流结束时的状态记录;1.5.0 及更 早版本只记录到响应开始为止。realtime 记录 WebSocket 会话关闭前的完整持续时间。 。类型:summary 。标签数量:15 个标签
标签
endpoint, inbound_protocol, upstream_protocol, provider, model, upstream_model, provider_key_id, provider_key_name, api_key_id, team_id, user_id, user_name, stream, status, outcomeinbound_protocol 的值
openai, anthropic, realtime, passthroughupstream_protocol 的值
openai, anthropic, bedrock, vertex, azure-openai, unknown网关与上游通信所使用的协议,与 inbound_protocol 相互独立。unknown 表示该请求没有选中任何上游——在转发前被拒绝,或是不调用模型的路由。
stream 的值
false, trueoutcome 的值
success, client_error, rate_limited, upstream_errorsuccess 表示 HTTP 200–399;client_error 表示除 429 外的 HTTP 400–499;rate_limited 表示所有 HTTP 429(网关限流、预算拒绝或上游自己返回的 429);其他所有状态均映射为 upstream_error。
aisix_proxy_request_duration_seconds 。描述:所有代理流量的详细请求持续时间。流式 HTTP 响应记录整个流,并以流结束时的状态记录;1.5.0 及更早版本只记录到响应开始为止。realtime 记录 WebSocket 会话关闭前的完整持续时间。 。类型:summary 。标签数量:15 个标签
标签
endpoint, inbound_protocol, upstream_protocol, provider, model, upstream_model, provider_key_id, provider_key_name, api_key_id, team_id, user_id, user_name, stream, status, outcomeinbound_protocol 的值
openai, anthropic, mcp, a2a, realtime, passthroughupstream_protocol 的值
openai, anthropic, bedrock, vertex, azure-openai, unknown网关与上游通信所使用的协议,与 inbound_protocol 相互独立。unknown 表示该请求没有选中任何上游——在转发前被拒绝,或是不调用模型的路由。
stream 的值
false, trueoutcome 的值
success, client_error, rate_limited, upstream_errorsuccess 表示 HTTP 200–399;client_error 表示除 429 外的 HTTP 400–499;rate_limited 表示所有 HTTP 429(网关限流、预算拒绝或上游自己返回的 429);其他所有状态均映射为 upstream_error。
aisix_llm_time_to_first_token_seconds 。描述:每个流式响应到首个流式帧的时间,包括聊天补全、消息和响应,流式音频转录和翻译,流式 A2A 调用,以及透传路由的流。side 标签(1.4.0 及更早版本不发射)区分上游区间与客户端实际等待的区间。 。类型:summary 。标签数量:13 个标签
标签
side, endpoint, inbound_protocol, upstream_protocol, provider, model, upstream_model, provider_key_id, provider_key_name, api_key_id, team_id, user_id, user_nameside 的值
upstream, downstreamupstream 是从服务该请求的那次尝试开始,到上游第一个帧(任意类型)的时间。downstream 是客户端实际等待的时间:从网关收到请求,到写给客户端的第一个帧。始终输出,标签选择无法删除它。1.4.0 及更早版本不发射该标签,它们只记录上游区间,且不带 side 标签。
inbound_protocol 的值
openai, anthropic, a2a, passthrough1.7.1 及更早版本不发射 a2a。
upstream_protocol 的值
openai, anthropic, bedrock, vertex, azure-openai, unknown网关与上游通信所使用的协议,与 inbound_protocol 相互独立。unknown 表示该请求没有选中任何上游——在转发前被拒绝,或是不调用模型的路由。
行为
1.4.0 及更早版本不发射 side 标签。不按 side 过滤的查询会混合两个区间,因此查看上游视角时请使用 side!="downstream"。不要使用 side="upstream":它匹配不到 1.4.0 及更早版本网关的任何序列,会在混合版本的集群中悄悄漏掉这些网关。
downstream 区间涵盖请求解析、输入安全护栏、失败的尝试及其退避等待,以及输出安全护栏的扣留。对于首次尝试即成功的请求,downstream 减去 upstream 就是网关侧的工作,通常是安全护栏;对于发生过重试的请求,差值还包含之前的尝试。
downstream 观测是 upstream 观测的子集。在首个帧到达客户端之前被输出安全护栏阻断的流,或在扣留期间被放弃的流,只会记录 upstream 观测。
在非 Anthropic 上游的 /v1/messages 和聊天协议上游的 /v1/responses 上,客户端收到的第一个帧是第一个携带内容的事件。这时 downstream 区间还包含等待该事件的时间,对推理型上游而言就是它的思考时间。
透传路由的流以 endpoint="/passthrough_route" 记录:被 AISIX 识别出协议的回复(1.6.0 及更早版本不记录),以及计时到首个字节帧的不透明中继(1.7.1 及更早版本不记录)。
流式音频转录和翻译,以及流式 A2A 调用(endpoint="/a2a"),1.7.1 及更早版本不记录。非流式响应不会在此记录;/v1/audio/speech 的分块音频正 文不是 Token 流,同样不记录;realtime 会话也不记录。
aisix_request_e2e_latency_seconds 。描述:请求指标所统计的每个请求的端到端延迟,包括完整的流式传输时长,realtime 会话除外。 。类型:histogram 。标签数量:7 个标签
标签
side, env_id, endpoint, model, provider, status_class, streamingside 的值
upstream, downstreamdownstream 是该标签出现之前本直方图一直记录的客户端感知延迟。upstream 是产生该响应的那次尝试的上游耗时,与该尝试的用量事件字段 upstream_latency_ms 是同一个数值。始终输出,标签选择无法删除它。1.4.0 及更早版本不发射该标签,它们只记录 downstream 数值,且不带 side 标签。
status_class 的值
2xx, 3xx, 4xx, 5xx, otherstreaming 的值
false, true行为
默认分桶范围为 5 毫秒到 600 秒,可通过 observability.metrics.buckets.request_e2e_latency 配置。较低边界用于记录缓存命中和分发前被拒绝的请求等快速响应。跨网关实例计算百分位数前,请先聚合 _bucket 序列。
downstream 一侧在所有记录请求指标的路由上记录,endpoint 相同:模型端点、/v1/models、OAuth 发现文档、MCP、A2A 及其 Agent Card、文件、批处理和微调路由,以及透传路由,包括在认证阶段或下发之前被拒绝的请求。/v1/realtime 例外:WebSocket 会话没有可计时的请求与响应。1.7.1 及更早版本只记录聊天补全、消息、响应、A2A 调用,以及协议被识别为这三种之一的透传路由请求。
每个请求只观测一次。非流式请求和失败请求在处理程序返回时记录。流式请求在流结束时记录,包括客户端取消的情况;取消的流记录 499 和截至取消时的时长,上游中断或超时的流记录其 502 或 504。在响应头发出之前就断开的调用方只计入 aisix_proxy_client_cancelled_requests_total,不在此记录。/v1/videos/:id/content 在视频正文转发给客户端完毕时记录,状态为其响应头的状态。1.5.0 及更早版本对多数被取消或失败的 chat、messages、responses 流记录 2xx 状态类。
A2A 调用使用 endpoint="/a2a",记录 Agent 调用的完整时长,包含完整的流;被放弃的 A2A 流在 4xx 状态类中记录为 499。1.7.1 及更早版本对已进入 A2A 统计、但在下发之前被拒绝的调用记录零时长,在进入 A2A 统计之前就被拒绝的调用则不记录。
1.4.0 及更早版本不发射 side 标签。上述观测均为 side="downstream"。不按 side 过滤的查询会混合两侧,上游样本会拉低其百分位数,因此查看客户端感知延迟时请使用 side!="upstream":它同样能匹配 1.4.0 及更早版本网关不带标签的序列。这与 TTFT 指标相反,TTFT 的上游视角使用 side!="downstream"。
每个请求最多记录一次 side="upstream" 观测,除 side 外其标签与 downstream 观测相同。它测量产生该响应的那次尝试,从尝试开始直到上游完成:完整收到响应,或者对流式请求而言上游流结束。只要那次尝试到达了上游就会记录,包括上游错误和超时;在 /a2a 上,这次尝试就是对 Agent 的调用。缓存命 中、在下发之前失败的请求、合议模型,以及不报告任何尝试的路由(例如 /v1/models、发现文档、视频状态查询和内容下载请求)只记录 downstream 一侧。1.7.1 及更早版本对 A2A 调用也只记录 downstream 一侧。更早失败的尝试及其重试退避只包含在 downstream 数值中。
PromQL 示例
histogram_quantile(
0.90,
sum by (le) (rate(aisix_request_e2e_latency_seconds_bucket{side!="upstream"}[5m]))
)aisix_request_ttft_seconds 。描述:每个流式响应到首个流式帧的时间,包括聊天补全、消息和响应,流式音频转录和翻译,流式 A2A 调用,以及透传路由的流。side 标签(1.4.0 及更早版本不发射)区分上游区间与客户端实际等待的区间。 。类型:histogram 。标签数量:7 个标签
标签
side, env_id, endpoint, model, provider, status_class, streamingside 的值
upstream, downstreamupstream 是从服务该请求的那次尝试开始,到上游第一个帧(任意类型)的时间。downstream 是客户端实际等待的时间:从网关收到请求,到写给客户端的第一个帧。始终输出,标签选择无法删除它。1.4.0 及更早版本不发射该标签,它们只记录上游区间,且不带 side 标签。
status_class 的值
2xx, 3xx, 4xx, 5xx, otherstreaming 的值
true行为
在 upstream 一侧,即使上游首帧不携带任何可见的生成输出——例如仅包含角色的起始帧或 Anthropic 的 message_start 事件 ——它也会停止计时。内容帧、推理帧和工具调用帧同样会停止计时。
1.4.0 及更早版本不发射 side 标签。不按 side 过滤的查询会混合两个区间,因此查看上游视角时请使用 side!="downstream"。不要使用 side="upstream":它匹配不到 1.4.0 及更早版本网关的任何序列,会在混合版本的集群中悄悄漏掉这些网关。
downstream 区间涵盖请求解析、输入安全护栏、失败的尝试及其退避等待,以及输出安全护栏的扣留。对于首次尝试即成功的请求,downstream 减去 upstream 就是网关侧的工作,通常是安全护栏;对于发生过重试的请求,差值还包含之前的尝试。
downstream 观测是 upstream 观测的子集。在首个帧到达客户端之前被输出安全护栏阻断的流,或在扣留期间被放弃的流,只会记录 upstream 观测。
在非 Anthropic 上游的 /v1/messages 和聊天协议上游的 /v1/responses 上,客户端收到的第一个帧是第一个携带内容的事件。这时 downstream 区间还包含等待该事件的时间,对推理型上游而言就是它的思考时间。
透传路由的流以 endpoint="/passthrough_route" 记录:被 AISIX 识别出协议的回复(1.6.0 及更早版本不记录),以及计时到首个字节帧的不透明中继(1.7.1 及更早版本不记录)。
流式音频转录和翻译,以及流式 A2A 调用(endpoint="/a2a"),1.7.1 及更早版本不记录。非流式响应不会在此记录;/v1/audio/speech 的分块音频正文不是 Token 流,同样不记录;realtime 会话也不记录。
默认分桶范围为 50 毫秒到 300 秒, 可通过 observability.metrics.buckets.request_ttft 配置。当附近的模型服务器可以在 50 毫秒内生成输出时,请降低起始边界。只使用托管服务提供方的部署可以提高下限,移除始终为空的分桶。
PromQL 示例
# 上游 P90 TTFT;同样匹配 1.4.0 及更早版本的网关
histogram_quantile(
0.90,
sum by (le) (rate(aisix_request_ttft_seconds_bucket{side!="downstream"}[5m]))
)
# 客户端侧 P90 TTFT,用于与上游 P90 对比
histogram_quantile(
0.90,
sum by (le) (rate(aisix_request_ttft_seconds_bucket{side="downstream"}[5m]))
)用量与成本指标
测量 Token 用量和标准化客户端用量。
哪些端点报告 Token
所有从上游接收 Token 数量的端点都会在此记录,包括聊天补全、补全、消息、响应、向量嵌入、重排序、/v1/systemone 和 /v1/decisions、音频转录和翻译路由、图像生成和编辑,以及 realtime 会话。
/a2a 记录网关对 message/send 和 message/stream 调用消息文本自行统计的 Token 数,即其用量事件以 usage_estimated: true 标记的数值,处理方式与聊天补全记录的估算值相同,且只在 Agent 实际收到调用时记录。1.7.1 及更早版本不发射。
/v1/messages/count_tokens 不消耗 Token,不在此记录;MCP 工具调用、不透明的透传中继、文件和微调路由同样不记录。批处理结果也不记录:已完成批处理的用量事件仍携带其 Token,但没有任何机制能保证一个批处理在多个网关副本和重启之间只被统计一次。
透传路由同样会在此以 endpoint="/passthrough_route" 记录 Token:适用于协议被 AISIX 识别为上述端点之一(聊天、Anthropic Messages、响应、补全、向量嵌入、图像生成或编辑、重排序)的请求,并按该端点的方式读取。其 model 是请求正文中的 model 归一到已配置模型名称后的值,或 unresolved。1.6.0 及更早版本不发射。
有两个模型推理端点不会报告 Token,因为其计费方式不同:/v1/audio/speech 按输入字符计费,/v1/videos 按视频计费。两者仍计为请求,因此只能在同一 endpoint 内用 Token 总数除以请求数,不能跨全部端点计算。
逐请求 Token 序列(三个 aisix_llm_*_tokens_total 计数器)使用与详细请求计数器相同的标签,因此查询可基于 endpoint、model、provider 和调用方身份标签关联 Token 用量与请求结果。另两个指标的标签不同:aisix_tokens_consumed_total 仅按 provider 和 model 标记;aisix_llm_tokens_by_client_total 仅按 client_type、model 和 token_type 标记。
携带调用方身份的 Token 和缓存 Token 计数器还支持 api_key_name 和 team_name,即认证所用 API Key 及其团队的显示名称。二者都不是默认标签:需将其加 入 observability.metrics.labels 中该指标族的标签列表。没有显示名称的 API Key、或网关尚未收到其名称的团队,报告为 unknown;重命名会产生新的序列。1.5.0 及更早版本不输出该标签。
另有三个计数器单独统计上游服务商用自身提示词缓存提供的 Token。它们与上述 Token 计数器使用相同的标签,且仅在取值非零时才创建序列,因此不报告缓存明细的服务商不会产生任何序列。它们描述的是**上游服务商**的缓存,而不是 AISIX 响应缓存——后者是缓存指标中的 aisix_cache_requests_total,两者互不相关。
各服务商对缓存读取采用两种不同的计量口径,因此读取侧有两个计数器而非一个。aisix_llm_cached_input_tokens_total 对应 OpenAI 口径:缓存命中的 Token 本身就属于上报的提示词 Token,因此已经包含在 aisix_llm_input_tokens_total 之内。aisix_llm_cache_read_input_tokens_total 和 aisix_llm_cache_creation_input_tokens_total 对应 Anthropic 口径:它们与输入 Token 并列上报而非包含其中,因此位于 aisix_llm_input_tokens_total 之外、aisix_llm_total_tokens_total 之内。
把两种口径分开正是跨协议查询能够成立的原因:请求实际消耗的输入为 aisix_llm_input_tokens_total + aisix_llm_cache_read_input_tokens_total + aisix_llm_cache_creation_input_tokens_total,其中由缓存提供的部分为 aisix_llm_cached_input_tokens_total + aisix_llm_cache_read_input_tokens_total。这两个表达式对任一服务商口径都成立。参见计算提示词缓存命中率。
aisix_tokens_consumed_total 。描述:所有报告 Token 用量的端点的 Token 总数,属于覆盖范围最广的兼容性序列。 。类型:counter 。标签数量:2 个标签
标签
provider, modelaisix_llm_input_tokens_total 。描述:AISIX 归因到该请求的输入 Token 数。对于模型端点,AISIX 会将服务提供方上报的用量标准化,并估算缺失的数量。Dev 版本根据请求文本估算 A2A 输入 Token;1.7.1 版本不发射 A2A Token 计数器。 。类型:counter 。标签数量:12 个标签
标签
endpoint, inbound_protocol, upstream_protocol, provider, model, upstream_model, provider_key_id, provider_key_name, api_key_id, team_id, user_id, user_nameinbound_protocol 的值
openai, anthropic, realtime, passthrough, a2a1.7.1 及更早版本不发射 a2a。
upstream_protocol 的值
openai, anthropic, bedrock, vertex, azure-openai, unknown网关与上游通信所使用的协议,与 inbound_protocol 相互独立。unknown 表示该请求没有选中任何上游——在转发前被拒绝,或是不调用模型的路由。
aisix_llm_output_tokens_total 。描述:AISIX 归因到该请求的输出 Token 数。对于模型端点,AISIX 会将服务提供方上报的用量标准化,并估算缺失的数量。Dev 版本根据响应文本估算 A2A 输出 Token;1.7.1 版本不发射 A2A Token 计数器。 。类型:counter 。标签数量:12 个标签
标签
endpoint, inbound_protocol, upstream_protocol, provider, model, upstream_model, provider_key_id, provider_key_name, api_key_id, team_id, user_id, user_nameinbound_protocol 的值
openai, anthropic, realtime, passthrough, a2a1.7.1 及更早版本不发射 a2a。
upstream_protocol 的值
openai, anthropic, bedrock, vertex, azure-openai, unknown网关与上游通信所使用的协议,与 inbound_protocol 相互独立。unknown 表示该请求没有选中任何上游——在转发前被拒绝,或是不调用模型的路由。
aisix_llm_total_tokens_total 。描述:AISIX 归因到该请求、包含缓存 Token 的总数。对于模型端点,AISIX 会将服务提供方上报的用量标准化,并估算缺失的数量。Dev 版本根据请求和响应文本估算 A2A Token 总数;1.7.1 版本不发射 A2A Token 计数器。 。类型:counter 。标签数量:12 个标签
标签
endpoint, inbound_protocol, upstream_protocol, provider, model, upstream_model, provider_key_id, provider_key_name, api_key_id, team_id, user_id, user_nameinbound_protocol 的值
openai, anthropic, realtime, passthrough, a2a1.7.1 及更早版本不发射 a2a。
upstream_protocol 的值
openai, anthropic, bedrock, vertex, azure-openai, unknown网关与上游通信所使用的协议,与 inbound_protocol 相互独立。unknown 表示该请求没有选中任何上游——在转发前被拒绝,或是不调用模型的路由。
aisix_llm_cached_input_tokens_total 。描述:上游用其提示词缓存提供、并计入提示词 Token 数量的输入 Token。 。类型:counter 。标签数量:12 个标签
标签
endpoint, inbound_protocol, upstream_protocol, provider, model, upstream_model, provider_key_id, provider_key_name, api_key_id, team_id, user_id, user_nameinbound_protocol 的值
openai, anthropic, realtime, passthroughupstream_protocol 的值
openai, anthropic, bedrock, vertex, azure-openai, unknown网关与上游通信所使用的协议,与 inbound_protocol 相互独立。unknown 表示该请求没有选中任何上游——在转发前被拒绝,或是不调用模型的路由。
行为
OpenAI 计量口径:OpenAI 及 OpenAI 兼容服务商的 prompt_tokens_details.cached_tokens、DeepSeek 的 prompt_cache_hit_tokens、Vertex AI 上 Gemini 的 cachedContentTokenCount。这些 Token 已计入 aisix_llm_input_tokens_total,两者相加会重复计算。
仅在上游报告该字段时记录。AISIX 不会依据响应耗时或提示词相似度推断缓存命中。
aisix_llm_cache_read_input_tokens_total 。描述:上游用其提示词缓存提供、并与输入 Token 数量分开上报的输入 Token。 。类型:counter 。标签数量:12 个标签
标签
endpoint, inbound_protocol, upstream_protocol, provider, model, upstream_model, provider_key_id, provider_key_name, api_key_id, team_id, user_id, user_nameinbound_protocol 的值
openai, anthropic, realtime, passthroughupstream_protocol 的值
openai, anthropic, bedrock, vertex, azure-openai, unknown网关与上游通信所使用的协议,与 inbound_protocol 相互独立。unknown 表示该请求没有选中任何上游——在转发前被拒绝,或是不调用模型的路由。
行为
Anthropic 计量口径:Anthropic 的 cache_read_input_tokens 和 Amazon Bedrock 的 cacheReadInputTokens。这些 Token **不**包含在 aisix_llm_input_tokens_total 中,但包含在 aisix_llm_total_tokens_total 中。
aisix_llm_cache_creation_input_tokens_total 。描述:写入上游提示词缓存的输入 Token。 。类型:counter 。标签数量:12 个标签
标签
endpoint, inbound_protocol, upstream_protocol, provider, model, upstream_model, provider_key_id, provider_key_name, api_key_id, team_id, user_id, user_nameinbound_protocol 的值
openai, anthropic, realtime, passthroughupstream_protocol 的值
openai, anthropic, bedrock, vertex, azure-openai, unknown网关与上游通信所使用的协议,与 inbound_protocol 相互独立。unknown 表示该请求没有选中任何上游——在转发前被拒绝,或是不调用模型的路由。
行为
对应 Anthropic 的 cache_creation_input_tokens 和 Amazon Bedrock 的 cacheWriteInputTokens。与同一口径下的缓存读取一样,这些 Token 位于 aisix_llm_input_tokens_total 之外、aisix_llm_total_tokens_total 之内。
各服务商对缓存写入的计费高于标准输入价格,对缓存读取的计费则远低于标准价格,因此写入远多于读取的工作负载反而比完全不用缓存更贵。将该计数器与 aisix_llm_cache_read_input_tokens_total 对比即可发现这种情况。
aisix_llm_spend_micro_usd_total 。描述:1.7.1 之后已移除:后续版本不再发射。统计支出请以控制面为每个请求记录的费用为准;用量事件仍携带 cost_usd。在 1.7.1 及更早版本中,它是网关仅为 Realtime 会话自行估算的支出,单位为价格所用币种的百万分之一。 。类型:counter 。标签数量:12 个标签
标签
endpoint, inbound_protocol, upstream_protocol, provider, model, upstream_model, provider_key_id, provider_key_name, api_key_id, team_id, user_id, user_nameendpoint 的值
/v1/realtimeinbound_protocol 的值
realtimeupstream_protocol 的值
openai, azure-openai行为
observability.metrics.labels 中仍写有该指标族时,后续版本的网关照常启动:忽略该条目,并在启动时输出一次警告。请删除该条目。
aisix_llm_tokens_by_client_total 。描述:所有报告 Token 用量的端点中的 Token 用量,按标准化客户端、请求模型和 Token 类型分组。 。类型:counter 。标签数量:3 个标签
标签
client_type, model, token_typeclient_type 的值
openai-python, openai-node, anthropic-python, anthropic-typescript, claude-code, codex, cline, roo-code, kilocode, zoo-code, github-copilot, cursor, opencode, qwen-code, gemini-cli, crush, zed, aider, vercel-ai-sdk, langchain, llamaindex, litellm, curl, python-requests, httpx, aiohttp, okhttp, go-http-client, node, postman, browser, other, unknown无法识别的 User-Agent 映射为 other;缺少 User-Agent 时映射为 unknown。部署可通过管理员定义的映射规则(observability.metrics.client_type_rules)扩展此集合。完整的 User-Agent 字符串和版本仍会保留在请求日志和用量分析中。
token_type 的值
input, output, totaltotal 包含输入、输出以及 Anthropic 缓存创建和缓存读取 Token。
行为
model 是调用方请求的模型名称,与 aisix_llm_* Token 序列的 model 标签值相同。路由、语义、合议和故障转移分发会保留此别名,而不是报告所选直接模型。
有界的 client_type 白名单可防止客户端可控的 User-Agent 导致 Prometheus 基数无限增长。具体模型别名受已配置模型集合的限制,但通配符别名会记录通过该模式请求的每个具体模型名称。基数很重要时,请限制通配符访问并监控标签增长。
管理员定义的映射规则(observability.metrics.client_type_rules)可对更多客户端进行分类。规则在内置白名单之前匹配,并输出固定且经过验证的标签值,因此标签集合保持有界。
在相同端点范围内跨所有标签聚合后,包含缓存的 total 与 aisix_llm_total_tokens_total 一致。由于两个指标系列使用不同的标签集合,单条序列并不对应;专用客户端类型序列避免为按密钥统计的 Token 序列再增加一个标签维度。
Anthropic 将缓存 Token 与输入 Token 分开报告,因此 total 可能大于 input 与 output 之和。
PromQL 示例
sum by (client_type, model, token_type) (
rate(aisix_llm_tokens_by_client_total[5m])
)限流与预算指标
监控每个标签集合的限流拒绝,以及最新配额或预算状态。
aisix_ratelimit_rejections_total 。描述:在各代理端点上被共享限流闸门拒绝的请求。 。类型:counter 。标签数量:3 个标签
标签
scope, layer, policy_idscope 的值
requests, tokens并发限制拒绝使用 requests;运行时不会发出单独的 concurrency 值。
layer 的值
api_key, model, mcp, policy行为
policy_id 在 layer="policy" 之外为空;在策略层上,该标签携带已配置的策略 ID。
可通过 observability.metrics.labels 添加 policy_name,即同一策略的配置名称;它不是默认标签。与 policy_id 一样,它在 layer="policy" 之外为空。1.5.0 及更早版本不输出该标签。
限流器背后的共享 Redis 可能在不拒绝任何请求的情况下失败——限流器会静默回退为按副本计数。这类失败由缓存指标中的 aisix_redis_failures_total 统计。
aisix_ratelimit_remaining_requests 。描述:API Key 限流窗口中的剩余请求配额,按 API Key 和模型分组;解析出模型的请求经过配额关卡时刷新。 。类型:gauge 。标签数量:2 个标签
标签
api_key_id, model行为
在所有于配额关卡之前解析出模型的路由上刷新,无论关卡放行还是拒绝该请求:模型端点、realtime 会话、文件、批处理和微调路由,以及请求正文指定了该路由提供商下已配置模型的透传路由。聊天补全在关卡拒绝时刷新,并在成功响应提交其 Token 后再次刷新。MCP 工具调用、A2A 调用和视频状态查询不解析模型,不会改变它。1.7.1 及更早版本只在聊天补全上刷新。
model 是请求解析到的已配置模型——通配符别名报告的是该行本身(例如 openai/*),而不是调用方发来的具体名称。
在 API Key 被删除、或其报告的模型不再存在之后的数秒内退休为 NaN。用 NaN 而不是 0,是因为 0 在这个仪表上本身就是一个有意 义的读数;任何与 NaN 的比较都为假,因此挂在退休序列上的告警会停止触发。对含有退休序列的指标族做聚合,结果同样是 NaN。
可通过 observability.metrics.labels 添加 api_key_name,即 API Key 的显示名称;它不是默认标签,没有显示名称的 API Key 报告为 unknown。重命名 API Key 会产生新的序列,旧序列以同样方式退休。1.5.0 及更早版本不输出该标签。
aisix_ratelimit_remaining_tokens 。描述:API Key 限流窗口中的剩余 Token 配额,按 API Key 和模型分组;解析出模型的请求经过配额关卡时刷新。 。类型:gauge 。标签数量:2 个标签
标签
api_key_id, model行为
刷新的路由和时机与 aisix_ratelimit_remaining_requests 相同。1.7.1 及更早版本只在聊天补全上刷新。
model 是请求解析到的已配置模型——通配符别名报告的是该行本身(例如 openai/*),而不是调用方发来的具体名称。
在 API Key 被删除、或其报告的模型不再存在之后的数秒内退休为 NaN。用 NaN 而不是 0,是因为 0 在这个仪表上本身就是一个有意义的读数;任何与 NaN 的比较都为假,因此挂在退休序列上的告警会停止触发。对含有退休序列的指标族做聚合,结果同样是 NaN。
可通过 observability.metrics.labels 添加 api_key_name,即 API Key 的显示名称;它不是默认标签,没有显示名称的 API Key 报告为 unknown。重命名 API Key 会产生新的序列,旧序列以同样方式退休。1.5.0 及更早版本不输出该标签。
aisix_budget_limit_usd 。描述:预算上限(控制面返回的金额;指标名保留 usd)。 。类型:gauge 。标签数量:4 个标签
标签
api_key_id, team_id, user_id, user_name行为
1.6.0 按美元计价;开发版按组织币种计价。开发版的 usd 后缀为保留名称,不表示固定使用美元。
删除某把 Key 的预算不会把这个仪表置零——它会保留最后一次的预算值,这正是查询需要加上 aisix_budget_details_present == 1 条件的原因。
在 API Key 被删除、或被改绑到其他团队或成员之后的数秒内退休为 NaN。用 NaN 而不是 0,是因为 0 在这个仪表上本身就是一个有意义的读数;任何与 NaN 的比较都为假,因此挂在退休序列上的告警会停止触发。对含有退休序列的指标族做聚合,结果同样是 NaN。
可通过 observability.metrics.labels 添加 api_key_name 和 team_name,即 API Key 及其团队的显示名称;二者都不是默认标签,无法解析的名称报告为 unknown。重命名 API Key 或团队会产生新的序列,旧序列以同样方式退休。1.5.0 及更早版本不输出该标签。
aisix_budget_spent_usd 。描述:已用预算(控制面返回的金额;指标名保留 usd)。 。类型:gauge 。标签数量:4 个标签
标签
api_key_id, team_id, user_id, user_name行为
1.6.0 按美元计价;开发版按组织币种计价。开发版的 usd 后缀为保留名称,不表示固定使用美元。
删除某把 Key 的预算不会把这个仪表置零——它会保留最后一次的预算值,这正是查询需要加上 aisix_budget_details_present == 1 条件的原因。
在 API Key 被删除、或被改绑到其他团队或成 员之后的数秒内退休为 NaN。用 NaN 而不是 0,是因为 0 在这个仪表上本身就是一个有意义的读数;任何与 NaN 的比较都为假,因此挂在退休序列上的告警会停止触发。对含有退休序列的指标族做聚合,结果同样是 NaN。
可通过 observability.metrics.labels 添加 api_key_name 和 team_name,即 API Key 及其团队的显示名称;二者都不是默认标签,无法解析的名称报告为 unknown。重命名 API Key 或团队会产生新的序列,旧序列以同样方式退休。1.5.0 及更早版本不输出该标签。
aisix_budget_remaining_usd 。描述:剩余预算(控制面返回的金额;指标名保留 usd)。 。类型:gauge 。标签数量:4 个标签
标签
api_key_id, team_id, user_id, user_name行为
1.6.0 按美元计价;开发版按组织币种计价。开发版的 usd 后缀为保留名称,不表示固定使用美元。
删除某把 Key 的预算不会把这个仪表置零——它会保留最后一次的预算值,这正是查询需要加上 aisix_budget_details_present == 1 条件的原因。
在 API Key 被删除、或被改绑到其他团队或成员之后的数秒内退休为 NaN。用 NaN 而不是 0,是因为 0 在这个仪表上本身就是一个有意义的读数;任何与 NaN 的比较都为假,因此挂在退休序列上的告警会停止触发。对含有退休序列的指标族做聚合,结果同样是 NaN。
可通过 observability.metrics.labels 添加 api_key_name 和 team_name,即 API Key 及其团队的显示名称;二者都不是默认标签,无法解析的名称报告为 unknown。重命名 API Key 或团队会产生新的序列,旧序列以同样方式退休。1.5.0 及更早版本不输出该标签。
aisix_budget_reset_seconds 。描述:距离预算周期重置的秒数。 。类型:gauge 。标签数量:4 个标签
标签
api_key_id, team_id, user_id, user_name行为
删除某把 Key 的预算不会把这个仪表置零——它会保留最后一次的预算值,这正是查询需要加上 aisix_budget_details_present == 1 条件的原因。
在 API Key 被删除、或被改绑到其他团队或成员之后的数秒内退休为 NaN。用 NaN 而不是 0,是因为 0 在这个仪表上本身就是一个有意义的读数;任何与 NaN 的比较都为假,因此挂在退休序列上的告警会停止触发。对含有退休序列的指标族做聚合,结果同样是 NaN。
可通过 observability.metrics.labels 添加 api_key_name 和 team_name,即 API Key 及其团队的显示名称;二者都不是默认标签,无法解析的名称报告为 unknown。重命名 API Key 或团队会产生新的序列,旧序列以同样方式 退休。1.5.0 及更早版本不输出该标签。
aisix_budget_details_present 。描述:是否已填充预算详情。 。类型:gauge 。标签数量:4 个标签
标签
api_key_id, team_id, user_id, user_name指标值 的值
0, 11 表示存在预算详情;0 表示预算详情已清除。
行为
可通过 observability.metrics.labels 添加 api_key_name 和 team_name,即 API Key 及其团队的显示名 称;二者都不是默认标签,无法解析的名称报告为 unknown。重命名 API Key 或团队会产生新的序列。1.5.0 及更早版本不输出该标签。
缓存指标
按策略衡量响应缓存的效果,并关注语义层的向量嵌入与存储健康状况。
缓存命中率
每个被已启用缓存策略覆盖、且后端可用的请求都会记录一次 aisix_cache_requests_total。没有匹配策略或后端不可用的请求不计入——闸门从未打开——因此该系列衡量的是策略效果,而不是总流量。
按策略计算命中率:sum by (policy) (rate(aisix_cache_requests_total{outcome=~"hit_exact|hit_semantic"}[5m])) / sum by (policy) (rate(aisix_cache_requests_total[5m]))。按 outcome 拆分可以看出语义层在精确匹配之上贡献了多少。
语义层的失败会退化为普通未命中,仅凭结果计数器无法区分损坏的向量嵌入模型或存储与健康的低命中率。对 aisix_cache_semantic_embedding_failures_total 和 aisix_cache_semantic_store_failures_total 设置告警来区分二者。
aisix_cache_requests_total 。描述:按策略名称和结果统计的缓存合格请求,当匹配的已启用策略与可用后端打开缓存闸门时,每个请求计数一次。 。类型:counter 。标签数量:2 个标签
标签
policy, outcomeoutcome 的值
hit_exact, hit_semantic, miss, bypassbypass 表示调用方发送了 Cache-Control: no-cache,跳过了读取路径。no-store 会保留读取路径,因此记录为普通的命中或未命中,并且只在未命中后禁止写入。
aisix_cache_semantic_embedding_seconds 。描述:语义层向量嵌入调用的延迟,按策略统计。无固定桶的摘要系列。 。类型:summary 。标签数量:1 个标签
标签
policyaisix_cache_semantic_embedding_failures_total 。描述:语义层的向量嵌入失败。失败的请求不经缓存直接发往上游。 。类型:counter 。标签数量:2 个标签
标签
policy, causecause 的值
resolve, embedresolve(向量嵌入模型缺失或不是向量嵌入模型)按合格请求计数一次,包括随后命中精确层的请求;embed(服务提供方调用失败或超时)按向量嵌入调用计数。
aisix_cache_semantic_store_failures_total 。描述:语义存储的操作失败,按操作统计。进程内存储不会失败;共享(Redis)存储可能失败。失败退化为普通未命中。 。类型:counter 。标签数量:2 个标签
标签
policy, opop 的值
lookup, storeaisix_redis_failures_total 。描述:对 Redis 后端存储的失败操作,每次操作失败计数一次。它覆盖所有以 Redis 为 后端的子系统——共享限流器、精确响应缓存和语义缓存——因为一套部署通常把它们指向同一个 Redis。1.1.0 及更早版本不发射该指标。 。类型:counter 。标签数量:1 个标签
标签
operationoperation 的值
ratelimit_acquire, ratelimit_commit, ratelimit_peek, ratelimit_release, ratelimit_add_tokens, cache_get, cache_put, semantic_acquire, semantic_index, semantic_lookup, semantic_store取值同时标明子系统和具体调用,因此即使限流器与各类缓存共用一个 Redis,也能分辨出是哪个存储在退化。
行为
这些失败在设计上都是静默降级——共享限流器回退为按副本计数,缓存读取变成未命中——因此该计数器是唯一能反映这种降级的指标。其中大多数同时也会记录日志;只有分离出去的 ratelimit_release 和 ratelimit_add_tokens 操作没有日志,该计数器是它们唯一的痕迹。
部署指标
监控每个目标模型的表现:上游尝试及其结果、目标之间的回退,以及目标是否仍参与轮转。
统计的是尝试而非请求
这些计数器每次上游**尝试**采样一次,且每个样本归属于被尝试的目标,而不是调用方指定的模型组。一次客户端请求若在三个目标之间故障转移,在这里是三个样本,在请求指标中是一个样本。用本族回答「哪个目标在失败」,用请求族回答「调用方经历了什么」。
只统计真正到达上游的尝试。被网关自行拒绝的尝试——目标超出其自身限流,或其凭据、端点在发送任何内容之前就未通过校验——从未产生上游响应,因此不会出现在这里,但仍会出现在用量日志中。这样配置错误就不会被读成目标不健康。
模型端点下发的每次上游尝试都会记录,无论目标是直连模型还是模型组中的目标,包括 /v1/videos 提交。视频状态查询和内容下载请求、realtime 会话(完成的 WebSocket 升级计为成功),以及文件、批处理和微调路由,也会在此记录其上游调用;1.7.1 及更早版本不记录这些。MCP 工具调用、A2A 调用和透传路由不调用已配置模型,不在此记录。
两个回退计数器来自模型端点在目标 之间的故障转移。realtime 会话、视频状态查询和内容下载请求,以及文件、批处理和微调路由只调用一个目标,从不记录回退。
aisix_deployment_requests_total、aisix_deployment_success_responses_total、aisix_deployment_failure_responses_total 和 aisix_deployment_cooled_down_total 在 observability.metrics.labels 中加入该指标族的标签列表后,还支持 provider_key_name,即提供商密钥的显示名称;它在这些指标上不是默认标签,重命名会产生新的序列。aisix_deployment_state 不支持该标签:该 Gauge 只在目标健康状态变化时写入,重命名后的密钥在下一次状态变化之前会一直报告旧名称。1.5.0 及更早版本不输出该标签。
aisix_deployment_requests_total 。描述:下发到某个目标模型的上游尝试次数,不论结果如何。 。类型:counter 。标签数量:4 个标 签
标签
provider, model, upstream_model, provider_key_idPromQL 示例
sum(rate(aisix_deployment_requests_total[5m])) by (model)aisix_deployment_success_responses_total 。描述:目标模型成功响应的上游尝试次数。 。类型:counter 。标签数量:4 个标签
标签
provider, model, upstream_model, provider_key_id行为
对于流式响应,尝试在上游流建立时即计为成功。此后中断的流不会在这里重新归类。
aisix_deployment_failure_responses_total 。描述:在目标模型处失败的上游尝试次数,包含随后被回退救回的那些失败。 。类型:counter 。标签数量:4 个标签
标签
provider, model, upstream_model, provider_key_idPromQL 示例
sum(rate(aisix_deployment_failure_responses_total[5m])) by (model)
/ sum(rate(aisix_deployment_requests_total[5m])) by (model)aisix_routing_successful_fallbacks_total 。描述:在先前目标失败后,成功处理了该请求的回退尝试次数。 。类型:counter 。标签数量:2 个标签
标签
model, fallback_model行为
model 是调用方所请求的名称,即模型组名称。fallback_model 是网关转向的目标。
aisix_routing_failed_fallbacks_total 。描述:同样失败的回退尝试次数。 。类型:counter 。标签数量:2 个标签
标签
model, fallback_model行为
被第二个回退目标救回的请求,会在这里贡献一个样本,同时在成功回退族中贡献一个样本。
aisix_deployment_state 。描述:目标模型是否参与轮转。 。类型:gauge 。标签数量:4 个标签
标签
provider, model, upstream_model, provider_key_id指标值 的值
0, 20 表示健康。2 表示目标因正在冷却或后台健康检查失败而退出轮转。
aisix_deployment_cooled_down_total 。描述:目标模型进入冷却的次数。 。类型:counter 。标签数量:4 个标签
标签
provider, model, upstream_model, provider_key_id安全护栏指标
跟踪所有端点上各安全护栏的执行延迟和结果,以及聚合阻断和 fail-open 绕过。
安全护栏执行延迟
每次计时的安全护栏执行都会记录一条 aisix_guardrail_latency_seconds 观测。安全护栏通常在每个适用阶段执行一次;流式窗口扫描可以为一条响应记录多次输出执行。该直方图使用可配置的分桶,默认范围为 1 毫秒到 30 秒,因此可通过 histogram_quantile 计算各安全护栏的 P50/P95/P99。
kind 标签标识所配置的安全护栏实现;result 标签用于区分 fail-open 绕过(bypassed,失败标签位于 error_type 中)与策略决策。fail-closed 的评估失败会显示为 blocked; 请按 error_type 过滤,把它与策略命中区分开。
_count 序列同时也可用作各安全护栏的执行计数器:sum by (guardrail, result) (rate(aisix_guardrail_latency_seconds_count[5m])) 无需单独的计数器即可提供执行率和阻断率。
聚合计数器覆盖所有受安全护栏保护的端点,但统计单位不同。aisix_guardrail_blocks_total 统计被拒绝的请求,aisix_guardrail_bypasses_total 统计绕过事件,其中包括在任何安全护栏成员执行之前由网关发起的放行。它们不包含安全护栏、种类和阶段标签;需要计时执行的这些维度时,请使用直方图的 _count 序列。
aisix_guardrail_latency_seconds 。描述:所有端点中一次计时的安全护栏执行所经历的实际时间。guardrail 是配置的安全护栏名称。 。类型:histogram 。标签数量:6 个标签
标签
env_id, guardrail, kind, phase, result, error_typekind 的值
keyword, pii, aliyun_ai_guardrail, aliyun_text_moderation, azure_content_safety, azure_content_safety_text_moderation, bedrock, lakera, openai_moderation, presidio, semantic, customkeyword 和 pii 在进程内运行。semantic 调用配置的向量嵌入模型,custom 运行配置的脚本,其余种类调用审核服务。
phase 的值
input, outputresult 的值
allowed, blocked, masked, bypassed, would_block, would_mask, would_mask_unsupportedbypassed 表示评估失败后 fail-open;fail-closed 的评估失败记录为 blocked。would_block/would_mask/would_mask_unsupported 来自配置为 enforcement_mode: monitor 的安全护栏。would_mask_unsupported 表示脱敏规则在无法改写内容的路由(例如透传路由)上命中;强制执行的安全护栏遇到同样的命中时记录为 allowed,因为内容已不经修改地放行。1.4.0 及更早版本不发射 would_mask_unsupported,它们把这类命中记录为 would_mask。
error_type 的值
none, aliyun_5xx, aliyun_config_error, aliyun_bad_response, aliyun_throttled, aliyun_timeout, azure_cs_5xx, azure_cs_config_error, azure_cs_throttled, azure_cs_timeout, bedrock_5xx, bedrock_throttled, bedrock_timeout, bedrock_too_large, lakera_5xx, lakera_config_error, lakera_throttled, lakera_timeout, lakera_too_large, openai_moderation_5xx, openai_moderation_config_error, openai_moderation_throttled, openai_moderation_timeout, openai_moderation_too_large, presidio_5xx, presidio_config_error, presidio_throttled, presidio_timeout, presidio_too_large, custom_timeout, custom_script_error, custom_engine_error, custom_no_verdict, custom_bad_verdict, custom_unknown_action, semantic_embed_unresolved, semantic_embed_timeout, semantic_embed_upstream当评估失败产生 result="blocked"、result="bypassed" 或监控模式下的 result="would_block" 时,设置为有界失败标签;其他情况为 none。bypassed 使用的取值同样用于 aisix_guardrail_bypasses_total{reason}。该计数器还会为网关自身发起、不产生计时直方图观测的放行使用 unscannable_body 和 output_buffer_exceeded。
行为
默认分桶:0.001、0.0025、0.005、0.01、0.025、0.05、0.1、0.25、0.5、1、2.5、5、10 和 30 秒,可通过 observability.metrics.buckets.guardrail_latency 配置。
监控模式执行会在请求继续处理的同时记录 would_block / would_mask,因此可以在实施策略前评估分阶段策略的规模。
通过同步逐字段操作执行的 PII 和关键词脱敏不会计入该序列;其进程内耗时以微秒计。
aisix_guardrail_blocks_total 。描述:在所有端点上被输入或输出安全护栏强制措施拒绝的请求数,包括安全护栏成员执行前因流式输出缓冲区溢出等原因触发的 fail-closed 路径。 。类型:counter 。标签数量:无标签
标签
无。
aisix_guardrail_bypasses_total 。描述:在所有受安全护栏保护的端点上,安全护栏评估失败或网关发起的不可读内容放行中,由 fail-open 策略让请求或响应继续处理的次数。 。类型:counter 。标签数量:1 个标签
标签
reasonreason 的值
aliyun_5xx, aliyun_config_error, aliyun_bad_response, aliyun_throttled, aliyun_timeout, azure_cs_5xx, azure_cs_config_error, azure_cs_throttled, azure_cs_timeout, bedrock_5xx, bedrock_throttled, bedrock_timeout, bedrock_too_large, lakera_5xx, lakera_config_error, lakera_throttled, lakera_timeout, lakera_too_large, openai_moderation_5xx, openai_moderation_config_error, openai_moderation_throttled, openai_moderation_timeout, openai_moderation_too_large, presidio_5xx, presidio_config_error, presidio_throttled, presidio_timeout, presidio_too_large, custom_timeout, custom_script_error, custom_engine_error, custom_no_verdict, custom_bad_verdict, custom_unknown_action, semantic_embed_unresolved, semantic_embed_timeout, semantic_embed_upstream, unscannable_body, output_buffer_exceededunscannable_body 和 output_buffer_exceeded 由网关自身发起:前者是 AISIX 无法读取的内容,后者是被保留的流在 on_buffer_exceeded: fail_open 下未经扫描放行。1.4.0 及更早版本不发射 output_buffer_exceeded,它们不把这种放行计为绕过。
A2A 指标
按调用到的 Agent 和调用的操作来度量 Agent-to-Agent 流量。
Agent 与操作标签
agent 是已注册的 A2A Agent,operation 是调用方实际调用的规范化操作。A2A 0.3 和 1.0 会把同一个操作拼成两种写法,因此 AISIX 记录规范化形式;同时对接两个版本的部署仍然会聚合为同一条序列。无法识别的方法归为 unknown。
任务 ID、上下文 ID 和 JSON-RPC 请求 ID 有意不作为标签。正是它们让单次调用可追踪,也正因如此它们不能做标签值;请到用量事件和链路追踪中查找。
aisix_a2a_requests_total 与 aisix_proxy_requests_total{endpoint="/a2a"} 的数字并不一致,这是有意为之。在 Agent 解析出来之前就被拒绝的调用没有可归属的 Agent,只会计入 proxy 系 列。调用方中途放弃的流在两个系列中都是 499;1.5.0 及更早版本在 proxy 系列中把它计为 2xx,因为响应是以 200 开始的。看 Agent 健康度用这个系列,看路由流量用 proxy 系列。
对于流式 A2A,aisix_proxy_request_duration_seconds 记录完整的流;1.5.0 及更早版本只记录到响应开始为止的时间。aisix_request_e2e_latency_seconds{endpoint="/a2a"} 记录 Agent 调用的完整时长,包含完整的流,其 side="upstream" 序列记录对 Agent 的调用(1.7.1 及更早版本不记录)。获取 Agent Card 计入其单独的 endpoint="/a2a/{agent}/.well-known/agent-card.json"。
aisix_a2a_requests_total 。描述:按调用到的 Agent、调用的规范化操作和状态类别统计的 A2A 调用数。 。类型:counter 。标签数量:3 个标签
标签
agent, operation, status行为
与用量事件在同一处记录,因此被计入用量的调用一定也被计入指标。
PromQL 示例
sum by (agent, operation) (
rate(aisix_a2a_requests_total{status!="2xx"}[5m])
)aisix_a2a_ttfb_seconds 。描述:流式 A2A 调用中,上游 Agent 发出首个流式事件的耗时。 。类型:histogram 。标签数量:2 个标签
标签
agent, operation行为
之所以按「事件」而非「Token」命名,是因为 Agent 流传输的是任务更新而不是 Token。默认分桶与 aisix_request_ttft_seconds 相同,可通过 observability.metrics.buckets.a2a_ttfb 配置。
仅在至少产生一个事件的流式操作上记录。
PromQL 示例
histogram_quantile(
0.90,
sum by (le, agent) (rate(aisix_a2a_ttfb_seconds_bucket[5m]))
)aisix_a2a_stream_events_total 。描述:流式 A2A 调用中向下游转发的事件数。 。类型:counter 。标签数量:2 个标签
标签
agent, operation行为
除以流式操作上 的 aisix_a2a_requests_total,即为每次调用的事件数——可以看出某个 Agent 有多「话密」,以及这一点是否发生了变化。message/stream 和 tasks/resubscribe 都是流式操作,分母要同时包含两者,否则比值会偏高。
PromQL 示例
sum by (agent) (rate(aisix_a2a_stream_events_total[5m]))
/
sum by (agent) (
rate(aisix_a2a_requests_total{operation=~"message/stream|tasks/resubscribe"}[5m])
)aisix_a2a_task_state_total 。描述:按 Agent 最后上报的任务状态统计的 A2A 调用数,已归一为规范定义的状态集合加 unknown。 。类型:counter 。标签数量:2 个标签
标签
agent, state行为
这是按每次调用「结束时」的状态累加的计数器,因此应当按速率来读,而不是当作实时积压量:任务后续状态变化不会减少之前的样本,而用 tasks/get 轮询同一个任务时每次轮询都会再上报一次状态。上游从未应答的调用不会上报状态,也不计入此指标。
PromQL 示例
sum by (agent, state) (rate(aisix_a2a_task_state_total[5m]))用量事件指标
区分用量事件发送尝试与未能到达控制面的事件——无论是传递队列未接受,还是 worker 未能投递。
用量事件传递
每次发送尝试的事件要么被传递到控制面,要么计为丢弃。从发送尝试速率中减去丢弃速率,即可计算传递速率。已传递的事件仍可能被控制面拒绝而未被存储,这部分由 aisix_usage_events_rejected_total 统计。
丢弃来自两个环节。队列侧的 reason(sink_disabled、sink_full、sink_closed)统计交接队列从未接受的事件,它们与发送尝试计数器携带相同的 model、provider_key_id 和 provider_key_name 标签,因此该减法在按模型、按 Provider Key 的粒度上同样成立。投递侧的 reason(send_failed、retry_budget_exhausted)统计 worker 已接受、但未能上报到控制面的事件;worker 持有的是事件本身而不是发出该事件的处理器所用的标签集,因此这些样本的 model 和两个 Provider Key 标签均为 unknown,只携带成员这一对标签。所以 发送尝试 = 已传递 + 已丢弃 在总量以及按 user_id/user_name 的粒度上成立,而按模型、按 Provider Key 的减法只覆盖队列侧。
被队列接受不等于已传递。worker 接受事件之后,控制面上报仍可能失败:在控制面表明自己按批次 ID 去重的前提下,worker 会重发失败的批次,并在该批次最早一条事件之后 30 分钟、或 8 次被应答的失败之后放弃,写入 telemetry batch failed (events dropped) 日志。这类丢失按投递侧的 reason 计入 aisix_usage_event_drops_total。导出器链路则是另一条独立的腿——它由同一个发射点供给,而不是接在 worker 之后——同样可能在重试后丢弃;导出器侧的丢失不会增加该计数器,由 aisix_otlp_fanout_drops_total 统计。
status_code 标签为 2xx、3xx、4xx、5xx 或 other,status 则在其旁边携带原始 HTTP 状态码——status 用于定位单一故障模式,status_code 用于按状态族汇总,二者描述的是同一个事件。handler 示例值包括 chat、embeddings、messages 和 mcp。
user_id 是发起请求所用 API Key 所属的组织成员,user_name 是该成员的显示名称;API Key 未绑定 成员时二者均为 unknown。两个计数器都携带这两个标签,因此 发送尝试 = 已传递 + 已丢弃 在按成员的粒度上依然成立。由于经 JWT 认证的请求会以其身份解析出的 API Key 运行,一个成员标签即可覆盖该成员使用的全部凭证。名称与 ID 一一对应,因此不会增加新的序列维度。在 1.5.0 及更早版本上,它是控制面上次投影该 API Key 时写入的名称,而非实时查询结果:此后成员改名,这些指标上仍会沿用旧名称,直到该 API Key 因其他原因被再次写入。更新版本的网关从成员自己的名称文档读取该名称,控制面会在成员改名时更新该文档。
model 是调用方请求的模型,并会归一到已配置的模型名称。未能解析出模型的请求报告 unresolved;本身就没有模型的请求——MCP 工具调用、A2A Agent 调用、正文未指定模型的透传请求——报告 unknown。凡是未解析出上游 Provider Key 的情况,两个 Provider Key 标签同样为 unknown。
MCP 工具调用使用 handler="mcp" 和 inbound_protocol="mcp"。其用量事件负载会标识 MCP 服务器和工具;Token 与成本字段为零。
A2A Agent 调用使用 handler="a2a"。该指标将其有界的 inbound_protocol 标签映射为 other,而传递的事件使用 inbound_protocol="a2a",并标识 Agent 名称和 JSON-RPC 方法。网关会根据消息文本估算输入和输出 Token 并置 usage_estimated: true,成本字段仍为零。