[OpenTelemetry] Support opt-in capture of request and response headers
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- csharp
- Domain
- backend, observability
Research direction
Start by reading the hosting code around CreateInitializeActivityTags, then trace where the Activity stops and how SuppressActivityOpenTelemetryData is applied. The issue describes separate opt-in request and response header lists, with request values available at sampling time. Done means the agreed configuration surface and header capture behavior are implemented; the issue leaves those design choices open.
Written by the indexing model from the issue text.
Description
Is there an existing issue for this?
- I have searched the existing issues
Is your feature request related to a problem? Please describe the problem.
I want to capture selected request and response headers on the hosting Activity, as http.request.header.<key> and http.response.header.<key>, and have request headers available to samplers. ASP.NET Core has no way to do this today.
- The semantic conventions define both attributes as stable, opt-in string arrays. They say "Instrumentations SHOULD require an explicit configuration of which headers are to be captured".
- For HTTP server spans,
http.request.header.<key>is one of the attributes that "SHOULD be provided at span creation time (if provided at all)" for sampling (http-spans). Enrichcallbacks inOpenTelemetry.Instrumentation.AspNetCoreand custom listeners both run after theActivityis created and sampled, so headers can't drive sampling decisions.
Describe the solution you'd like
Opt-in header capture in hosting, targeting .NET 12. Would this be accepted? I'm happy to contribute the implementation.
- Two configurable lists of header names, one for request headers and one for response headers. Both are empty by default, so nothing is captured and nothing changes.
- Names are matched exactly, case-insensitively, with no wildcards
- Request headers are added in
CreateInitializeActivityTagsashttp.request.header.<lower-cased-name>with string-array values, so they are available to samplers. - Response headers are added when the
Activitystops, ashttp.response.header.<lower-cased-name>. - Both respect
SuppressActivityOpenTelemetryData.
Creation tags are added even when the request isn't sampled, so a configured list costs one header lookup per configured name per request. An empty list costs nothing.
Open questions:
- What configuration surface would you prefer: a public API, an OTel-aligned environment variable as proposed in #69092, or both?
- Should response headers be in scope, or request headers only?
Alternatives considered:
Enrichcallbacks or a custom listener: these work for export, but headers are added after sampling, and every app writes the same code and requires the contrib instrumentation package.- Header capture in
OpenTelemetry.Instrumentation.AspNetCore: this has the same post-sampling limitation and ideally the maintainers would like to deprecate this package once optional attributes are built into ASP.NET Core. This requires extra dependencies and registration for consumers vs. on a clean OOB experience.
Additional context
- open-telemetry/opentelemetry-dotnet-contrib#5921: now that #65873 has made the contrib package largely optional, the preference there is to build this into ASP.NET Core for .NET 12 rather than add features to the package. Contrib may carry an interim bridge for
net10.0/net11.0. - Within OTel there is a moratorium on new
OTEL_env vars so a discussion would need to occur on how ASP.NET Core users would opt in for this. - #69092 is a related request to make hosting's OpenTelemetry behaviour configurable.
- Dominant language
- C#
- Stars
- 38.5k
- Forks
- 11.6k
- Avg merge
- 3d 1h
- Merged PRs (30d)
- 289
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from dotnet/aspnetcore
-
area-networking
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
dotnet/aspnetcore#70545 · 1 comment ·
Maintainers usually reply within 1 day
-
area-infrastructure
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
dotnet/aspnetcore#70524 · 1 comment ·
Maintainers usually reply within 1 day
-
[OpenTelemetry] Hosting replaces an Activity.DisplayName that the app set, when a route matchesOpenarea-hosting Regression
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
dotnet/aspnetcore#70516 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day
-
[SSE] ServerSentEventsResult.WrapEvents is missing [EnumeratorCancellation], so RequestAborted never reaches the app's generator on the IAsyncEnumerable<T> overloadPossibly taken @bharatprajapati-coder claimed this 1 day ago. Openarea-minimal
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
dotnet/aspnetcore#70419 · 2 comments ·
Maintainers usually reply within 1 day
-
[Blazor] DefaultInMemoryCircuitPersistenceProvider never disposes the retention CancellationTokenSource when a persist is rejected at capacityPossibly taken @Vinoth2562000 claimed this 1 day ago. Openarea-blazor
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
dotnet/aspnetcore#70418 · 1 comment · 1 assignee ·
Maintainers usually reply within 1 day
All issues in dotnet/aspnetcore
Similar issues
-
bug emitter:client:csharp
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
microsoft/typespec#12572 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day
-
needs-area-label
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 2 days
-
AWS Lambda: KeyNotFoundException drops HTTP-triggered transactions when allowAllHeaders is disabledOpenbug
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
newrelic/newrelic-dotnet-agent#3949 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 87/100
Maintainers usually reply within 1 day
-
priority:P2
Difficulty 2/5 1-3 hours Newbie friendliness 80/100