From aa6d7b08395066ed032470ed63bafff85799942a Mon Sep 17 00:00:00 2001 From: zirain Date: Wed, 14 Jan 2026 14:20:20 +0800 Subject: [PATCH 1/5] marked as Deprecated Signed-off-by: zirain --- api/v1alpha1/shared_types.go | 2 ++ ....envoyproxy.io_backendtrafficpolicies.yaml | 2 ++ .../gateway.envoyproxy.io_envoyproxies.yaml | 2 ++ ....envoyproxy.io_backendtrafficpolicies.yaml | 2 ++ .../gateway.envoyproxy.io_envoyproxies.yaml | 2 ++ site/content/en/latest/api/extension_types.md | 4 +-- .../latest/tasks/observability/proxy-trace.md | 32 +++++++++++++++++++ test/helm/gateway-crds-helm/all.out.yaml | 4 +++ .../envoy-gateway-crds.out.yaml | 4 +++ 9 files changed, 52 insertions(+), 2 deletions(-) diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go index 5f1438a294..343f1210c8 100644 --- a/api/v1alpha1/shared_types.go +++ b/api/v1alpha1/shared_types.go @@ -863,6 +863,8 @@ type Tracing struct { // CustomTags defines the custom tags to add to each span. // If provider is kubernetes, pod name and namespace are added by default. // + // Deprecated: Use Tags instead. + // // +optional CustomTags map[string]CustomTag `json:"customTags,omitempty"` // Tags defines the custom tags to add to each span. diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 83a79f13b6..5915859840 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -2418,6 +2418,8 @@ spec: description: |- CustomTags defines the custom tags to add to each span. If provider is kubernetes, pod name and namespace are added by default. + + Deprecated: Use Tags instead. type: object samplingFraction: description: |- diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml index 48e9e92049..f5e7979998 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml @@ -15045,6 +15045,8 @@ spec: description: |- CustomTags defines the custom tags to add to each span. If provider is kubernetes, pod name and namespace are added by default. + + Deprecated: Use Tags instead. type: object provider: description: Provider defines the tracing provider. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 053af4985a..1b554aa324 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -2417,6 +2417,8 @@ spec: description: |- CustomTags defines the custom tags to add to each span. If provider is kubernetes, pod name and namespace are added by default. + + Deprecated: Use Tags instead. type: object samplingFraction: description: |- diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml index bb5c66eb20..775671bc8f 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml @@ -15044,6 +15044,8 @@ spec: description: |- CustomTags defines the custom tags to add to each span. If provider is kubernetes, pod name and namespace are added by default. + + Deprecated: Use Tags instead. type: object provider: description: Provider defines the tracing provider. diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 75d7c6b879..cf4903007a 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -4252,7 +4252,7 @@ _Appears in:_ | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `samplingFraction` | _[Fraction](https://gateway-api.sigs.k8s.io/reference/1.4/spec/#fraction)_ | false | | SamplingFraction represents the fraction of requests that should be
selected for tracing if no prior sampling decision has been made. | -| `customTags` | _object (keys:string, values:[CustomTag](#customtag))_ | false | | CustomTags defines the custom tags to add to each span.
If provider is kubernetes, pod name and namespace are added by default. | +| `customTags` | _object (keys:string, values:[CustomTag](#customtag))_ | false | | CustomTags defines the custom tags to add to each span.
If provider is kubernetes, pod name and namespace are added by default.
Deprecated: Use Tags instead. | | `tags` | _object (keys:string, values:string)_ | false | | Tags defines the custom tags to add to each span.
Envoy [command operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators) may be used in the value.
The [format string documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#config-access-log-format-strings) provides more information.
If provider is kubernetes, pod name and namespace are added by default.
Same keys take precedence over CustomTags. | | `spanName` | _[TracingSpanName](#tracingspanname)_ | false | | SpanName defines the name of the span which will be used for tracing.
Envoy [command operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators) may be used in the value.
The [format string documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#config-access-log-format-strings) provides more information.
If not set, the span name is provider specific.
e.g. Datadog use `ingress` as the default client span name,
and `router egress` as the server span name. | | `samplingRate` | _integer_ | false | | SamplingRate controls the rate at which traffic will be
selected for tracing if no prior sampling decision has been made.
Defaults to 100, valid values [0-100]. 100 indicates 100% sampling.
Only one of SamplingRate or SamplingFraction may be specified.
If neither field is specified, all requests will be sampled. | @@ -5329,7 +5329,7 @@ _Appears in:_ | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | `samplingFraction` | _[Fraction](https://gateway-api.sigs.k8s.io/reference/1.4/spec/#fraction)_ | false | | SamplingFraction represents the fraction of requests that should be
selected for tracing if no prior sampling decision has been made. | -| `customTags` | _object (keys:string, values:[CustomTag](#customtag))_ | false | | CustomTags defines the custom tags to add to each span.
If provider is kubernetes, pod name and namespace are added by default. | +| `customTags` | _object (keys:string, values:[CustomTag](#customtag))_ | false | | CustomTags defines the custom tags to add to each span.
If provider is kubernetes, pod name and namespace are added by default.
Deprecated: Use Tags instead. | | `tags` | _object (keys:string, values:string)_ | false | | Tags defines the custom tags to add to each span.
Envoy [command operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators) may be used in the value.
The [format string documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#config-access-log-format-strings) provides more information.
If provider is kubernetes, pod name and namespace are added by default.
Same keys take precedence over CustomTags. | | `spanName` | _[TracingSpanName](#tracingspanname)_ | false | | SpanName defines the name of the span which will be used for tracing.
Envoy [command operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators) may be used in the value.
The [format string documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#config-access-log-format-strings) provides more information.
If not set, the span name is provider specific.
e.g. Datadog use `ingress` as the default client span name,
and `router egress` as the server span name. | diff --git a/site/content/en/latest/tasks/observability/proxy-trace.md b/site/content/en/latest/tasks/observability/proxy-trace.md index 054e9fb5e6..1d5daffe24 100644 --- a/site/content/en/latest/tasks/observability/proxy-trace.md +++ b/site/content/en/latest/tasks/observability/proxy-trace.md @@ -347,5 +347,37 @@ spec: EOF ``` +### Custom Tags + +You can add custom tags to the traces by setting the `telemetry.tracing.tags` in the [EnvoyProxy][envoy-proxy-crd] CRD. +You can use the same format as Envoy's [access log command operators](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#command-operators) to define the tag values. +The following configurations show how to apply proxy with custom tags: + +```shell +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: EnvoyProxy +metadata: + name: otel + namespace: envoy-gateway-system +spec: + telemetry: + tracing: + # sample 100% of requests + samplingRate: 100 + provider: + backendRefs: + - name: otel-collector + namespace: monitoring + port: 4317 + type: OpenTelemetry + tags: + # This is an example of using a literal as a tag value + provider: "otel" + "k8s.pod.name": "%ENVIRONMENT(ENVOY_POD_NAME)%" + "k8s.namespace.name": "%ENVIRONMENT(ENVOY_POD_NAMESPACE)%" + # This is an example of using a header value as a tag value + "header1": "%REQUEST_HEADER(X-Header-1)%" + "requestedServerName": "%REQUESTED_SERVER_NAME% +``` [envoy-proxy-crd]: ../../api/extension_types#envoyproxy diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml index 4b9d30859d..379fe0d9ba 100644 --- a/test/helm/gateway-crds-helm/all.out.yaml +++ b/test/helm/gateway-crds-helm/all.out.yaml @@ -23715,6 +23715,8 @@ spec: description: |- CustomTags defines the custom tags to add to each span. If provider is kubernetes, pod name and namespace are added by default. + + Deprecated: Use Tags instead. type: object samplingFraction: description: |- @@ -43802,6 +43804,8 @@ spec: description: |- CustomTags defines the custom tags to add to each span. If provider is kubernetes, pod name and namespace are added by default. + + Deprecated: Use Tags instead. type: object provider: description: Provider defines the tracing provider. diff --git a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml index 564c9e73e4..5bb19922ef 100644 --- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml +++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml @@ -2895,6 +2895,8 @@ spec: description: |- CustomTags defines the custom tags to add to each span. If provider is kubernetes, pod name and namespace are added by default. + + Deprecated: Use Tags instead. type: object samplingFraction: description: |- @@ -22982,6 +22984,8 @@ spec: description: |- CustomTags defines the custom tags to add to each span. If provider is kubernetes, pod name and namespace are added by default. + + Deprecated: Use Tags instead. type: object provider: description: Provider defines the tracing provider. From 05578e33c77821518e4357f108f8fcaf6b67a1d4 Mon Sep 17 00:00:00 2001 From: zirain Date: Wed, 14 Jan 2026 14:20:37 +0800 Subject: [PATCH 2/5] impl Signed-off-by: zirain --- internal/gatewayapi/listener.go | 1 + internal/ir/xds.go | 1 + internal/ir/zz_generated.deepcopy.go | 7 +++ internal/xds/translator/route.go | 2 +- internal/xds/translator/tracing.go | 29 +++++++---- test/e2e/testdata/btp-tracing.yaml | 48 ++++--------------- .../tracing-datadog-custom-service-name.yaml | 24 ++-------- test/e2e/testdata/tracing-datadog.yaml | 24 ++-------- .../tracing-otel-custom-service-name.yaml | 24 ++-------- .../testdata/tracing-zipkin-span-name.yaml | 24 ++-------- test/e2e/testdata/tracing-zipkin.yaml | 24 ++-------- 11 files changed, 65 insertions(+), 143 deletions(-) diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go index 2dc724a719..39ca07b071 100644 --- a/internal/gatewayapi/listener.go +++ b/internal/gatewayapi/listener.go @@ -786,6 +786,7 @@ func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.Envo ServiceName: serviceName, SamplingRate: proxySamplingRate(tracing), CustomTags: tracing.CustomTags, + Tags: tracing.Tags, Destination: ir.RouteDestination{ Name: destName, Settings: ds, diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 2be632dd36..de4d274169 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -2599,6 +2599,7 @@ type Tracing struct { Authority string `json:"authority,omitempty"` SamplingRate float64 `json:"samplingRate,omitempty"` CustomTags map[string]egv1a1.CustomTag `json:"customTags,omitempty"` + Tags map[string]string `json:"tags,omitempty"` Destination RouteDestination `json:"destination,omitempty"` Traffic *TrafficFeatures `json:"traffic,omitempty"` Provider egv1a1.TracingProvider `json:"provider"` diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 2bef3b3cd5..3f1a103344 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -4283,6 +4283,13 @@ func (in *Tracing) DeepCopyInto(out *Tracing) { (*out)[key] = *val.DeepCopy() } } + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } in.Destination.DeepCopyInto(&out.Destination) if in.Traffic != nil { in, out := &in.Traffic, &out.Traffic diff --git a/internal/xds/translator/route.go b/internal/xds/translator/route.go index 1f5ab06d84..96a268c140 100644 --- a/internal/xds/translator/route.go +++ b/internal/xds/translator/route.go @@ -818,7 +818,7 @@ func buildRouteTracing(httpRoute *ir.HTTPRoute) (*routev3.Tracing, error) { } tracing := httpRoute.Traffic.Telemetry.Tracing - tags, err := buildTracingTags(tracing.CustomTags) + tags, err := buildTracingTags(tracing.CustomTags, tracing.Tags) if err != nil { return nil, fmt.Errorf("failed to build route tracing tags:%w", err) } diff --git a/internal/xds/translator/tracing.go b/internal/xds/translator/tracing.go index 95dd20e573..f8571e5616 100644 --- a/internal/xds/translator/tracing.go +++ b/internal/xds/translator/tracing.go @@ -93,7 +93,7 @@ func buildHCMTracing(tracing *ir.Tracing) (*hcm.HttpConnectionManager_Tracing, e return nil, fmt.Errorf("failed to marshal tracing configuration: %w", err) } - tags, err := buildTracingTags(tracing.CustomTags) + tags, err := buildTracingTags(tracing.CustomTags, tracing.Tags) if err != nil { return nil, fmt.Errorf("failed to build tracing tags: %w", err) } @@ -161,13 +161,14 @@ func processClusterForTracing(tCtx *types.ResourceVersionTable, tracing *ir.Trac }) } -func buildTracingTags(tracingTags map[string]egv1a1.CustomTag) ([]*tracingtype.CustomTag, error) { - tags := make([]*tracingtype.CustomTag, 0, len(tracingTags)) +func buildTracingTags(tracingTags map[string]egv1a1.CustomTag, tags map[string]string) ([]*tracingtype.CustomTag, error) { + out := make([]*tracingtype.CustomTag, 0, len(tracingTags)+len(tags)) + // TODO: consider add some default tags for better UX for k, v := range tracingTags { switch v.Type { case egv1a1.CustomTagTypeLiteral: - tags = append(tags, &tracingtype.CustomTag{ + out = append(out, &tracingtype.CustomTag{ Tag: k, Type: &tracingtype.CustomTag_Literal_{ Literal: &tracingtype.CustomTag_Literal{ @@ -181,7 +182,7 @@ func buildTracingTags(tracingTags map[string]egv1a1.CustomTag) ([]*tracingtype.C defaultVal = *v.Environment.DefaultValue } - tags = append(tags, &tracingtype.CustomTag{ + out = append(out, &tracingtype.CustomTag{ Tag: k, Type: &tracingtype.CustomTag_Environment_{ Environment: &tracingtype.CustomTag_Environment{ @@ -196,7 +197,7 @@ func buildTracingTags(tracingTags map[string]egv1a1.CustomTag) ([]*tracingtype.C defaultVal = *v.RequestHeader.DefaultValue } - tags = append(tags, &tracingtype.CustomTag{ + out = append(out, &tracingtype.CustomTag{ Tag: k, Type: &tracingtype.CustomTag_RequestHeader{ RequestHeader: &tracingtype.CustomTag_Header{ @@ -209,10 +210,20 @@ func buildTracingTags(tracingTags map[string]egv1a1.CustomTag) ([]*tracingtype.C return nil, fmt.Errorf("unknown custom tag type: %s", v.Type) } } + + for k, v := range tags { + out = append(out, &tracingtype.CustomTag{ + Tag: k, + Type: &tracingtype.CustomTag_Value{ + Value: v, + }, + }) + } + // sort tags by tag name, make result consistent - sort.Slice(tags, func(i, j int) bool { - return tags[i].Tag < tags[j].Tag + sort.Slice(out, func(i, j int) bool { + return out[i].Tag < out[j].Tag }) - return tags, nil + return out, nil } diff --git a/test/e2e/testdata/btp-tracing.yaml b/test/e2e/testdata/btp-tracing.yaml index 9cd3385cd9..0a9acc6755 100644 --- a/test/e2e/testdata/btp-tracing.yaml +++ b/test/e2e/testdata/btp-tracing.yaml @@ -32,25 +32,11 @@ spec: - name: otel-collector namespace: monitoring port: 4317 - customTags: - "provider": - type: Literal - literal: - value: "otel" - "k8s.cluster.name": - type: Literal - literal: - value: "envoy-gateway" - "k8s.pod.name": - type: Environment - environment: - name: ENVOY_POD_NAME - defaultValue: "-" - "k8s.namespace.name": - type: Environment - environment: - name: ENVOY_POD_NAMESPACE - defaultValue: "envoy-gateway-system" + tags: + "provider": "otel" + "k8s.cluster.name": "envoy-gateway" + "k8s.pod.name": "%ENVIRONMENT(ENVOY_POD_NAME)%" + "k8s.namespace.name": "%ENVIRONMENT(ENVOY_POD_NAMESPACE)%" shutdown: drainTimeout: 5s minDrainDuration: 1s @@ -103,22 +89,8 @@ spec: tracing: samplingFraction: numerator: 100 - customTags: - "provider": - type: Literal - literal: - value: "otel-override" - "k8s.cluster.name": - type: Literal - literal: - value: "envoy-gateway" - "k8s.pod.name": - type: Environment - environment: - name: ENVOY_POD_NAME - defaultValue: "-" - "k8s.namespace.name": - type: Environment - environment: - name: ENVOY_POD_NAMESPACE - defaultValue: "envoy-gateway-system" + tags: + "provider": "otel-override" + "k8s.cluster.name": "envoy-gateway" + "k8s.pod.name": "%ENVIRONMENT(ENVOY_POD_NAME)%" + "k8s.namespace.name": "%ENVIRONMENT(ENVOY_POD_NAMESPACE)%" diff --git a/test/e2e/testdata/tracing-datadog-custom-service-name.yaml b/test/e2e/testdata/tracing-datadog-custom-service-name.yaml index 6b5ec03799..bd812a44c2 100644 --- a/test/e2e/testdata/tracing-datadog-custom-service-name.yaml +++ b/test/e2e/testdata/tracing-datadog-custom-service-name.yaml @@ -37,25 +37,11 @@ spec: namespace: monitoring port: 8126 serviceName: my-custom-service - customTags: - "provider": - type: Literal - literal: - value: "datadog" - "k8s.cluster.name": - type: Literal - literal: - value: "envoy-gateway" - "k8s.pod.name": - type: Environment - environment: - name: ENVOY_POD_NAME - defaultValue: "-" - "k8s.namespace.name": - type: Environment - environment: - name: ENVOY_POD_NAMESPACE - defaultValue: "envoy-gateway-system" + tags: + "provider": "datadog" + "k8s.cluster.name": "envoy-gateway" + "k8s.pod.name": "%ENVIRONMENT(ENVOY_POD_NAME)%" + "k8s.namespace.name": "%ENVIRONMENT(ENVOY_POD_NAMESPACE)%" shutdown: drainTimeout: 5s minDrainDuration: 1s diff --git a/test/e2e/testdata/tracing-datadog.yaml b/test/e2e/testdata/tracing-datadog.yaml index d39f5e1fa5..f6a71a5381 100644 --- a/test/e2e/testdata/tracing-datadog.yaml +++ b/test/e2e/testdata/tracing-datadog.yaml @@ -36,25 +36,11 @@ spec: - name: otel-collector namespace: monitoring port: 8126 - customTags: - "provider": - type: Literal - literal: - value: "datadog" - "k8s.cluster.name": - type: Literal - literal: - value: "envoy-gateway" - "k8s.pod.name": - type: Environment - environment: - name: ENVOY_POD_NAME - defaultValue: "-" - "k8s.namespace.name": - type: Environment - environment: - name: ENVOY_POD_NAMESPACE - defaultValue: "envoy-gateway-system" + tags: + "provider": "datadog" + "k8s.cluster.name": "envoy-gateway" + "k8s.pod.name": "%ENVIRONMENT(ENVOY_POD_NAME)%" + "k8s.namespace.name": "%ENVIRONMENT(ENVOY_POD_NAMESPACE)%" shutdown: drainTimeout: 5s minDrainDuration: 1s diff --git a/test/e2e/testdata/tracing-otel-custom-service-name.yaml b/test/e2e/testdata/tracing-otel-custom-service-name.yaml index 310cf3abe9..7504431199 100644 --- a/test/e2e/testdata/tracing-otel-custom-service-name.yaml +++ b/test/e2e/testdata/tracing-otel-custom-service-name.yaml @@ -33,25 +33,11 @@ spec: namespace: monitoring port: 4317 serviceName: my-custom-service - customTags: - "provider": - type: Literal - literal: - value: "otel" - "k8s.cluster.name": - type: Literal - literal: - value: "envoy-gateway" - "k8s.pod.name": - type: Environment - environment: - name: ENVOY_POD_NAME - defaultValue: "-" - "k8s.namespace.name": - type: Environment - environment: - name: ENVOY_POD_NAMESPACE - defaultValue: "envoy-gateway-system" + tags: + "provider": "otel" + "k8s.cluster.name": "envoy-gateway" + "k8s.pod.name": "%ENVIRONMENT(ENVOY_POD_NAME)%" + "k8s.namespace.name": "%ENVIRONMENT(ENVOY_POD_NAMESPACE)%" shutdown: drainTimeout: 5s minDrainDuration: 1s diff --git a/test/e2e/testdata/tracing-zipkin-span-name.yaml b/test/e2e/testdata/tracing-zipkin-span-name.yaml index 13d2c01960..8bf64e94e8 100644 --- a/test/e2e/testdata/tracing-zipkin-span-name.yaml +++ b/test/e2e/testdata/tracing-zipkin-span-name.yaml @@ -46,25 +46,11 @@ spec: port: 9411 zipkin: enable128BitTraceId: true - customTags: - "provider": - type: Literal - literal: - value: "zipkin" - "k8s.cluster.name": - type: Literal - literal: - value: "envoy-gateway" - "k8s.pod.name": - type: Environment - environment: - name: ENVOY_POD_NAME - defaultValue: "-" - "k8s.namespace.name": - type: Environment - environment: - name: ENVOY_POD_NAMESPACE - defaultValue: "envoy-gateway-system" + tags: + "provider": "zipkin" + "k8s.cluster.name": "envoy-gateway" + "k8s.pod.name": "%ENVIRONMENT(ENVOY_POD_NAME)%" + "k8s.namespace.name": "%ENVIRONMENT(ENVOY_POD_NAMESPACE)%" --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute diff --git a/test/e2e/testdata/tracing-zipkin.yaml b/test/e2e/testdata/tracing-zipkin.yaml index 2e25caaa4c..87d2a5e1d8 100644 --- a/test/e2e/testdata/tracing-zipkin.yaml +++ b/test/e2e/testdata/tracing-zipkin.yaml @@ -41,25 +41,11 @@ spec: port: 9411 zipkin: enable128BitTraceId: true - customTags: - "provider": - type: Literal - literal: - value: "zipkin" - "k8s.cluster.name": - type: Literal - literal: - value: "envoy-gateway" - "k8s.pod.name": - type: Environment - environment: - name: ENVOY_POD_NAME - defaultValue: "-" - "k8s.namespace.name": - type: Environment - environment: - name: ENVOY_POD_NAMESPACE - defaultValue: "envoy-gateway-system" + tags: + "provider": "zipkin" + "k8s.cluster.name": "envoy-gateway" + "k8s.pod.name": "%ENVIRONMENT(ENVOY_POD_NAME)%" + "k8s.namespace.name": "%ENVIRONMENT(ENVOY_POD_NAMESPACE)%" shutdown: drainTimeout: 5s minDrainDuration: 1s From f6bbc11a10e6fef699d931159e5a02f66fae68d1 Mon Sep 17 00:00:00 2001 From: zirain Date: Wed, 14 Jan 2026 14:22:56 +0800 Subject: [PATCH 3/5] release notes Signed-off-by: zirain --- release-notes/current.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/release-notes/current.yaml b/release-notes/current.yaml index 1eaac34961..604e78a8a2 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -27,6 +27,7 @@ new features: | Added support for custom span name. Added support for TLS telemetry gRPC backends. Added support for addIfAbsent header action in ClientTrafficPolicy EarlyRequestHeaders and LateResponseHeaders to add headers only when they don't already exist. + Added support for tracing tag, which allows to use Envoy string command operators such as `%ENVIRONMENT(...)%`. bug fixes: | Fixed configured OIDC authorization endpoint being overridden by discovered endpoints from issuer's well-known URL. From 987ddabaf241fbf84b4ec6042d8d6be76f2b2011 Mon Sep 17 00:00:00 2001 From: zirain Date: Mon, 19 Jan 2026 09:26:37 +0800 Subject: [PATCH 4/5] nit Signed-off-by: zirain --- site/content/en/latest/tasks/observability/proxy-trace.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/en/latest/tasks/observability/proxy-trace.md b/site/content/en/latest/tasks/observability/proxy-trace.md index 1d5daffe24..5a87e20356 100644 --- a/site/content/en/latest/tasks/observability/proxy-trace.md +++ b/site/content/en/latest/tasks/observability/proxy-trace.md @@ -377,7 +377,7 @@ spec: "k8s.namespace.name": "%ENVIRONMENT(ENVOY_POD_NAMESPACE)%" # This is an example of using a header value as a tag value "header1": "%REQUEST_HEADER(X-Header-1)%" - "requestedServerName": "%REQUESTED_SERVER_NAME% + "requestedServerName": "%REQUESTED_SERVER_NAME%" ``` [envoy-proxy-crd]: ../../api/extension_types#envoyproxy From c17b3a75bb501c1237751a5262cf246d419592cc Mon Sep 17 00:00:00 2001 From: zirain Date: Tue, 20 Jan 2026 09:08:14 +0800 Subject: [PATCH 5/5] tags take first Signed-off-by: zirain --- .../backendtrafficpolicy-tracing.in.yaml | 5 ++++ .../backendtrafficpolicy-tracing.out.yaml | 8 +++++ internal/xds/translator/tracing.go | 30 +++++++++++-------- test/e2e/testdata/btp-tracing.yaml | 6 ++++ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-tracing.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-tracing.in.yaml index ffcec998ea..bcafa8246e 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-tracing.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-tracing.in.yaml @@ -64,3 +64,8 @@ backendTrafficPolicies: requestHeader: name: "X-Request-Id" defaultValue: "-" + # tags will override customTags + tags: + env1: "%ENVIRONMENT(ENVOY_POD_NAME)%" + literal1: "literal_value_1" + req1: "%REQUEST_HEADER(X-Request-Id)%" diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-tracing.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-tracing.out.yaml index 96dba4f327..0d3910df37 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-tracing.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-tracing.out.yaml @@ -29,6 +29,10 @@ backendTrafficPolicies: samplingFraction: denominator: 100 numerator: 1 + tags: + env1: '%ENVIRONMENT(ENVOY_POD_NAME)%' + literal1: literal_value_1 + req1: '%REQUEST_HEADER(X-Request-Id)%' status: ancestors: - ancestorRef: @@ -241,6 +245,10 @@ xdsIR: samplingFraction: denominator: 100 numerator: 1 + tags: + env1: '%ENVIRONMENT(ENVOY_POD_NAME)%' + literal1: literal_value_1 + req1: '%REQUEST_HEADER(X-Request-Id)%' readyListener: address: 0.0.0.0 ipFamily: IPv4 diff --git a/internal/xds/translator/tracing.go b/internal/xds/translator/tracing.go index f8571e5616..2a5466fe6c 100644 --- a/internal/xds/translator/tracing.go +++ b/internal/xds/translator/tracing.go @@ -162,27 +162,27 @@ func processClusterForTracing(tCtx *types.ResourceVersionTable, tracing *ir.Trac } func buildTracingTags(tracingTags map[string]egv1a1.CustomTag, tags map[string]string) ([]*tracingtype.CustomTag, error) { - out := make([]*tracingtype.CustomTag, 0, len(tracingTags)+len(tags)) + out := make(map[string]*tracingtype.CustomTag) // TODO: consider add some default tags for better UX for k, v := range tracingTags { switch v.Type { case egv1a1.CustomTagTypeLiteral: - out = append(out, &tracingtype.CustomTag{ + out[k] = &tracingtype.CustomTag{ Tag: k, Type: &tracingtype.CustomTag_Literal_{ Literal: &tracingtype.CustomTag_Literal{ Value: v.Literal.Value, }, }, - }) + } case egv1a1.CustomTagTypeEnvironment: defaultVal := "" if v.Environment.DefaultValue != nil { defaultVal = *v.Environment.DefaultValue } - out = append(out, &tracingtype.CustomTag{ + out[k] = &tracingtype.CustomTag{ Tag: k, Type: &tracingtype.CustomTag_Environment_{ Environment: &tracingtype.CustomTag_Environment{ @@ -190,14 +190,14 @@ func buildTracingTags(tracingTags map[string]egv1a1.CustomTag, tags map[string]s DefaultValue: defaultVal, }, }, - }) + } case egv1a1.CustomTagTypeRequestHeader: defaultVal := "" if v.RequestHeader.DefaultValue != nil { defaultVal = *v.RequestHeader.DefaultValue } - out = append(out, &tracingtype.CustomTag{ + out[k] = &tracingtype.CustomTag{ Tag: k, Type: &tracingtype.CustomTag_RequestHeader{ RequestHeader: &tracingtype.CustomTag_Header{ @@ -205,25 +205,31 @@ func buildTracingTags(tracingTags map[string]egv1a1.CustomTag, tags map[string]s DefaultValue: defaultVal, }, }, - }) + } default: return nil, fmt.Errorf("unknown custom tag type: %s", v.Type) } } + // same key in tags will override tracingTags for k, v := range tags { - out = append(out, &tracingtype.CustomTag{ + out[k] = &tracingtype.CustomTag{ Tag: k, Type: &tracingtype.CustomTag_Value{ Value: v, }, - }) + } + } + + result := make([]*tracingtype.CustomTag, 0, len(out)) + for _, v := range out { + result = append(result, v) } // sort tags by tag name, make result consistent - sort.Slice(out, func(i, j int) bool { - return out[i].Tag < out[j].Tag + sort.Slice(result, func(i, j int) bool { + return result[i].Tag < result[j].Tag }) - return out, nil + return result, nil } diff --git a/test/e2e/testdata/btp-tracing.yaml b/test/e2e/testdata/btp-tracing.yaml index 0a9acc6755..f61908d834 100644 --- a/test/e2e/testdata/btp-tracing.yaml +++ b/test/e2e/testdata/btp-tracing.yaml @@ -32,6 +32,12 @@ spec: - name: otel-collector namespace: monitoring port: 4317 + # will be overridden by tags + customTags: + "provider": + type: Literal + literal: + value: "value-will-be-overrite" tags: "provider": "otel" "k8s.cluster.name": "envoy-gateway"