Suppressing logs for cancelled HTTP requests with Scrutor
A Habr author describes how their ASP.NET Core team stopped logging OperationCanceledException when a client aborts an HTTP request. NLog filters and middleware catches fell short. The working approach decorates ILoggerProvider with Scrutor and checks HttpContext.RequestAborted before writing the entry.
Key points
- Decorate ILoggerProvider instead of ILogger<T> so loggers created through ILoggerFactory.CreateLogger(string) are covered too.
- Keep the null-conditional in accessor.HttpContext?.RequestAborted; background services and queue consumers have no HTTP context.
- services.Decorate<ILoggerProvider, T>() wraps every registered provider, including Console and NLog.
- In production, unwrap OperationCanceledException from AggregateException before deciding to suppress it.
- The article's token equality check is a simplification; a coincidental match could hide a real external service failure.
Client-aborted requests are a common source of noise in ASP.NET Core logs: when a user leaves a page, the browser cancels the request and the resulting OperationCanceledException is recorded as a genuine error. The author's team first tried filtering the exception in the NLog configuration, then catching it in middleware. Both approaches fell short. NLog has no access to the current HTTP context, and repositories that log and rethrow write the entry before the exception reaches middleware.
The working fix wraps ILoggerProvider with a decorator registered through Scrutor's Decorate method. The wrapper drops an entry when the exception is an OperationCanceledException and HttpContext.RequestAborted is already cancelled, which it reads through IHttpContextAccessor. Because the wrapper implements the same interface, the rest of the logging pipeline stays unchanged. The article also warns about a null HttpContext in background services, about Decorate affecting every registered provider, and about cancellations nested inside AggregateException.
Real-world use
- An ASP.NET Core API with NLog where users often navigate away during slow report generation and the logs fill with cancellation errors.
- A codebase whose repositories catch, log and rethrow every exception, where middleware-level suppression never runs in time.
Why it matters
Routine client disconnects stop polluting alerts and reports from one central place, while real timeouts and database failures are still logged.