Add missing header tags in unhandled exception handler in ASP.NET Core#2460
Add missing header tags in unhandled exception handler in ASP.NET Core#2460andrewlock wants to merge 1 commit into
Conversation
I can't think of a reason that we shouldn't do this. It was probably (incorrectly) assumed that the end request handlers would handle this case |
Great, that's what we thought, thanks! |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
|
||
| // Generic unhandled exceptions are converted to 500 errors by Kestrel | ||
| span.SetHttpStatusCode(statusCode: statusCode, isServer: true, tracer.Settings); | ||
| span.SetHeaderTags(new HeadersCollectionAdapter(unhandledStruct.HttpContext.Response.Headers), tracer.Settings.HeaderTags, defaultTagPrefix: SpanContextPropagator.HttpResponseHeadersTagPrefix); |
There was a problem hiding this comment.
Not asking to change anything, more a philosophical question that I asked myself.
I wonder if we could find a way to make sure we ask ourselves the question "should I also set the header" when we set a httpstatuscode. I thought maybe adding a new method on Span doing both could be a way as people would see it and ask themselves the question. But I find it kinda ugly.
Anyway, if you think this comment is relevant and you find a more appropriate idea, it could be nice to reduce the risk of forgetting this in the future.
There was a problem hiding this comment.
I don't think we can combine these, as we don't set header tags for client requests (e.g. HttpClient, AWS's SDK client etc). We only set them for "server" requests (aspnet, aspnetcore).
If we should be setting them on client http spans, then that's another question! 😄
We should be recording response headers when an exception is thrown too. Note that the snapshots show we're not recording the correlation id header (for example) in these error cases. I'm not sure why, but it is likely due to the way the middleware pipeline works
48e1957 to
e337325
Compare
Benchmarks Report 🐌Benchmarks for #2460 compared to master:
The following thresholds were used for comparing the benchmark speeds:
Allocation changes below 0.5% are ignored. Benchmark detailsBenchmarks.Trace.AgentWriterBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.AspNetCoreBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.DbCommandBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.ElasticsearchBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.GraphQLBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.HttpClientBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.ILoggerBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.Log4netBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.NLogBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.RedisBenchmark - Slower
|
| Benchmark | diff/base | Base Median (ns) | Diff Median (ns) | Modality |
|---|---|---|---|---|
| Benchmarks.Trace.RedisBenchmark.SendReceive‑net472 | 1.193 | 2,317.71 | 2,763.91 |
| Benchmark | base/diff | Base Median (ns) | Diff Median (ns) | Modality |
|---|---|---|---|---|
| Benchmarks.Trace.RedisBenchmark.SendReceive‑netcoreapp3.1 | 1.121 | 2,360.93 | 2,105.43 |
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | SendReceive |
net472 | 2.32μs | 9.1ns | 32.8ns | 0.159 | 0 | 0 | 1 KB |
| master | SendReceive |
netcoreapp3.1 | 2.38μs | 11.7ns | 52.4ns | 0.0139 | 0 | 0 | 1 KB |
| #2460 | SendReceive |
net472 | 2.77μs | 9.73ns | 36.4ns | 0.159 | 0 | 0 | 1 KB |
| #2460 | SendReceive |
netcoreapp3.1 | 2.11μs | 6.97ns | 27ns | 0.0136 | 0 | 0 | 1 KB |
Benchmarks.Trace.SerilogBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | EnrichedLog |
net472 | 6.26μs | 32.4ns | 155ns | 0.289 | 0 | 0 | 1.85 KB |
| master | EnrichedLog |
netcoreapp3.1 | 5.2μs | 19.2ns | 74.2ns | 0.021 | 0 | 0 | 1.47 KB |
| #2460 | EnrichedLog |
net472 | 6.33μs | 14.4ns | 54ns | 0.287 | 0 | 0 | 1.85 KB |
| #2460 | EnrichedLog |
netcoreapp3.1 | 5.31μs | 25ns | 96.7ns | 0.0185 | 0 | 0 | 1.47 KB |
Benchmarks.Trace.SpanBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | StartFinishSpan |
net472 | 920ns | 4.37ns | 16.9ns | 0.0703 | 0 | 0 | 449 B |
| master | StartFinishSpan |
netcoreapp3.1 | 892ns | 2.5ns | 9.67ns | 0.00592 | 0 | 0 | 448 B |
| master | StartFinishScope |
net472 | 1.09μs | 2.92ns | 10.9ns | 0.0829 | 0 | 0 | 530 B |
| master | StartFinishScope |
netcoreapp3.1 | 1.1μs | 3.59ns | 13.9ns | 0.00772 | 0 | 0 | 568 B |
| #2460 | StartFinishSpan |
net472 | 977ns | 5.64ns | 47.2ns | 0.0704 | 0 | 0 | 449 B |
| #2460 | StartFinishSpan |
netcoreapp3.1 | 923ns | 3.64ns | 13.6ns | 0.00598 | 0 | 0 | 448 B |
| #2460 | StartFinishScope |
net472 | 1.12μs | 3.07ns | 11.5ns | 0.083 | 0 | 0 | 530 B |
| #2460 | StartFinishScope |
netcoreapp3.1 | 1.08μs | 3ns | 11.2ns | 0.00791 | 0 | 0 | 568 B |
Code Coverage Report 📊✔️ Merging #2460 into master will not change line coverage
View the full report for further details: Datadog.Trace Breakdown ✔️
The following classes have significant coverage changes.
View the full reports for further details: |
|
Superseded by #2480 |
Summary of changes
Reason for change
Discovered while investigating #2458. We noticed that we were not calling
SetHeaderTags()to record response headers when an unhandled exception occurs in the middleware/mvc pipeline./cc @zacharycmontoya as you implemented this originally I believe - is there any reason you're aware of that we shouldn't be doing this?
Implementation details
Set the response headers if we need to.
Test coverage
Updated the snapshots to include the missing response headers for the "erroring" endpoints.
Note that the snapshots show we're not recording the correlation id header (for example) in these error cases. I'm not sure why, but it is likely due to the way the middleware pipeline works (i.e. the header is not being added!)
@DataDog/apm-dotnet