跳到主要内容
版本:3.9.x

追踪 API 流量

追踪(Traces)与指标(Metrics)和日志(Logs)并称为可观测性的三大支柱。追踪记录了一个请求在系统各个部分中穿梭的过程。这是一种有效的机制,可帮助开发人员和管理员监控系统性能、识别瓶颈并改善用户体验。

本教程将指导你如何使用 opentelemetry 插件创建追踪。该插件对网关进行插桩,并基于 OpenTelemetry 规范,通过 HTTP 将二进制编码的 OTLP 格式的追踪发送到 OpenTelemetry Collector。以下是一个交互式演示,为你提供实际操作介绍。

前置条件

  1. 在网关组上运行一个 API 并创建路由

安装 OpenTelemetry

虽然本节中的步骤使用了特定的 OpenTelemetry Collector,但你也可以使用其他发行版的 Collector,例如 SigNoz OpenTelemetry Collector。它们都能处理遥测数据,但在侧重点、功能和集成的灵活性上有所不同。

启动一个 OpenTelemetry Collector 实例:

docker run -d --name otel-collector -p 4318:4318 otel/opentelemetry-collector-contrib

配置 OpenTelemetry 元数据

在本节中,你将配置 opentelemetry 插件的元数据,该元数据指定了连接接口和其他参数。

  1. 从侧边导航栏中选择你网关组的 Plugin Settings(插件设置)。

  2. 选择 Plugin Metadata(插件元数据)选项卡,然后点击 Add Plugin Metadata(添加插件元数据)。

  3. 搜索 opentelemetry 插件,然后点击 Add Metadata(添加元数据)。

  4. 在出现的对话框中,将以下配置添加到 JSON Editor 中,并将 collector 地址替换为你的 IP:

    {
    "trace_id_source": "x-request-id",
    "resource": {
    "service.name": "API7"
    },
    "collector": {
    "address": "192.168.2.106:4318",
    "request_timeout": 3,
    "request_headers": {
    "Authorization": "token"
    }
    },
    "batch_span_processor": {
    "drop_on_queue_full": false,
    "max_queue_size": 1024,
    "batch_timeout": 2,
    "inactive_timeout": 1,
    "max_export_batch_size": 16
    },
    "set_ngx_var": true
    }
  5. 点击 Save(保存)。

将 OpenTelemetry 配置为全局插件

在本示例中,你将配置 opentelemetry 作为全局插件来追踪所有请求。

  1. 从侧边导航栏中选择你网关组的 Plugin Settings(插件设置)。
  2. 选择 Plugin Global Rules(插件全局规则)选项卡,然后点击 Add Plugin(添加插件)。
  3. 搜索 opentelemetry 插件,然后点击 Add(添加)。
  4. 在出现的对话框中,将以下配置添加到 JSON Editor 中:
  {
"opentelemetry": {
"sampler": {
"name": "always_on"
}
}
}
  1. 点击 Add(添加)。

验证

假设你已完成 发布你的第一个 API 中的步骤并创建了一个示例路由。

向该路由发送一些请求:

curl "http://127.0.0.1:9080/ip"

在 OpenTelemetry collector 的日志中,你应该能看到从网关流量中收集的追踪信息:

{"resource": {"service.instance.id": "c4a2503a-f1e7-4077-9e1e-f139da86442f", "service.name": "otelcol", "service.version": "0.136.0"}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces", "resource spans": 1, "spans": 1}

在路由上配置 OpenTelemetry

在本示例中,你将在单个路由上配置 opentelemetry 插件,该插件只会追踪访问此路由的请求。

  1. 点击进入你的服务以创建一个新路由或更新现有的 /ip 路由。
  2. 点击 Add Plugin(添加插件)。
  3. 搜索 opentelemetry 插件,然后点击 Add(添加)。
  4. 在出现的对话框中,将以下配置添加到 JSON Editor 中:
  {
"opentelemetry": {
"sampler": {
"name": "always_on"
}
}
}
  1. 点击 Add(添加)。

验证

向该路由发送一些请求:

curl "http://127.0.0.1:9080/ip"

在 OpenTelemetry collector 的日志中,你应该能看到从网关流量中收集的追踪信息:

{"resource": {"service.instance.id": "c4a2503a-f1e7-4077-9e1e-f139da86442f", "service.name": "otelcol", "service.version": "0.136.0"}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "traces", "resource spans": 1, "spans": 1}

在网关访问日志中使用 Trace 变量

在本示例中,你将更新网关的配置,以使访问日志显示 OpenTelemetry 的追踪信息。请确保已在 插件元数据 中将 set_ngx_var 设置为 true

更新网关配置文件中的日志格式配置:

docker exec <api7-ee-gateway-container-name> /bin/sh -c "echo '
nginx_config:
http:
enable_access_log: true
access_log_format: \"{\\\"time\\\": \\\"\$time_iso8601\\\",\\\"opentelemetry_context_traceparent\\\": \\\"\$opentelemetry_context_traceparent\\\",\\\"opentelemetry_trace_id\\\": \\\"\$opentelemetry_trace_id\\\",\\\"opentelemetry_span_id\\\": \\\"\$opentelemetry_span_id\\\",\\\"remote_addr\\\": \\\"\$remote_addr\\\"}\"
access_log_format_escape: json
' > /usr/local/apisix/conf/config.yaml"

重新加载容器以使配置更改生效:

docker exec <api7-ee-gateway-container-name> apisix reload

验证

假设你已完成 发布你的第一个 API 中的步骤并创建了一个示例路由。

向该路由发送一些请求:

curl "http://127.0.0.1:9080/ip"

在网关的日志中,你应该会看到类似于以下的访问日志:

{"time": "2025-10-10T10:00:33+00:00","opentelemetry_context_traceparent": "00-dd43f6275874022ef5fe6c470b4fee89-c099993cd4ad537a-01","opentelemetry_trace_id": "dd43f6275874022ef5fe6c470b4fee89","opentelemetry_span_id": "c099993cd4ad537a","remote_addr": "127.0.0.1"}
{"time": "2025-10-10T10:01:17+00:00","opentelemetry_context_traceparent": "00-830ec1895f16da34063e3a5c5b96c1fb-06ca189db60cba2a-01","opentelemetry_trace_id": "830ec1895f16da34063e3a5c5b96c1fb","opentelemetry_span_id": "06ca189db60cba2a","remote_addr": "127.0.0.1"}