Skip to content

Conversation

@codefromthecrypt
Copy link
Contributor

@codefromthecrypt codefromthecrypt commented Dec 5, 2025

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

What this PR does / why we need it:
Adds support for custom headers on all OTLP/gRPC exports (metrics, tracing, and access logs), enabling authentication with collectors like Elastic Cloud, Datadog, or cloud providers that require API keys or bearer tokens.

This uses Envoy's GrpcService.initial_metadata to send headers as gRPC metadata.

Release Notes: Yes

Notes:
This PR includes an example showing authenticated OTLP exports for all three signals. The example uses otel-tui, but could use anything else.

Screenshot 2025-12-11 at 9 49 34 AM Screenshot 2025-12-11 at 9 49 13 AM

Changes

  • Metrics: Added Headers field to ProxyOpenTelemetrySink in telemetry.metrics.sinks[].openTelemetry
  • Tracing: Added Headers field to TracingProvider in telemetry.tracing.provider
  • Access Logs: Added Headers field to OpenTelemetryAccessLog in telemetry.accessLog.settings[].sinks[].openTelemetry

All three use the same pattern: a list of HTTPHeader objects with name and value fields.

FAQ

Why not use SecretObjectReference for sensitive headers?

For EnvoyProxy config that supports file-based standalone mode, Kubernetes secrets are not available. Plain text headers are needed regardless.

For example, Honeycomb requires non-secret headers like x-honeycomb-dataset. Secret support can be added in a follow-up for Kubernetes mode.

@codefromthecrypt codefromthecrypt requested a review from a team as a code owner December 5, 2025 06:44
@codecov
Copy link

codecov bot commented Dec 5, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.41%. Comparing base (b0e3ced) to head (a7376ae).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7674      +/-   ##
==========================================
+ Coverage   72.34%   72.41%   +0.07%     
==========================================
  Files         234      235       +1     
  Lines       34542    34566      +24     
==========================================
+ Hits        24988    25032      +44     
+ Misses       7762     7746      -16     
+ Partials     1792     1788       -4     

☔ 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 codefromthecrypt force-pushed the otel-grpc-headers branch 2 times, most recently from c58e24a to 5f69a4f Compare December 5, 2025 07:42
@codefromthecrypt codefromthecrypt force-pushed the otel-grpc-headers branch 2 times, most recently from 2483048 to 36f5bee Compare December 5, 2025 12:13
@codefromthecrypt
Copy link
Contributor Author

ok made a revision also to PR desc to hopefully answer questions in comments. I will revisit this again monday if there is more feedback.

@codefromthecrypt codefromthecrypt marked this pull request as draft December 7, 2025 00:29
@codefromthecrypt
Copy link
Contributor Author

pulling into draft while I remove the port dodging things for things we can't control yet.

@codefromthecrypt
Copy link
Contributor Author

also I just realized we never added this for tracing either, so will add that to the PR

@codefromthecrypt codefromthecrypt changed the title feat(accesslog): add custom headers for OTLP access log exports feat(telemetry): add custom headers for OTLP exports (metrics, tracing, access logs) Dec 7, 2025
spec:
telemetry:
metrics:
# TODO: Some backends like otel-tui and Elastic require delta temporality
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These problems are too much to do in this PR, and I can over time try to clean these up also

@codefromthecrypt codefromthecrypt force-pushed the otel-grpc-headers branch 3 times, most recently from 607296e to 5bff38d Compare December 7, 2025 05:42
log := collector.TakeLog()
require.NotNil(t, log)
require.Contains(t, log.Body.GetStringValue(), `HTTP/1.1" 200`)
require.Equal(t, "Bearer test-api-key", testotel.GetAttributeString(log.Attributes, "grpc.metadata.authorization"))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mathetake @anuraaga you might like this sneaky trick to verify the headers/metadata received by otel. propagate them into fake span attrs

@codefromthecrypt codefromthecrypt force-pushed the otel-grpc-headers branch 2 times, most recently from 412773b to ea11614 Compare December 7, 2025 06:20
@codefromthecrypt codefromthecrypt marked this pull request as ready for review December 7, 2025 06:20
@codefromthecrypt
Copy link
Contributor Author

ok I updated this as I noticed the same thing was missing everywhere, in logs metrics and tracing. fixed so that the tests are coherent and we don't need to go back and clean this up multiple times. There's been a history of fragmentation and not following up later, so doing otel holistically for one thing is a good thing.

@codefromthecrypt
Copy link
Contributor Author

@arkodg @zirain I will mark this draft again and rebase after #7695 is merged because without those changes, the integration test for headers here won't pass.

@codefromthecrypt
Copy link
Contributor Author

codefromthecrypt commented Dec 10, 2025

will undraft after #7697 because I noticed metrics are unreadable in otel-tui until that change (many otel backends require delta temporality)

…sink

This enables OTLP access logs to have both body (text) and attributes
populated simultaneously, matching the OpenTelemetry LogRecord spec.

Previously, the GatewayAPI translator used a switch statement that forced
choosing EITHER body (from format.Text) OR attributes (from format.JSON),
never both. This did not match the OTLP spec where body and attributes
serve complementary purposes:
- body: The primary log message
- attributes: Structured metadata for querying/filtering

The new sink-level text and attributes fields allow configuring both
directly, with fallback to setting-level format for backwards compatibility.

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

@arkodg @zirain I looked carefully at my screenshots and noticed that the logs didn't include any otel attributes. this is a bug, even if very small one. I raised #7720 as we shouldn't merge this until it works like one would expect (the example should be valid and actually have attributes in otel for the log).

once that is merged I think we're finally good. thanks for your patience

@codefromthecrypt
Copy link
Contributor Author

updated the screenshots based on the current branch which cherry-picks and shows the attributes for the log messages get to otel

Adds a Headers field to the OpenTelemetry configuration for access
logging, tracing, and metrics. This allows configuring gRPC initial
metadata (e.g., Authorization headers) for authenticated OTLP export
to collectors like Elastic, Datadog, or cloud providers.

Also adds MinItems=1 validation for OTLP headers.

Signed-off-by: Adrian Cole <[email protected]>
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.

3 participants