Skip to content

Fix ArgumentNullException in per-request log buffering at the end of a request - #7811

Merged
evgenyfedorov2 merged 8 commits into
mainfrom
evgenyfedorov2-fix-per-request-buffer-null-request-serv
Oct 6, 2026
Merged

evgenyfedorov2 merged 8 commits into
mainfrom
evgenyfedorov2-fix-per-request-buffer-null-request-serv

Conversation

@evgenyfedorov2

@evgenyfedorov2 evgenyfedorov2 commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

Fixes #7806

Problem

As reported in #7806, with per-request log buffering (AddPerIncomingRequestBuffer) and Information level enabled for Microsoft.AspNetCore.Hosting.Diagnostics, ILogger.Log throws ArgumentNullException: Value cannot be null. (Parameter 'provider') when ASP.NET Core logs "Request finished" (event id 2) at the end of a request.

Root cause

ASP.NET Core disposes the request's service scope in a response OnCompleted callback, after which HttpContext.RequestServices returns null, and then logs "Request finished" in HostingApplication.DisposeContext while IHttpContextAccessor.HttpContext still returns the request's HttpContext. PerRequestLogBufferManager.TryEnqueue and Flush only checked HttpContext for null, so they passed the null RequestServices to GetService<T>(), which throws. ExtendedLogger calls TryEnqueue outside its try/catch, so the exception escapes ILogger.Log.

Fix

In PerRequestLogBufferManager:

  • TryEnqueue uses the global buffer when HttpContext or its RequestServices is null, the same way it already handled a null HttpContext.
  • Flush skips the per-request buffer when RequestServices is null and still flushes the global buffer.

Evgenii Fedorov and others added 2 commits October 6, 2026 12:00
โ€ฆa request

PerRequestLogBufferManager read HttpContext.RequestServices without checking
it for null. ASP.NET Core disposes the request services, after which
RequestServices returns null, before it logs "Request finished" and clears
IHttpContextAccessor.HttpContext. TryEnqueue now uses the global buffer in
that case, and Flush skips the per-request buffer and still flushes the
global buffer.

Fixes #7806

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep the test that reproduces the reported scenario ("Request finished"
logged after the request services have been disposed) and remove the unit
tests that used an HttpContext without request services.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@dotnet-comment-bot

Copy link
Copy Markdown
Collaborator

โ€ผ๏ธ Found issues โ€ผ๏ธ

Project Coverage Type Expected Actual
Microsoft.Extensions.Diagnostics.Testing Line 99 98.65 ๐Ÿ”ป
Microsoft.Extensions.Telemetry Line 93 92.53 ๐Ÿ”ป
Microsoft.Extensions.AI.OpenAI Line 75 68.32 ๐Ÿ”ป
Microsoft.Extensions.AI.OpenAI Branch 75 57.59 ๐Ÿ”ป
Microsoft.Extensions.DataIngestion.MarkItDown Line 75 4.46 ๐Ÿ”ป
Microsoft.Extensions.DataIngestion.MarkItDown Branch 75 0 ๐Ÿ”ป
Microsoft.Extensions.Diagnostics.ResourceMonitoring Line 99 96.03 ๐Ÿ”ป
Microsoft.Extensions.Diagnostics.ResourceMonitoring Branch 99 92.76 ๐Ÿ”ป
Microsoft.Extensions.Diagnostics.ResourceMonitoring.Kubernetes Line 99 97.73 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery.Dns Line 75 71.61 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery.Abstractions Line 75 42.11 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery.Abstractions Branch 75 42.86 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery Line 75 69.66 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery Branch 75 71.43 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery.Yarp Line 75 73.85 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery.Yarp Branch 75 70 ๐Ÿ”ป
Microsoft.Extensions.VectorData.Abstractions Line 75 37.39 ๐Ÿ”ป
Microsoft.Extensions.VectorData.Abstractions Branch 75 22.73 ๐Ÿ”ป

๐ŸŽ‰ Good job! The coverage increased ๐ŸŽ‰
Update MinCodeCoverage in the project files.

Project Expected Actual
Microsoft.Extensions.Http.Diagnostics 94 95
Microsoft.Gen.BuildMetadata 97 100
Microsoft.Gen.MetadataExtractor 57 73
Microsoft.Gen.MetricsReports 67 69
Microsoft.Extensions.AI.Abstractions 82 86
Microsoft.Extensions.AI.Evaluation.NLP 0 78
Microsoft.Extensions.Caching.Hybrid 82 85
Microsoft.Extensions.DataIngestion 75 89
Microsoft.Extensions.DataIngestion.Markdig 75 90
Microsoft.Extensions.Http.Resilience 97 100

