配置分布式追踪
分布式追踪可以端到端展示请求经过 API7 网关和后端服务的路径。API7 网关使用 opentelemetry 插件生成跨度,并通过 OTLP/HTTP 将其发送到 Jaeger、Tempo、OpenTelemetry Collector、Honeycomb、Datadog、New Relic、AWS X-Ray 等兼容 Collector。
工作原理
opentelemetry 插件有两层配置:
- 插件元数据:由网关组中的所有路由共享,控制 Collector 端点、请求超时、自定义标头、批量跨度处理器和 Trace ID 来源。每个网关组通过
/apisix/admin/plugin_metadata/opentelemetry设置一次。 - 路由插件配置:设置在路由、Service 或全局规则上,控制采样策略和匹配流量的额外跨度属性。
在任何路由产生有用跨度之前,必须至少为网关组配置一次插件元数据。
前置条件
- 运行中的 API7 网关部署,且至少有一个在线数据面;
- 数据面可以访问 OTLP/HTTP Collector(以下示例使用 Jaeger 的
4318端口); - 令牌管理。
步骤一:配置 Collector 端点
在插件元数据中设置 Collector 地址。生产环境应根据流量调整批量跨度处理器和请求超时;默认的 127.0.0.1:4318 和 3 秒超时通常不适用。
- Admin API
- ADC
curl -k "https://localhost:7443/apisix/admin/plugin_metadata/opentelemetry?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"trace_id_source": "x-request-id",
"resource": {
"service.name": "api7-gateway",
"deployment.environment": "production"
},
"collector": {
"address": "jaeger:4318",
"request_timeout": 3
},
"set_ngx_var": true
}'
plugin_metadata:
opentelemetry:
trace_id_source: x-request-id
resource:
service.name: api7-gateway
deployment.environment: production
collector:
address: "jaeger:4318"
request_timeout: 3
set_ngx_var: true
adc sync -f adc.yaml
set_ngx_var: true 会将 Trace ID 和 Span ID 暴露为 $opentelemetry_trace_id 与 $opentelemetry_span_id NGINX 变量,用于关联追踪和访问日志。如果 Collector 需要认证,请在 collector.request_headers 下添加标头。
步骤二:在路由上启用追踪
启用插件并选择采样策略。默认采样器为 always_off,必须显式设置采样器才能开始捕获链路。以下示例先创建 Service 和路由,再通过全局规则覆盖网关组中的所有路由:
- Admin API
- ADC
# 创建带上游的 Service
curl -k "https://localhost:7443/apisix/admin/services/tracing-demo?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "tracing-demo",
"upstream": {
"type": "roundrobin",
"nodes": [
{ "host": "httpbin.org", "port": 80, "weight": 1 }
]
}
}'
# 创建路由
curl -k "https://localhost:7443/apisix/admin/routes/tracing-demo?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "tracing-demo",
"service_id": "tracing-demo",
"paths": ["/anything"]
}'
# 通过全局规则为所有请求启用追踪
curl -k "https://localhost:7443/apisix/admin/global_rules/opentelemetry?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"plugins": {
"opentelemetry": {
"sampler": {
"name": "trace_id_ratio",
"options": { "fraction": 1.0 }
},
"additional_attributes": ["consumer_name", "request_uri"]
}
}
}'
global_rules:
opentelemetry:
sampler:
name: trace_id_ratio
options:
fraction: 1.0
additional_attributes:
- consumer_name
- request_uri
adc sync -f adc.yaml
additional_attributes 中的值使用 APISIX 变量名,例如 consumer_name、request_uri 和 route_name。插件还会自动附加 http.route、http.status_code、apisix.route_name 等 OpenTelemetry 语义属性。
选择采样策略
| 策略 | 使用场景 |
|---|---|
always_on | 开发、预发布或低流量路由,需要追踪每个请求。 |
trace_id_ratio | 生产环境。选择如 0.01(1%)的比例,以限制 Collector 负载 和存储成本。 |
parent_base | 上游服务或 Service Mesh 已经决定采样时,网关遵循其决定。 |
always_off | 默认策略。保留插件但暂时停止生成跨度。 |
生产环境常用 parent_base 配合低比例 trace_id_ratio 根采样器:
{
"sampler": {
"name": "parent_base",
"options": {
"root": {
"name": "trace_id_ratio",
"options": { "fraction": 0.01 }
}
}
}
}
步骤三:验证
通过网关发送请求:
curl -i "http://127.0.0.1:9080/anything"
打开 Collector 的 UI(Jaeger 使用 http://127.0.0.1:16686),搜索服务 api7-gateway。你应看到以请求方法和路径命名的跨度,例如 GET /anything,以及 http.status_code、apisix.route_name=tracing-demo 和 request_uri 等属性。
关联追踪和访问日志
当插件元数据中设置了 set_ngx_var: true 时,可将 Trace ID 和 Span ID 加入访问日志格式:
nginx_config:
http:
access_log_format: '{"time": "$time_iso8601","trace_id": "$opentelemetry_trace_id","span_id": "$opentelemetry_span_id","remote_addr": "$remote_addr","status": "$status"}'
access_log_format_escape: json
同样的变量也可在 http-logger 或 kafka-logger 插件的 log_format 字段中使用。