Skip to content

Conversation

@codefromthecrypt
Copy link
Contributor

@codefromthecrypt codefromthecrypt commented Jan 16, 2026

What type of PR is this?
feat(telemetry): add new feature

What this PR does / why we need it:
Adds support for resource attributes on OTLP metrics and tracing sinks, enabling callers like Envoy AI Gateway to map all attributes required for Elastic Cloud OTLP endpoints.

This completes the OTEL_RESOURCE_ATTRIBUTES equivalent for all three OTLP signals:

  • Access Logs: Already supported via resources field (maps to Envoy's resource_attributes)
  • Tracing: New resources field (maps to Envoy's resource_detectors with StaticConfigResourceDetector)
  • Metrics: New resources field (maps to Envoy's resource_detectors with StaticConfigResourceDetector)

Example use case: Setting service.name, service.version, and deployment.environment for proper service identification in observability backends like Elastic APM.

otel-tui
Screenshot 2026-01-16 at 3 16 02 PM
Screenshot 2026-01-16 at 3 15 46 PM
Screenshot 2026-01-16 at 3 15 54 PM

Release Notes: Yes

Added support for:
- Custom headers on OTLP exports (metrics, tracing, access logs)
- Resource attributes on OTLP metrics and tracing sinks via the resources field
- TLS telemetry gRPC backends

Signed-off-by: Adrian Cole <[email protected]>
@netlify
Copy link

netlify bot commented Jan 16, 2026

Deploy Preview for cerulean-figolla-1f9435 ready!

Name Link
🔨 Latest commit 691d28e
🔍 Latest deploy log https://app.netlify.com/projects/cerulean-figolla-1f9435/deploys/6969de6b7bcff5000897163e
😎 Deploy Preview https://deploy-preview-7972--cerulean-figolla-1f9435.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@codecov
Copy link

codecov bot commented Jan 16, 2026

Codecov Report

❌ Patch coverage is 80.95238% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.80%. Comparing base (d82eece) to head (691d28e).

Files with missing lines Patch % Lines
internal/gatewayapi/listener.go 66.66% 1 Missing and 1 partial ⚠️
internal/xds/translator/tracing.go 85.71% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7972      +/-   ##
==========================================
- Coverage   72.81%   72.80%   -0.02%     
==========================================
  Files         237      237              
  Lines       35475    35495      +20     
==========================================
+ Hits        25832    25843      +11     
- Misses       7801     7809       +8     
- Partials     1842     1843       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codefromthecrypt
Copy link
Contributor Author

So I was able to get data to Elastic Cloud, but traces aren't rendering even though logs and metrics do..

index 167f76fd5..204dead9e 100644
--- a/examples/otel-headers/resources/gateway.yaml
+++ b/examples/otel-headers/resources/gateway.yaml
@@ -5,15 +5,10 @@ metadata:
 spec:
   endpoints:
     - fqdn:
-        hostname: localhost
-        port: 4317
-# Use below for cloud OTLP endpoints
-#   endpoints:
-#     - fqdn:
-#         hostname: otel.example.com
-#         port: 443
-#   tls:
-#     wellKnownCACertificates: System
+        hostname: b7e5ce524b21440da7e3a9030fdf365d.ingest.us-central1.gcp.elastic.cloud
+        port: 443
+  tls:
+    wellKnownCACertificates: System
 ---
 apiVersion: gateway.envoyproxy.io/v1alpha1
 kind: EnvoyProxy
@@ -35,7 +30,7 @@ spec:
             # Authorization header sent as gRPC initial metadata
             headers:
               - name: Authorization
-                value: Bearer fake
+                value: ApiKey XXXXXXX==
             resources:
               service.name: envoy-gateway-example
               service.version: v1.0.0
@@ -52,7 +47,7 @@ spec:
         openTelemetry:
           headers:
             - name: Authorization
-              value: Bearer fake
+              value: ApiKey XXXXXXX==
           resources:
             service.name: envoy-gateway-example
             service.version: v1.0.0
@@ -84,7 +79,7 @@ spec:
                 # Authorization header sent as gRPC initial metadata
                 headers:
                   - name: Authorization
-                    value: Bearer fake
+                    value: ApiKey XXXXXXX==
 ---
 apiVersion: gateway.networking.k8s.io/v1
 kind: GatewayClass
Screenshot 2026-01-16 at 3 42 05 PM Screenshot 2026-01-16 at 3 41 33 PM Screenshot 2026-01-16 at 3 43 38 PM

cc @anuraaga @axw if any ideas and I can take the config thing offline as I think it is a different PR whatever that is..

@codefromthecrypt codefromthecrypt marked this pull request as ready for review January 16, 2026 06:49
@codefromthecrypt codefromthecrypt requested a review from a team as a code owner January 16, 2026 06:49
@axw
Copy link

axw commented Jan 16, 2026

@codefromthecrypt can you see any docs in traces-*? If there are, can you grab one so I can see what it looks like? Might be an issue with the UI/data contract

@codefromthecrypt
Copy link
Contributor Author

@axw so it wasn't selected by default so I added it..

Screenshot 2026-01-16 at 4 02 59 PM

here's one

{
  "_index": ".ds-traces-generic.otel-default-2026.01.07-000005",
  "_id": "AZvFiCdw3JeNWXAgrBz-",
  "_version": 1,
  "_score": null,
  "fields": {
    "resource.attributes.telemetry.sdk.name.text": [
      "envoy"
    ],
    "scope.name": [
      "envoy"
    ],
    "resource.attributes.telemetry.sdk.name": [
      "envoy"
    ],
    "resource.attributes.agent.name.text": [
      "envoy/cpp"
    ],
    "upstream_address": [
      "66.241.125.232:443"
    ],
    "attributes.span.name": [
      "router httproute/envoy-gateway-system/backend/rule/0 egress"
    ],
    "attributes.event.success_count": [
      1
    ],
    "attributes.service.target.type": [
      "http"
    ],
    "attributes.timestamp.us": [
      1768545582880064
    ],
    "telemetry.sdk.language": [
      "cpp"
    ],
    "processor.event": [
      "span"
    ],
    "upstream_cluster": [
      "httproute/envoy-gateway-system/backend/rule/0"
    ],
    "attributes.upstream_cluster": [
      "httproute/envoy-gateway-system/backend/rule/0"
    ],
    "peer.address": [
      "66.241.125.232:443"
    ],
    "telemetry.sdk.version": [
      "bad8280de85c25b147a90c1d9b8a8c67a13e7134/1.36.4/Modified/RELEASE/BoringSSL"
    ],
    "deployment.environment": [
      "production"
    ],
    "event.outcome": [
      "success"
    ],
    "scope.attributes.service.framework.name": [
      "envoy"
    ],
    "parent_span_id": [
      "9b6b7fb183615f61"
    ],
    "attributes.response_flags": [
      "-"
    ],
    "span_id": [
      "5f59db9765a0f256"
    ],
    "kind": [
      "Client"
    ],
    "attributes.http.protocol": [
      "HTTP/2"
    ],
    "span.id": [
      "5f59db9765a0f256"
    ],
    "span.type": [
      "external"
    ],
    "timestamp.us": [
      1768545582880064
    ],
    "resource.attributes.telemetry.sdk.version": [
      "bad8280de85c25b147a90c1d9b8a8c67a13e7134/1.36.4/Modified/RELEASE/BoringSSL"
    ],
    "resource.attributes.deployment.environment": [
      "production"
    ],
    "attributes.upstream_address": [
      "66.241.125.232:443"
    ],
    "name": [
      "router httproute/envoy-gateway-system/backend/rule/0 egress"
    ],
    "parent.id": [
      "9b6b7fb183615f61"
    ],
    "resource.attributes.service.name.text": [
      "envoy-gateway-example"
    ],
    "attributes.span.name.text": [
      "router httproute/envoy-gateway-system/backend/rule/0 egress"
    ],
    "scope.attributes.service.framework.version": [
      "bad8280de85c25b147a90c1d9b8a8c67a13e7134/1.36.4/Modified/RELEASE/BoringSSL"
    ],
    "attributes.span.subtype": [
      "http"
    ],
    "resource.attributes.service.name": [
      "envoy-gateway-example"
    ],
    "span.representative_count": [
      1
    ],
    "upstream_cluster.name": [
      "httproute/envoy-gateway-system/backend/rule/0"
    ],
    "span.name": [
      "router httproute/envoy-gateway-system/backend/rule/0 egress"
    ],
    "resource.attributes.agent.version": [
      "bad8280de85c25b147a90c1d9b8a8c67a13e7134/1.36.4/Modified/RELEASE/BoringSSL"
    ],
    "resource.attributes.agent.name": [
      "envoy/cpp"
    ],
    "attributes.service.target.name": [
      ""
    ],
    "resource.attributes.telemetry.sdk.language": [
      "cpp"
    ],
    "attributes.span.type": [
      "external"
    ],
    "attributes.component": [
      "proxy"
    ],
    "telemetry.sdk.name": [
      "envoy"
    ],
    "duration": [
      256249000
    ],
    "attributes.span.duration.us": [
      256249
    ],
    "trace.id": [
      "ddd03f3cca6e589a2af1ed3897ecbf19"
    ],
    "span.duration.us": [
      256249
    ],
    "event.success_count": [
      1
    ],
    "resource.attributes.service.version": [
      "v1.0.0"
    ],
    "attributes.upstream_cluster.name": [
      "httproute/envoy-gateway-system/backend/rule/0"
    ],
    "scope.attributes.service.framework.name.text": [
      "envoy"
    ],
    "attributes.upstream_cluster.name.text": [
      "httproute/envoy-gateway-system/backend/rule/0"
    ],
    "trace_id": [
      "ddd03f3cca6e589a2af1ed3897ecbf19"
    ],
    "attributes.service.target.name.text": [
      ""
    ],
    "span.subtype": [
      "http"
    ],
    "http.protocol": [
      "HTTP/2"
    ],
    "response_flags": [
      "-"
    ],
    "http.status_code": [
      "200"
    ],
    "attributes.http.status_code": [
      "200"
    ],
    "attributes.processor.event": [
      "span"
    ],
    "component": [
      "proxy"
    ],
    "attributes.peer.address": [
      "66.241.125.232:443"
    ],
    "attributes.event.outcome": [
      "success"
    ],
    "scope.version": [
      "bad8280de85c25b147a90c1d9b8a8c67a13e7134/1.36.4/Modified/RELEASE/BoringSSL"
    ],
    "attributes.span.representative_count": [
      1
    ],
    "event.dataset": [
      "generic.otel"
    ]
  },
  "sort": [
    "2026-01-16T06:39:42.880Z",
    9
  ]
}

@axw
Copy link

axw commented Jan 16, 2026

Thanks, so definitely seems to be an issue with the fields...

Nothing obvious jumps out. If you're able to grab an OTLP dump (OTLP/JSON is fine if easier to drop here) then I can try to reproduce and see what's up (probably on Monday).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants