From 222de2921de5e7dde881cc6f79f4abdfc1e09827 Mon Sep 17 00:00:00 2001 From: xiongpan828 Date: Sun, 14 Jun 2026 11:41:09 +0800 Subject: [PATCH 1/2] feat(opentelemetry): Supports injecting custom attributes into open telemetry --- apisix/plugins/opentelemetry.lua | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/apisix/plugins/opentelemetry.lua b/apisix/plugins/opentelemetry.lua index 333e6816fa32..752d81cd69d6 100644 --- a/apisix/plugins/opentelemetry.lua +++ b/apisix/plugins/opentelemetry.lua @@ -184,6 +184,11 @@ local schema = { type = "string", minLength = 1, } + }, + additional_custom_attributes = { + type = "object", + description = "custom attributes string kv map", + additionalProperties = {type = "string"}, } } } @@ -504,6 +509,21 @@ function _M.log(conf, api_ctx) ) end + if conf.additional_custom_attributes then + -- get keys + local custom_keys = {} + for key,_ in pairs(conf.additional_custom_attributes) do + table.insert(custom_keys, key) + end + -- inject attributes + inject_attributes( + attributes, + custom_keys, + conf.additional_custom_attributes, + false + ) + end + for i = 1, #attributes do span:set_attributes(attributes[i]) end From 35b0ed610ac5214b77d22b062e1b07f42b0434a2 Mon Sep 17 00:00:00 2001 From: xiongpan828 Date: Sun, 14 Jun 2026 12:04:01 +0800 Subject: [PATCH 2/2] feat: add docs and test --- docs/en/latest/plugins/opentelemetry.md | 1 + docs/zh/latest/plugins/opentelemetry.md | 1 + t/plugin/opentelemetry.t | 60 +++++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/docs/en/latest/plugins/opentelemetry.md b/docs/en/latest/plugins/opentelemetry.md index 298563a131bd..fdedb98a759b 100644 --- a/docs/en/latest/plugins/opentelemetry.md +++ b/docs/en/latest/plugins/opentelemetry.md @@ -90,6 +90,7 @@ curl http://127.0.0.1:9180/apisix/admin/plugin_metadata/opentelemetry -H "X-API- | 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-`. | +| additional_custom_attributes | object | False | - | - | Custom attributes string key-value map appended to the trace span. Both keys and values must be strings. For example, `{"custom.key1": "value1", "custom.key2": "value2"}`. | ## Examples diff --git a/docs/zh/latest/plugins/opentelemetry.md b/docs/zh/latest/plugins/opentelemetry.md index fe15e748858d..2a82b319833f 100644 --- a/docs/zh/latest/plugins/opentelemetry.md +++ b/docs/zh/latest/plugins/opentelemetry.md @@ -89,6 +89,7 @@ curl http://127.0.0.1:9180/apisix/admin/plugin_metadata/opentelemetry -H "X-API- | 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-` 的所有标头。 | +| additional_custom_attributes | object | 否 | - | - | 追加到 trace span 的自定义属性字符串键值映射。键和值都必须为字符串类型。例如,`{"custom.key1": "value1", "custom.key2": "value2"}`。 | ## 示例 diff --git a/t/plugin/opentelemetry.t b/t/plugin/opentelemetry.t index a260a62a21bd..2d72a0b23863 100644 --- a/t/plugin/opentelemetry.t +++ b/t/plugin/opentelemetry.t @@ -644,3 +644,63 @@ opentracing tail -n 1 ci/pod/otelcol-contrib/data-otlp.json --- response_body eval qr/.*x-injected-by-plugin.*test-value.*/ + + + +=== TEST 29: set additional_custom_attributes +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "name": "route_name", + "plugins": { + "opentelemetry": { + "sampler": { + "name": "always_on" + }, + "additional_custom_attributes": { + "custom.attr1": "custom_value_1", + "custom.attr2": "custom_value_2" + } + } + }, + "uri": "/opentracing", + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t + + + +=== TEST 30: trigger opentelemetry with additional_custom_attributes +--- request +GET /opentracing +--- more_headers +X-Request-Id: 01010101010101010101010101010104 +--- wait: 2 +--- response_body +opentracing + + + +=== TEST 31: check custom attributes in span +--- exec +tail -n 1 ci/pod/otelcol-contrib/data-otlp.json +--- response_body eval +qr/.*custom\.attr1.*custom_value_1.*custom\.attr2.*custom_value_2.*/