From 14c8d6cce1afa1362ceac8e38b3a742358ba1c2c Mon Sep 17 00:00:00 2001 From: Yilia Lin <114121331+Yilialinn@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:04:41 +0800 Subject: [PATCH 1/8] docs: improve `opentelemetry` plugin docs --- docs/en/latest/plugins/opentelemetry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/latest/plugins/opentelemetry.md b/docs/en/latest/plugins/opentelemetry.md index 09a17a82da07..d38321d01336 100644 --- a/docs/en/latest/plugins/opentelemetry.md +++ b/docs/en/latest/plugins/opentelemetry.md @@ -10,7 +10,7 @@ description: This document contains information about the Apache opentelemetry P + + + + ## Description The `opentelemetry` Plugin can be used to report tracing data according to the [OpenTelemetry specification](https://opentelemetry.io/docs/reference/specification/). The Plugin only supports binary-encoded [OLTP over HTTP](https://opentelemetry.io/docs/reference/specification/protocol/otlp/#otlphttp). -## Attributes - -| Name | Type | Required | Default | Valid values | Description | -|---------------------------------------|---------------|----------|-------------------------------------------------|--------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| sampler | object | False | | | Sampling configuration. | -| sampler.name | string | False | always_off | ["always_on", "always_off", "trace_id_ratio", "parent_base"] | Sampling strategy. `always_on`: always samples, `always_off`: never samples, `trace_id_ratio`: random sampling result based on given sampling probability, `parent_base`: use parent decision if given, else determined by the root sampler. | -| sampler.options | object | False | | {fraction = 0, root = {name = "always_off"}} | Parameters for sampling strategy. | -| sampler.options.fraction | number | False | 0 | [0, 1] | Sampling probability for `trace_id_ratio`. | -| sampler.options.root | object | False | {name = "always_off", options = {fraction = 0}} | | Root sampler for `parent_base` strategy. | -| sampler.options.root.name | string | False | always_off | ["always_on", "always_off", "trace_id_ratio"] | Root sampling strategy. | -| sampler.options.root.options | object | False | {fraction = 0} | | Root sampling strategy parameters. | -| sampler.options.root.options.fraction | number | False | 0 | [0, 1] | Root sampling probability for `trace_id_ratio`. | -| additional_attributes | array[string] | False | | | Additional attributes appended to the trace span. Support built-in NGINX or APISIX variables in values, such as `http_header` or `route_id`. | -| additional_header_prefix_attributes | array[string] | False | | | Headers or header prefixes appended to the trace span's attributes. For example, use `x-my-header"` or `x-my-headers-*` to include all headers with the prefix `x-my-headers-`. | - -### Configuring the collector - -You can set up the collector by configuring it in you configuration file (`conf/config.yaml`): - -| Name | Type | Default | Description | -|--------------------------------------------|---------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| trace_id_source | enum | x-request-id | Source of the trace ID. Valid values are `random` or `x-request-id`. When set to `x-request-id`, the value of the `x-request-id` header will be used as trace ID. Make sure that it matches the regex pattern `[0-9a-f]{32}`. | -| resource | object | | Additional [resource](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md) appended to the trace. | -| collector | object | {address = "127.0.0.1:4318", request_timeout = 3} | OpenTelemetry Collector configuration. | -| collector.address | string | 127.0.0.1:4318 | Collector address. If the collector serves on https, use https://127.0.0.1:4318 as the address. | -| collector.request_timeout | integer | 3 | Report request timeout in seconds. | -| collector.request_headers | object | | Report request HTTP headers. | -| batch_span_processor | object | | Trace span processor. | -| batch_span_processor.drop_on_queue_full | boolean | false | When set to `true`, drops the span when queue is full. Otherwise, force process batches. | -| batch_span_processor.max_queue_size | integer | 1024 | Maximum queue size for buffering spans for delayed processing. | -| batch_span_processor.batch_timeout | number | 2 | Maximum time in seconds for constructing a batch. | -| batch_span_processor.max_export_batch_size | integer | 16 | Maximum number of spans to process in a single batch. | -| batch_span_processor.inactive_timeout | number | 1 | Time interval in seconds between processing batches. | +## Static Configurations -:::note +By default, configurations of the Service name, tenant ID, collector, and batch span processor are pre-configured in [default configuration](https://github.com/apache/apisix/blob/master/apisix/cli/config.lua). -If you find a `bad argument #1 to '?' (invalid value)` error triggered by the `hex2bytes` function in error log, it's essential to verify if your traceId matches the specified regex pattern `[0-9a-f]{32}`, as required by opentelemetry's [traceId format](https://opentelemetry.io/docs/specs/otel/trace/api/#retrieving-the-traceid-and-spanid). +To customize these values, add the corresponding configurations to `config.yaml`. For example: -For instance, a possible scenario occurs when the plugin attribute `trace_id_source` is configured as `x-request-id`, and requests include an x-request-id header generated by Envoy. Envoy typically uses a [UUID](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/observability/tracing#trace-context-propagation) to create this header by default. When the opentelemetry plugin adopts this UUID as the traceId, the presence of hyphens in the UUID can cause issues. Since the UUID format with hyphens does not comply with the expected traceId format, it results in errors when attempting to push traces to the collector. - -::: - -You can configure these as shown below in your configuration file (`conf/config.yaml`): - -```yaml title="conf/config.yaml" +```yaml plugin_attr: opentelemetry: - resource: - service.name: APISIX - tenant.id: business_id + trace_id_source: x-request-id # Specify the source of the trace ID, `x-request-id` or `random`. When set to `x-request-id`, + # the value of the `x-request-id` header will be used as the trace ID. + resource: # Additional resource to append to the trace. + service.name: APISIX # Set the Service name for OpenTelemetry traces. collector: - address: 192.168.8.211:4318 - request_timeout: 3 - request_headers: - foo: bar - batch_span_processor: - drop_on_queue_full: false - max_queue_size: 6 - batch_timeout: 2 - inactive_timeout: 1 - max_export_batch_size: 2 + address: 127.0.0.1:4318 # Set the address of the OpenTelemetry collector to send traces to. + request_timeout: 3 # Set the timeout for requests to the OpenTelemetry collector in seconds. + request_headers: # Set the headers to include in requests to the OpenTelemetry collector. + Authorization: token # Set the authorization header to include an access token. + batch_span_processor: # Trace span processor. + drop_on_queue_full: false # Drop spans when the export queue is full. + max_queue_size: 1024 # Set the maximum size of the span export queue. + batch_timeout: 2 # Set the timeout for span batches to wait in the export queue before + # being sent. + inactive_timeout: 1 # Set the timeout for spans to wait in the export queue before being sent, + # if the queue is not full. + max_export_batch_size: 16 # Set the maximum number of spans to include in each batch sent to the OpenTelemetry collector. + set_ngx_var: false # Export opentelemetry variables to nginx variables. ``` -## Variables +Reload APISIX for changes to take effect. -The following nginx variables are set by OpenTelemetry: +## Attributes -- `opentelemetry_context_traceparent` - [W3C trace context](https://www.w3.org/TR/trace-context/#trace-context-http-headers-format), e.g.: `00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01` -- `opentelemetry_trace_id` - Trace Id of the current span -- `opentelemetry_span_id` - Span Id of the current span +| Name | Type | Required | Default | Valid Values | Description | +|---------------------------------------|---------------|----------|--------------|--------------|-------------| +| sampler | object | False | - | - | Sampling configuration. | +| sampler.name | string | False | `always_off` | `always_on`, `always_off`, `trace_id_ratio`, or `parent_base` | Sampling strategy.
To always sample, use `always_on`.
To never sample, use `always_off`.
To randomly sample based on a given ratio, use `trace_id_ratio`.
To use the sampling decision of the span's parent, use `parent_base`. If there is no parent, use the root sampler. | +| sampler.options | object | False | - | - | Parameters for sampling strategy. | +| sampler.options.fraction | number | False | 0 | [0, 1] | Sampling ratio when the sampling strategy is `trace_id_ratio`. | +| sampler.options.root | object | False | - | - | Root sampler when the sampling strategy is `parent_base` strategy. | +| sampler.options.root.name | string | False | - | `always_on`, `always_off`, or `trace_id_ratio` | Root sampling strategy. | +| sampler.options.root.options | object | False | - | - | Root sampling strategy parameters. | +| sampler.options.root.options.fraction | number | False | 0 | [0, 1] | Root sampling ratio when the sampling strategy is `trace_id_ratio`. | +| additional_attributes | array[string] | False | - | - | Additional attributes appended to the trace span. Support [built-in variables](https://apisix.apache.org/docs/apisix/apisix-variable/) in values. | +| additional_header_prefix_attributes | array[string] | False | - | - | Headers or header prefixes appended to the trace span's attributes. For example, use `x-my-header"` or `x-my-headers-*` to include all headers with the prefix `x-my-headers-`. | -How to use variables? you have to add it to your configuration file (`conf/config.yaml`): +## Examples -```yaml title="conf/config.yaml" -http: - enable_access_log: true - access_log: "/dev/stdout" - 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","uri": "$uri"}' - access_log_format_escape: json -plugins: - - opentelemetry -plugin_attr: - opentelemetry: - set_ngx_var: true -``` +The examples below demonstrate how you can work with the `opentelemetry` Plugin for different scenarios. -## Enable Plugin +### Enable `opentelemetry` Plugin -To enable the Plugin, you have to add it to your configuration file (`conf/config.yaml`): +By default, the `opentelemetry` Plugin is disabled in APISIX. To enable, add the Plugin to your configuration file as such: -```yaml title="conf/config.yaml" +```yaml title="config.yaml" plugins: - ... - opentelemetry ``` -Now, you can enable the Plugin on a specific Route: +Reload APISIX for changes to take effect. + +See [static configurations](#static-configurations) for other available options you can configure in `config.yaml`. -:::note -You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command: +### Send Traces to OpenTelemetry -```bash -admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g') +The following example demonstrates how to trace requests to a Route and send traces to OpenTelemetry. + +Start an OpenTelemetry collector instance in Docker: + +```shell +docker run -d --name otel-collector -p 4318:4318 otel/opentelemetry-collector-contrib ``` -::: +Create a Route with `opentelemetry` Plugin: ```shell -curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "methods": ["GET"], - "uris": [ - "/uid/*" - ], +curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "id": "otel-tracing-route", + "uri": "/anything", "plugins": { - "opentelemetry": { - "sampler": { - "name": "always_on" - } + "opentelemetry": { + "sampler": { + "name": "always_on" } + } }, "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:1980": 1 - } + "type": "roundrobin", + "nodes": { + "httpbin.org": 1 + } } -}' + }' ``` -## Delete Plugin - -To remove the `opentelemetry` Plugin, you can delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect. +Send a request to the Route: ```shell -curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "methods": ["GET"], - "uris": [ - "/uid/*" - ], - "plugins": { - }, - "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:1980": 1 - } - } -}' +curl "http://127.0.0.1:9080/anything" +``` + +You should receive an `HTTP/1.1 200 OK` response. + +In OpenTelemetry collector's log, you should see information similar to the following: + +```text +2024-02-18T17:14:03.825Z info ResourceSpans #0 +Resource SchemaURL: +Resource attributes: + -> telemetry.sdk.language: Str(lua) + -> telemetry.sdk.name: Str(opentelemetry-lua) + -> telemetry.sdk.version: Str(0.1.1) + -> hostname: Str(e34673e24631) + -> service.name: Str(APISIX) +ScopeSpans #0 +ScopeSpans SchemaURL: +InstrumentationScope opentelemetry-lua +Span #0 + Trace ID : fbd0a38d4ea4a128ff1a688197bc58b0 + Parent ID : + ID : af3dc7642104748a + Name : GET /anything + Kind : Server + Start time : 2024-02-18 17:14:03.763244032 +0000 UTC + End time : 2024-02-18 17:14:03.920229888 +0000 UTC + Status code : Unset + Status message : +Attributes: + -> net.host.name: Str(127.0.0.1) + -> http.method: Str(GET) + -> http.scheme: Str(http) + -> http.target: Str(/anything) + -> http.user_agent: Str(curl/7.64.1) + -> apisix.route_id: Str(otel-tracing-route) + -> apisix.route_name: Empty() + -> http.route: Str(/anything) + -> http.status_code: Int(200) +{"kind": "exporter", "data_type": "traces", "name": "debug"} +``` + +To visualize these traces, you can export your telemetry to backend Services, such as Zipkin and Prometheus. See [exporters](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter) for more details. + +### Using Trace Variables in Logging + +The following example demonstrates how to configure the `opentelemetry` Plugin to set the following built-in variables, which can be used in logger Plugins or access logs: + +- `opentelemetry_context_traceparent`: [trace parent](https://www.w3.org/TR/trace-context/#trace-context-http-headers-format) ID +- `opentelemetry_trace_id`: trace ID of the current span +- `opentelemetry_span_id`: span ID of the current span + +Update the configuration file as below. You should customize the access log format to use the `opentelemetry` Plugin variables, and set `opentelemetry` variables in the `set_ngx_var` field. + +```yaml title="conf/config.yaml" +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 +plugin_attr: + opentelemetry: + set_ngx_var: true +``` + +Reload APISIX for configuration changes to take effect. + +You should see access log entries similar to the following when you generate requests: + +```text +{"time": "18/Feb/2024:15:09:00 +0000","opentelemetry_context_traceparent": "00-fbd0a38d4ea4a128ff1a688197bc58b0-8f4b9d9970a02629-01","opentelemetry_trace_id": "fbd0a38d4ea4a128ff1a688197bc58b0","opentelemetry_span_id": "af3dc7642104748a","remote_addr": "172.10.0.1"} ``` From b8b31b1fbb26379b5ebe665ac6f092530cd61dea Mon Sep 17 00:00:00 2001 From: Yilia Lin <114121331+Yilialinn@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:22:21 +0800 Subject: [PATCH 3/8] Update docs/en/latest/plugins/opentelemetry.md Co-authored-by: Traky Deng --- docs/en/latest/plugins/opentelemetry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/latest/plugins/opentelemetry.md b/docs/en/latest/plugins/opentelemetry.md index 3d0ece722b13..d9517a01afdd 100644 --- a/docs/en/latest/plugins/opentelemetry.md +++ b/docs/en/latest/plugins/opentelemetry.md @@ -5,7 +5,7 @@ keywords: - API Gateway - Plugin - OpenTelemetry -description: The `opentelemetry` Plugin instruments APISIX and sends traces to OpenTelemetry collector based on the OpenTelemetry specification, in binary-encoded OLTP over HTTP. +description: The opentelemetry Plugin instruments APISIX and sends traces to OpenTelemetry collector based on the OpenTelemetry specification, in binary-encoded OLTP over HTTP. --- + + + + ## 描述 -`opentelemetry` 插件可用于根据 [OpenTelemetry specification](https://opentelemetry.io/docs/reference/specification/) 协议规范上报 Tracing 数据。 +`opentelemetry` 插件可用于根据 [OpenTelemetry Specification](https://opentelemetry.io/docs/reference/specification/) 协议规范上报 Traces 数据。该插件仅支持二进制编码的 OLTP over HTTP,即请求类型为 `application/x-protobuf` 的数据上报。 -该插件仅支持二进制编码的 [OLTP over HTTP](https://opentelemetry.io/docs/reference/specification/protocol/otlp/#otlphttp),即请求类型为 `application/x-protobuf` 的数据上报。 +## 静态配置 -## 属性 +默认情况下,服务名称、租户 ID、collector 和 batch span processor 的配置已预配置在[默认配置](https://github.com/apache/apisix/blob/master/apisix/cli/config.lua)中。 + +要自定义这些值,请将相应的配置添加到 `config.yaml` 中。例如: -| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | -| ------------------------------------- | ------------- | ------ | ----------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------- | -| sampler | object | 否 | | | 采样策略。 | -| sampler.name | string | 否 | always_off | ["always_on", "always_off", "trace_id_ratio", "parent_base"] | 采样策略。`always_on`:全采样;`always_off`:不采样;`trace_id_ratio`:基于 trace id 的百分比采样;`parent_base`:如果存在 tracing 上游,则使用上游的采样决定,否则使用配置的采样策略决策。 | -| sampler.options | object | 否 | | {fraction = 0, root = {name = "always_off"}} | 采样策略参数。 | -| sampler.options.fraction | number | 否 | 0 | [0, 1] | `trace_id_ratio` 采样策略的百分比。 | -| sampler.options.root | object | 否 | {name = "always_off", options = {fraction = 0}} | | `parent_base` 采样策略在没有上游 tracing 时,会使用 root 采样策略做决策。 | -| sampler.options.root.name | string | 否 | always_off | ["always_on", "always_off", "trace_id_ratio"] | root 采样策略。 | -| sampler.options.root.options | object | 否 | {fraction = 0} | | root 采样策略参数。 | -| sampler.options.root.options.fraction | number | 否 | 0 | [0, 1] | `trace_id_ratio` root 采样策略的百分比 | -| additional_attributes | array[string] | 否 | | | 追加到 trace span 的额外属性,支持内置 NGINX 或 APISIX 变量,例如:`http_header` 或者 `route_id`。 | -| additional_header_prefix_attributes | array[string] | False | | | 附加到跟踪范围属性的标头或标头前缀。例如,使用 `x-my-header"` 或 `x-my-headers-*` 来包含带有前缀 `x-my-headers-` 的所有标头。 | - -## 如何设置数据上报 - -你可以通过在 `conf/config.yaml` 中指定配置来设置数据上报: - -| 名称 | 类型 | 默认值 | 描述 | -| ------------------------------------------ | ------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | -| trace_id_source | enum | x-request-id | trace ID 的来源。有效值为:`random` 或 `x-request-id`。当设置为 `x-request-id` 时,`x-request-id` 头的值将用作跟踪 ID。请确保当前请求 ID 是符合 TraceID 规范的:`[0-9a-f]{32}`。 | -| resource | object | | 追加到 trace 的额外 [resource](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md)。 | -| collector | object | {address = "127.0.0.1:4318", request_timeout = 3} | OpenTelemetry Collector 配置。 | -| collector.address | string | 127.0.0.1:4318 | 数据采集服务的地址。如果数据采集服务使用的是 HTTPS 协议,可以将 address 设置为 https://127.0.0.1:4318。 | -| collector.request_timeout | integer | 3 | 数据采集服务上报请求超时时长,单位为秒。 | -| collector.request_headers | object | | 数据采集服务上报请求附加的 HTTP 请求头。 | -| batch_span_processor | object | | trace span 处理器参数配置。 | -| batch_span_processor.drop_on_queue_full | boolean | false | 如果设置为 `true` 时,则在队列排满时删除 span。否则,强制处理批次。| -| batch_span_processor.max_queue_size | integer | 1024 | 处理器缓存队列容量的最大值。 | -| batch_span_processor.batch_timeout | number | 2 | 构造一批 span 超时时间,单位为秒。 | -| batch_span_processor.max_export_batch_size | integer | 16 | 单个批次中要处理的 span 数量。 | -| batch_span_processor.inactive_timeout | number | 1 | 两个处理批次之间的时间间隔,单位为秒。 | - -:::note - -如果你在 error log 中发现由 hex2bytes 函数引发的 `bad argument #1 to '?' (invalid value)` 错误,务必确认你的 traceId 是否满足 opentelemetry 的 [traceId 格式](https://opentelemetry.io/docs/specs/otel/trace/api/#retrieving-the-traceid-and-spanid) 所需的正则规范`[0-9a-f]{32}`。 - -例如,当插件属性 `trace_id_source` 配置为 `x-request-id` 时,如果请求包含由 Envoy 生成的 x-request-id 请求头,可能会发生上述情况。Envoy 默认使用 [UUID](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/observability/tracing#trace-context-propagation) 生成该请求头。当 opentelemetry 插件将此 UUID 作为 traceId 时,UUID 中的 `-` 可能会引起问题。由于带有 `-` 的 UUID 格式与 traceId 格式不符,因此尝试将跟踪推送到收集器时会导致错误。 - -::: - -你可以参考以下示例进行配置: - -```yaml title="./conf/config.yaml" +```yaml plugin_attr: opentelemetry: - resource: - service.name: APISIX - tenant.id: business_id + trace_id_source: x-request-id # 指定追踪 ID 的来源,`x-request-id` 或 `random`。当设置为 `x-request-id` 时, + # `x-request-id` 头的值将用作追踪 ID。 + resource: # 追加到追踪的额外资源。 + service.name: APISIX # 为 OpenTelemetry 追踪设置服务名称。 collector: - address: 192.168.8.211:4318 - request_timeout: 3 - request_headers: - foo: bar - batch_span_processor: - drop_on_queue_full: false - max_queue_size: 6 - batch_timeout: 2 - inactive_timeout: 1 - max_export_batch_size: 2 + address: 127.0.0.1:4318 # 设置要发送追踪的 OpenTelemetry 收集器的地址。 + request_timeout: 3 # 设置请求 OpenTelemetry 收集器的超时时间(秒)。 + request_headers: # 设置请求 OpenTelemetry 收集器时要包含的头信息。 + 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 # 设置每个批次发送到 OpenTelemetry 收集器的跨度的最大数量。 + set_ngx_var: false # 将 opentelemetry 变量导出到 nginx 变量。 ``` -## 如何使用变量 +重新加载 APISIX 以使更改生效。 -以下`nginx`变量是由`opentelemetry` 设置的。 +## 属性 -- `opentelemetry_context_traceparent` - [W3C trace context](https://www.w3.org/TR/trace-context/#trace-context-http-headers-format), 例如:`00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01` -- `opentelemetry_trace_id` - 当前 span 的 trace_id -- `opentelemetry_span_id` - 当前 span 的 span_id +| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | +|---------------------------------------|---------------|----------|--------------|--------------|-------------| +| sampler | object | 否 | - | - | 采样策略。 | +| sampler.name | string | False | `always_off` | ["always_on", "always_off", "trace_id_ratio", "parent_base"] | 采样策略。
`always_on`:全采样;`always_off`:不采样;`trace_id_ratio`:基于 trace id 的百分比采样;`parent_base`:如果存在 tracing 上游,则使用上游的采样决定,否则使用配置的采样策略决策。| +| sampler.options | object | 否 | - | - | 采样策略参数。 | +| sampler.options.fraction | number | 否 | 0 | [0, 1] | `trace_id_ratio`:采样策略的百分比。 | +| sampler.options.root | object | 否 | - | - | `parent_base`:采样策略在没有上游 tracing 时,会使用 root 采样策略做决策。| +| sampler.options.root.name | string | 否 | - | ["always_on", "always_off", "trace_id_ratio"] | root 采样策略。 | +| sampler.options.root.options | object | 否 | - | - | root 采样策略参数。 | +| sampler.options.root.options.fraction | number | 否 | 0 | [0, 1] | `trace_id_ratio` root 采样策略的百分比| +| additional_attributes | array[string] | 否 | - | - | 追加到 trace span 的额外属性,支持内置 NGINX 或 [APISIX 变量](https://apisix.apache.org/docs/apisix/apisix-variable/)。| +| additional_header_prefix_attributes | array[string] | 否 | - | - | 附加到跟踪范围属性的标头或标头前缀。例如,使用 `x-my-header"` 或 `x-my-headers-*` 来包含带有前缀 `x-my-headers-` 的所有标头。 | -如何使用?你需要在配置文件(`./conf/config.yaml`)设置如下: +## 示例 -```yaml title="./conf/config.yaml" -http: - enable_access_log: true - access_log: "/dev/stdout" - 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","uri": "$uri"}' - access_log_format_escape: json -plugins: - - opentelemetry -plugin_attr: - opentelemetry: - set_ngx_var: true -``` +以下示例展示了如何在不同场景下使用 `opentelemetry` 插件。 -## 如何启用 +### 启用 opentelemetry 插件 -`opentelemetry` 插件默认为禁用状态,你需要在配置文件(`./conf/config.yaml`)中开启该插件: +默认情况下,APISIX 中的 `opentelemetry` 插件是禁用的。要启用它,请将插件添加到配置文件中,如下所示: -```yaml title="./conf/config.yaml" +```yaml title="config.yaml" plugins: - - ... # plugin you need + - ... - opentelemetry ``` -开启成功后,可以通过如下命令在指定路由上启用 `opentelemetry` 插件: +重新加载 APISIX 以使更改生效。 + +有关 `config.yaml` 中可以配置的其他选项,请参阅[静态配置](#静态配置)。 -:::note +### 将 Traces 上报到 OpenTelemetry -您可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量: +以下示例展示了如何追踪对路由的请求并将 traces 发送到 OpenTelemetry。 -```bash -admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g') +在 Docker 启动一个 OpenTelemetry collector 实例: + +```shell +docker run -d --name otel-collector -p 4318:4318 otel/opentelemetry-collector-contrib ``` -::: +创建一个开启了 `opentelemetry` 插件的路由: ```shell -curl http://127.0.0.1:9180/apisix/admin/routes/1 \ --H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "methods": ["GET"], - "uris": [ - "/uid/*" - ], +curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ + -H "X-API-KEY: ${admin_key}" \ + -d '{ + "id": "otel-tracing-route", + "uri": "/anything", "plugins": { - "opentelemetry": { - "sampler": { - "name": "always_on" - } + "opentelemetry": { + "sampler": { + "name": "always_on" } + } }, "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:1980": 1 - } + "type": "roundrobin", + "nodes": { + "httpbin.org": 1 + } } -}' + }' ``` -## 删除插件 - -当你需要禁用 `opentelemetry` 插件时,可以通过以下命令删除相应的 JSON 配置,APISIX 将会自动重新加载相关配置,无需重启服务: +向路由发送请求: ```shell -curl http://127.0.0.1:9180/apisix/admin/routes/1 \ --H "X-API-KEY: $admin_key" -X PUT -d ' -{ - "methods": ["GET"], - "uris": [ - "/uid/*" - ], - "plugins": { - }, - "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:1980": 1 - } - } -}' +curl "http://127.0.0.1:9080/anything" +``` + +你应该收到一个 `HTTP/1.1 200 OK` 响应。 + +在 OpenTelemetry collector 的日志中,你应该看到类似以下的信息: + +```text +2024-02-18T17:14:03.825Z info ResourceSpans #0 +Resource SchemaURL: +Resource attributes: + -> telemetry.sdk.language: Str(lua) + -> telemetry.sdk.name: Str(opentelemetry-lua) + -> telemetry.sdk.version: Str(0.1.1) + -> hostname: Str(e34673e24631) + -> service.name: Str(APISIX) +ScopeSpans #0 +ScopeSpans SchemaURL: +InstrumentationScope opentelemetry-lua +Span #0 + Trace ID : fbd0a38d4ea4a128ff1a688197bc58b0 + Parent ID : + ID : af3dc7642104748a + Name : GET /anything + Kind : Server + Start time : 2024-02-18 17:14:03.763244032 +0000 UTC + End time : 2024-02-18 17:14:03.920229888 +0000 UTC + Status code : Unset + Status message : +Attributes: + -> net.host.name: Str(127.0.0.1) + -> http.method: Str(GET) + -> http.scheme: Str(http) + -> http.target: Str(/anything) + -> http.user_agent: Str(curl/7.64.1) + -> apisix.route_id: Str(otel-tracing-route) + -> apisix.route_name: Empty() + -> http.route: Str(/anything) + -> http.status_code: Int(200) +{"kind": "exporter", "data_type": "traces", "name": "debug"} +``` + +要可视化这些追踪,你可以将 traces 导出到后端服务,例如 Zipkin 和 Prometheus。有关更多详细信息,请参阅[exporters](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter)。 + +### 在日志中使用 trace 变量 + +以下示例展示了如何配置 `opentelemetry` 插件以设置以下内置变量,这些变量可以在日志插件或访问日志中使用: + +- `opentelemetry_context_traceparent`: [W3C trace context](https://www.w3.org/TR/trace-context/#trace-context-http-headers-format) +- `opentelemetry_trace_id`: 当前 span 的 trace_id +- `opentelemetry_span_id`: 当前 span 的 span_id + +如下更新配置文件。你应该自定义访问日志格式以使用 `opentelemetry` 插件变量,并在 `set_ngx_var` 字段中设置 `opentelemetry` 变量。 + +```yaml title="conf/config.yaml" +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 +plugin_attr: + opentelemetry: + set_ngx_var: true +``` + +重新加载 APISIX 以使配置更改生效。 + +```text +{"time": "18/Feb/2024:15:09:00 +0000","opentelemetry_context_traceparent": "00-fbd0a38d4ea4a128ff1a688197bc58b0-8f4b9d9970a02629-01","opentelemetry_trace_id": "fbd0a38d4ea4a128ff1a688197bc58b0","opentelemetry_span_id": "af3dc7642104748a","remote_addr": "172.10.0.1"} ``` From f4a39920559c180ec83b2b0b0a74f796af14f21c Mon Sep 17 00:00:00 2001 From: Yilia Date: Thu, 16 Jan 2025 14:41:23 +0800 Subject: [PATCH 7/8] update description --- docs/zh/latest/plugins/opentelemetry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/latest/plugins/opentelemetry.md b/docs/zh/latest/plugins/opentelemetry.md index 0116e0f5926b..487911549ed1 100644 --- a/docs/zh/latest/plugins/opentelemetry.md +++ b/docs/zh/latest/plugins/opentelemetry.md @@ -5,7 +5,7 @@ keywords: - API 网关 - Plugin - OpenTelemetry -description: 本文介绍了关于 Apache APISIX `opentelemetry` 插件的基本信息及使用方法。 +description: opentelemetry 插件可用于根据 OpenTelemetry 协议规范上报 Traces 数据,该插件仅支持二进制编码的 OLTP over HTTP。 ---