可观测性导出器
可观测性导出器会将网关用量事件发送到用于链路追踪、日志记录、存储或记账的目标。本指南通过 AISIX Enterprise 和 AISIX Cloud 的控制面路径,或 AISIX OSS 的资源文件路径配置 OTLP/HTTP 导出器,再说明目标选择、内容采集和投递行为。
准备工作
请先准备以下内容:
- 以下任一配置路径:
- AISIX Enterprise 或 AISIX Cloud,其中包含一个环境、已关联的网关和具备写入作用域的 Admin Token。对于 AISIX Enterprise,请按照 AISIX Enterprise 入门指南操作。如需申请 AISIX Cloud 访问权限,请联系 API7。
- 加载声明式
resources.yaml文件的开源 AISIX 网关。
- 计划使用的导出器对应的遥测目标。
- 用于验证投递的可用模型别名和调用方 API Key。
导出验证所用的网关和请求参数:
# AISIX_PROXY 不含尾部斜杠或端点路径
# 本地快速入门使用 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"
对于控制面示例,请导出 Admin API 基础 URL、Admin Token 和环境 ID:
# AISIX_CP 包含 /api,且不含尾部斜杠
# 本地 AISIX Enterprise 快速入门使用 http://localhost:8080/api
export AISIX_CP="YOUR_AISIX_CONTROL_PLANE_API_URL"
export AISIX_TOKEN="YOUR_ADMIN_TOKEN"
export ENV_ID="YOUR_ENVIRONMENT_ID"
其他部署方式请使用可访问的 AISIX Cloud Admin API URL。
选择导出器类型
两种配置路径都支持所有导出器类型。AISIX Cloud Admin API 请求和资源文件条目通过 kind 值选择类型,控制台则显示同一底层类型对应的标签:
kind 值 | 控制台标签 | 适用场景 |
|---|---|---|
otlp_http | OTLP/HTTP | 已经通过 OTLP/HTTP 收集器或厂商端点收集链路(Trace)。 |
object_store | Object storage | 希望将批量 NDJSON 请求事件写入 Amazon S3、S3 兼容存储、Google Cloud Storage 或 Azure Blob。 |
datadog | Datadog | 使用 Datadog Logs HTTP 接收端。 |
aliyun_sls | Alibaba Cloud SLS | 使用阿里云日志服务作为日志目标。 |
网关会将遥测直接发送到所选目标。
配置 OTLP 导出器
设置示例使用的收集器端点和授权请求头:
# 请替换为实际值
export OTLP_ENDPOINT="https://collector.example.com/v1/traces"
export OTLP_AUTH_HEADER="Bearer YOUR_COLLECTOR_TOKEN"
网关进程必须能够访问该端点。端点可以是任意主机的 https:// 或 http:// URL,例如集群内的采集器 http://otel-collector-dev:4318/v1/traces。如果接收端与网关进程位于同一主机,可以使用 http://localhost:4318/v1/traces;容器化网关则需要使用接收端在容器网络或宿主机上的地址。如果接收端不要求认证,请从导出器中移除 headers 块。
使用 http:// 时,静态请求头和导出的遥测 数据以明文在网络中传输。请求头可能携带认证 Token,遥测数据可能包含提示词和响应内容,因此请在可信网络中使用 http://。
1.7.0 及更早版本的网关仅在运维人员配置的 http:// 端点主机名为 localhost、127.0.0.1 或 otel-collector 时接受该端点。环境中注册了此类网关时,AISIX Cloud Admin API 会以 422 DP_INCOMPATIBLE 拒绝保存其他主机上的 http:// 端点。将该环境的网关升级后即可保存。
AISIX Enterprise 或 AISIX Cloud
创建导出器并获取其 ID:
EXPORTER_ID=$(curl -sS -X POST "$AISIX_CP/environments/$ENV_ID/observability_exporters" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "prod-otlp",
"kind": "otlp_http",
"endpoint": "'"${OTLP_ENDPOINT}"'",
"headers": {
"Authorization": "'"${OTLP_AUTH_HEADER}"'"
},
"sample_rate": 1
}' | jq -r '.observability_exporter.id')
❶ 只有当 OTLP 目标要求时才设置静态请求头。请求头值会加密存储,并且读取操作绝不会返回这些值。
❷ sample_rate: 1 可以让投递检查得到确定的结果。它等同于省略该字段,即导出每个请求链路。验证完成后,如需减少跨度(Span)数量,可以降低该值。
获取导出器,确认存储的配置:
curl -sS "$AISIX_CP/environments/$ENV_ID/observability_exporters/$EXPORTER_ID" \
-H "Authorization: Bearer $AISIX_TOKEN"
你应该会看到类似下面的响应。读取操作通过 header_keys 暴露已配置的请求头名称,并通过 headers_set 确认已存储请求头值;但绝不会返回请求头值本身。
{
"observability_exporter": {
"id": "b46a9f5d-6a4d-4bb1-ae2c-4ab1b22f5e80",
"env_id": "0f2f6a1e-9d33-4a8f-9a6e-2a7b6a9c1d2e",
"name": "prod-otlp",
"enabled": true,
"kind": "otlp_http",
"endpoint": "https://collector.example.com/v1/traces",
"header_keys": ["Authorization"],
"headers_set": true,
"sample_rate": 1,
"created_at": "2026-07-22T08:30:00Z",
"updated_at": "2026-07-22T08:30:00Z"
}
}
保存 $EXPORTER_ID,以便后续更新或删除导出器。导出器默认启用。设置 enabled: false 可在不发送遥测的情况下保存资源。停用或删除导出器后,每个网关收到该配置变更时都会停止其投递流水线,并从投递健康报告中移除该导出器。流水线会按下文的重试规则和关闭期限尝试排空已排队的事件,但不保证全部送达。重新启用会启动一条计数器清零的新流水线。
AISIX OSS
将以下导出器添加到完整资源文件的 observability_exporters 中。使用环境变量插值可以避免将收集器 Token 写入文件:
observability_exporters:
- name: prod-otlp
kind: otlp_http
endpoint: ${OTLP_ENDPOINT}
headers:
Authorization: ${OTLP_AUTH_HEADER}
sample_rate: 1
验证组装后的完整文件:
aisix validate --resources resources.yaml
在进程环境中设置 OTLP_ENDPOINT 和 OTLP_AUTH_HEADER,然后启动或重启网关。只有当这些变量已经可用于运行中的进程时,才重新加载网关。导出器默认启用;添加 enabled: false 可保留条目但不发送遥测。
验证 OTLP 投递
保存导出器只能确认 AISIX 接受了配置。要验证上面配置的 OTLP 导出器,请获取 AISIX 返回的请求 ID,在目标端查找该 ID,并检查网关的投递信号。如果正在检查的现有 OTLP 导出器的 sample_rate 小于 1,请暂时将采样率设为 1,避免该请求被采样丢弃。
通过一个可用的模型别名发送成功请求,并获取 AISIX 返回的 ID。无论 AISIX 接受调用方提供的 ID,还是自行生成 ID,这种方式都能取得准确结果:
export EXPORTER_NAME="prod-otlp"
if TEST_REQUEST_ID=$(
set -o pipefail
curl -fsS -D - -o /dev/null \
-X POST "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer $AISIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${MODEL_ALIAS}"'",
"messages": [{"role": "user", "content": "Reply with: exporter check"}]
}' \
| awk 'tolower($1) == "x-aisix-request-id:" { id = $2; sub(/\r$/, "", id) } END { print id }'
) && test -n "$TEST_REQUEST_ID"; then
export TEST_REQUEST_ID
printf 'request ID: %s\n' "$TEST_REQUEST_ID"
else
unset TEST_REQUEST_ID
printf 'verification request failed or returned no request ID\n' >&2
false
fi
等待导出器发送该批次,然后在 OTLP 后端查找 aisix.request_id 属性等于 $TEST_REQUEST_ID 的跨度。找到该跨度即可确认端到端投递:网关已加载导出器,在需要时完成目标端认证,且目标端已接受该批次。
在 AISIX Enterprise 或 AISIX Cloud 中,环境的 Observability 视图通过导出器行显示投递是否健康,以及在线网关已发送的批次数。也可以通过 Admin API 查看相同的逐网关心跳数据:
curl -sS "$AISIX_CP/environments/$ENV_ID/dp_nodes" \
-H "Authorization: Bearer $AISIX_TOKEN" \
| jq --arg exporter "$EXPORTER_NAME" \
'[.data[] | select(.status != "offline") | .exporter_health[]? | select(.name == $exporter)]'
下次心跳后,至少一个在线网关应报告大于零的 delivered_batches 和 last_error: null。网关重启或导出器配置变更时,计数器会重置。非空的 last_error 表示当前投递失败。后续成功投递会清除 last_error,但历史字段 failed_batches 和 last_failure_unix 仍会保留数值。
使用开源 AISIX 网关时,请在目标端确认成功。如果记录未到达,请在网关日志中检查 sink delivery failed; retrying 或 sink delivery dropped。
了解投递行为
每个导出器都有自己的投递管道:一个内存队列,后面是一个把记录攒批并发往目标端的后台工作任务。下面这些行为是固定的,没有配置项。
记录会一直缓冲,直到批次达到 100 条记录或经过 1 秒,以先到者为准。
目标端以可恢复的方式拒收一个批次时(连接失败、429 或 5xx),网关按时间预算而不是固定次数重试。延迟从 200 毫秒开始,逐次翻倍,上限为 30 秒;重试会持续到该批次首次尝试之后的 300 秒为止。预算耗尽后,该批次被丢弃,并在 aisix_otlp_fanout_drops_total 中计为 retries_exhausted。429 或 503 响应上的 Retry-After 头会取代计算出的延迟,同样以 30 秒封顶,因此要求更长等待的目标端会被尊重而不是被反复冲击。该预算让批次有机会跨越暂时的接收端故障,但不构成无损保证:即使故障短于 300 秒,队列溢出、永久性投递错误或进程关闭仍可能导致事件丢失。
在一个批次被重试期间,新记录仍在不断到达。每个导出器队列可容纳 8,192 条记录;队列满时被拒收的是最新的那条记录,计为 queue_full,这样已经排队的记录仍有机会送达目标端。
启用了完整内容采集的导出器,其记录由自己持有,包含提示词和响应文本。在 content_max_bytes 取默认值 131,072 的情况下,目标端卡住时装满 8,192 条记录的队列可能占用数百 MB 常驻内存。当你在可能卡住的目标端上启用完整采集时,请结合网关的内存上限来设置 content_max_bytes。请参阅配置内容采集。
解读 OTLP 链路
AISIX 为每个采样请求导出一个相互关联的链路层级。跨度的父子关系、W3C 链路延续、名称、状态、语义约定属性、采集内容和资源字段参见 OTLP 链路参考。