跳到主要内容
版本:1.2.0

访问日志与请求关联

AISIX AI 网关会写入结构化访问日志,并记录可将请求与调用方、前置基础设施和上游模型服务提供方关联起来的标识符。借助这些记录,运维人员可以还原请求过程,并在各个系统中找到对应的条目。

收集访问日志

AISIX 通过进程日志记录器将访问日志写入标准错误流。容器运行时、服务管理器或主机日志流水线可以收集该数据流。

在启动配置中设置进程日志级别:

config.yaml
observability:
log_level: "info"

RUST_LOG 环境变量设置为有效过滤器时,它会覆盖已配置的日志级别。

备注

access_log 字段为保留字段,目前不起作用。访问日志没有单独的格式或接收端配置;请收集进程的标准错误流。

在相应值可用时,访问日志会包含请求方法、路径、状态、延迟、模型服务提供方、模型、API Key ID、请求 ID、Token 数量和路由结果。

对于失败的请求,error_kind 提供稳定的失败类别,error 则在可用时提供底层原因。

了解日志写入时机和覆盖范围

访问日志的写入时机和可用详情取决于请求类型:

信号写入时机提供的信息
非流式请求的访问日志请求结束时请求结果及网关解析出的所有字段,包括可用时的 Token 数量和模型服务提供方响应 ID。
流式请求的访问日志响应打开时初始结果和路由字段。此时 Token 数量和模型服务提供方响应 ID 尚不可用;流式数据由用量事件携带。
Realtime 会话的访问日志WebSocket 会话关闭后会话结果和已解析的请求字段。Token 总数仍由用量事件携带。
provider call completed 日志每个返回 ID 的模型服务提供方调用各写入一次该上游尝试的 request_idattempt_indexattempt_kindprovider_request_id
用量事件支持的代理路径中,每次请求尝试写入一次尝试结果、用量、延迟,以及可用时的模型服务提供方响应 ID。

追踪模型服务提供方调用尝试

provider_request_id 是模型服务提供方返回的响应对象 ID,例如 OpenAI 的 chat.completion.id、Anthropic 消息 id 或 Responses API 的 resp_…。可以用它在模型服务提供方的控制台或支持记录中查找对应调用。

该字段在没有可用 ID 时会被省略而不是留空,包括安全护栏拦截、缓存命中以及经过规范化的嵌入、音频和图像响应。对于流式请求,请在 provider call completed 条目中查找各个返回的模型服务提供方 ID。通过 request_id 将其与访问日志关联,并使用 attempt_index 区分重试或故障转移。

跨系统关联请求

x-aisix-request-id 响应头是关联请求记录的主要键。其他受支持的响应头会报告缓存结果、重试时间和所选目标;其路由覆盖范围请参阅响应头和错误码

一个请求可能涉及三类标识符,彼此不能替代:

标识符分配方用途
request_idAISIX;如果 AISIX 接受调用方提供的值,则由调用方分配。以 x-aisix-request-id 返回。查找请求的访问日志和用量事件,包括导出的记录以及控制台 Logs 页面中的条目。
downstream_request_id前置基础设施通过 x-request-id 请求头分配。记录在网关日志中,但不会作为独立的下游 ID 返回。如果 AISIX 接受该值,则以 x-aisix-request-id 返回。在 Ingress Controller、反向代理、服务网格或 CDN 中查找同一个 HTTP 请求。
provider_request_id模型服务提供方;响应中包含 ID 的每次上游尝试各有一个。在模型服务提供方控制台中查找该次尝试,或向其支持团队提供该 ID。

调查已完成的响应时:

  1. 从返回给调用方的 x-aisix-request-id 值开始。
  2. 通过 request_id 查找对应的访问日志和用量事件。使用 attempt_index 对重试或故障转移排序。
  3. 需要与模型服务提供方一起调查调用时,从相关尝试中读取 provider_request_id

如果连接在响应头发送前断开,请从前置基础设施提供的 downstream_request_id 开始调查。

匹配前置基础设施

AISIX 会分别记录网络连接、转发请求和解析出的调用方地址:

标识对象匹配对象
peer已接受 TCP 连接的远端,包括其源端口。前置代理的连接记录。AISIX 使用主机网络并位于四层负载均衡器后方时最有用。
downstream_request_idx-request-id 接收的 HTTP 请求 ID。前置代理或 Ingress Controller 的请求日志。
解析出的调用方地址通过 proxy.real_ip 选择的不带端口的调用方 IP。访问控制决策和用量记录。

如果存在,peerdownstream_request_id 会贯穿请求的访问日志、provider call completed 条目和中间诊断日志。缺失的值会被省略,而不是以空字段记录。