Full code coverage report: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1624770&view=codecoverage-tab

evgenyfedorov2 and others added 6 commits October 6, 2026 15:34
Replace the IServiceProvider? locals with ?. on HttpContext.RequestServices.
TryEnqueue already falls back to the global buffer when there's no
per-request buffer, and Flush still flushes the global buffer.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use Assert.Contains on FakeLogCollector.GetLogsAsync instead of a loop, and
remove the status code check, which the bug doesn't affect.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Replace the end-to-end test with a test of PerRequestLogBufferManager: a
record logged while HttpContext.RequestServices is null is held by the global
buffer and written when PerRequestLogBuffer is flushed. The test covers both
TryEnqueue and Flush.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@evgenyfedorov2
evgenyfedorov2 marked this pull request as ready for review October 6, 2026 14:23
@evgenyfedorov2
evgenyfedorov2 requested a review from a team as a code owner October 6, 2026 14:23
Copilot AI balanced review requested due to automatic review settings October 6, 2026 14:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

๐ŸŸข Approval recommended

The focused null handling matches the reported lifecycle behavior and is adequately covered by a regression test.

Review effort: Balanced
Findings: None

What changed in this PR

Fixes per-request log buffering when request services have already been disposed.

Changes:

  • Falls back to the global buffer when RequestServices is null.
  • Adds regression coverage for logging and flushing.
File Description
PerRequestLogBufferManager.cs Safely handles null request services.
PerRequestLogBufferManagerTests.cs Verifies global-buffer fallback behavior.

๐Ÿ’ก Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@dotnet-comment-bot

Copy link
Copy Markdown
Collaborator

โ€ผ๏ธ Found issues โ€ผ๏ธ

Project Coverage Type Expected Actual
Microsoft.Extensions.Diagnostics.Testing Line 99 98.65 ๐Ÿ”ป
Microsoft.Extensions.Telemetry Line 93 92.53 ๐Ÿ”ป
Microsoft.Extensions.AI.OpenAI Line 75 68.32 ๐Ÿ”ป
Microsoft.Extensions.AI.OpenAI Branch 75 57.59 ๐Ÿ”ป
Microsoft.Extensions.DataIngestion.MarkItDown Line 75 4.46 ๐Ÿ”ป
Microsoft.Extensions.DataIngestion.MarkItDown Branch 75 0 ๐Ÿ”ป
Microsoft.Extensions.Diagnostics.ResourceMonitoring Line 99 96.03 ๐Ÿ”ป
Microsoft.Extensions.Diagnostics.ResourceMonitoring Branch 99 92.76 ๐Ÿ”ป
Microsoft.Extensions.Diagnostics.ResourceMonitoring.Kubernetes Line 99 97.73 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery.Dns Line 75 68.32 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery Line 75 67.21 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery Branch 75 71.43 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery.Abstractions Line 75 42.11 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery.Abstractions Branch 75 42.86 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery.Yarp Line 75 73.85 ๐Ÿ”ป
Microsoft.Extensions.ServiceDiscovery.Yarp Branch 75 70 ๐Ÿ”ป
Microsoft.Extensions.VectorData.Abstractions Line 75 37.39 ๐Ÿ”ป
Microsoft.Extensions.VectorData.Abstractions Branch 75 22.73 ๐Ÿ”ป

๐ŸŽ‰ Good job! The coverage increased ๐ŸŽ‰
Update MinCodeCoverage in the project files.

Project Expected Actual
Microsoft.Extensions.Http.Diagnostics 94 95
Microsoft.Gen.BuildMetadata 97 100
Microsoft.Gen.MetadataExtractor 57 73
Microsoft.Gen.MetricsReports 67 69
Microsoft.Extensions.AI.Abstractions 82 86
Microsoft.Extensions.AI.Evaluation.NLP 0 78
Microsoft.Extensions.Caching.Hybrid 82 85
Microsoft.Extensions.DataIngestion 75 89
Microsoft.Extensions.DataIngestion.Markdig 75 90
Microsoft.Extensions.Http.Resilience 97 100

Full code coverage report: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1624977&view=codecoverage-tab

@evgenyfedorov2
evgenyfedorov2 merged commit 3b82226 into main Oct 6, 2026
6 checks passed
evgenyfedorov2 pushed a commit that referenced this pull request Oct 7, 2026
#7811 fixed the exception the filter avoided.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Per-request log buffering throws ArgumentNullException at the end of a request

4 participants