AISIX 会先检查传入的 x-request-id,再将其写入日志。记录该值并不会让它成为网关的 request_id;是否接受该值由 proxy.request_id.accept_headers 单独控制。

诊断未完成或被拒绝的请求

访问日志和相关信号可用于区分请求停止的位置:

场景AISIX 记录附加信号
调用方在响应头发送前断开状态为 499error_kind="client_disconnected" 的访问日志。如果模型和模型服务提供方已经解析,则日志会包含这些信息,但不含 Token 字段。aisix_proxy_client_cancelled_requests_total 对该请求计数。
调用方在流式响应期间断开访问日志保留正常响应状态,因为该状态已经写出。用量事件记录状态 499 以及断开前收到的 Token。
超大请求正文被完全排空info 级别的 aisix::body_limit 条目,其中 drain_outcome="completed"。调用方可以收到 413 Content Too Largeaisix_proxy_request_body_limit_rejections_total 对该拒绝计数。
超大正文无法完全排空诊断结果为 cap_reachedtimeoutclient_read_error,调用方通常会看到连接关闭。这些 warn 条目按每种结果每秒最多一条进行限制。拒绝指标会对每次发生计数,包括日志限流器抑制的诊断。

正文限制诊断条目还包含 request_iddeclared_content_lengthconfigured_limit_bytesdrained_bytes。使用 request_id 将其与访问日志关联。

如果调用方在模型解析前断开,访问日志既不包含模型,也不包含模型服务提供方。

复用自己的请求 ID

如果服务已经为业务调用生成请求 ID,请将其发送给 AISIX。被接受的值随后会出现在响应头、访问日志、每个用量事件、AISIX Cloud 请求日志以及发送到上游的 x-aisix-request-id 请求头中。

# AISIX_PROXY 是网关 Origin;不要包含末尾斜杠和端点路径
# 本地快速入门使用 http://127.0.0.1:3000
export AISIX_PROXY="YOUR_AISIX_GATEWAY_URL"
export AISIX_API_KEY="YOUR_CALLER_API_KEY"
export MODEL_ALIAS="YOUR_MODEL_ALIAS"

curl -i "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer $AISIX_API_KEY" \
-H "Content-Type: application/json" \
-H "x-aisix-request-id: req_abc123-orders-svc" \
-d '{
"model": "'"$MODEL_ALIAS"'",
"messages": [
{
"role": "user",
"content": "Hello"
}
]
}'

响应会回显相同的值:

HTTP/1.1 200 OK
x-aisix-request-id: req_abc123-orders-svc

重试和故障转移会在每个用量事件中复用已接受的 ID,因此按该值筛选可以返回完整的尝试链。

可接受的值

AISIX 按以下方式处理调用方提供的值:

提供的值结果
长度为 1–256 字节,且仅包含可见 ASCII 字符(!~AISIX 接受该值。UUID、ULID、req_abc123 等带前缀的 ID,以及 nginx $request_id 生成的十六进制 ID 都符合要求。
空值、超长值、非 ASCII 值、包含空格或控制字符的值AISIX 忽略该值,生成 UUID,并继续处理请求。
在不同请求中重复使用的值AISIX 会接受该值,因为它不强制唯一性,但这些请求在日志和事件轨迹中将无法区分。

请为每个请求生成新的 ID。

选择接受的请求头

默认情况下,AISIX 只从 x-aisix-request-id 接受调用方提供的 ID。以下配置还会接受基础设施分配的 x-request-id,并保留默认请求头作为后备:

config.yaml
proxy:
request_id:
# 默认:只接受 AISIX 请求 ID 请求头。
# accept_headers: ["x-aisix-request-id"]

# 请求头按从左到右的顺序检查;采用第一个可接受的值。
accept_headers: ["x-request-id", "x-aisix-request-id"]

# 要忽略调用方提供的所有 ID 并始终生成 UUID,请使用:
# accept_headers: []

当 AISIX 是请求的第一跳,或者需要让反向代理或 Ingress Controller 分配的 ID 在所有位置成为请求标识时,请使用此选项。无论该设置如何,AISIX 都会将可接受的 x-request-id 记录为 downstream_request_id;如果同时接受该值,request_iddownstream_request_id 将完全相同。

如果使用环境变量配置 AISIX,请将优先级列表设置为逗号分隔的 AISIX_PROXY__REQUEST_ID__ACCEPT_HEADERS 值。

只能使用有效且非保留的 HTTP 请求头名称。如果列表包含格式错误或保留的请求头(包括携带凭证的请求头、hostcookietraceparenttracestate),启动会失败。AISIX 会阻止这些请求头,因为接受的值会被记录、返回给调用方并发送到上游。

后续步骤

使用指标和日志监控聚合流量,并比较请求级指标与每次尝试的用量事件。配置可观测性导出器,将用量事件发送到外部目标。