Full Request/Response Tracing for ASP.NET Core
This projects provides an ASP.NET Core middleware to allow complete tracing of requests and responses (including the body) going in/out of an ASP.NET Core app.
Install the package:
Install-Package AspNetCoreRequestTracing
Then in the Startup
class adds the configuration and the request middleware:
using AspNetCoreRequestTracing;
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
// ...
// Configure the RequestTracingMiddlewareOptions. This is one way of doing it.
services.Configure<RequestTracingMiddlewareOptions>(options =>
{
// List of regular expressions used to match the incoming requests path
// for which tracing is enabled.
// If the request path is not matched, no tracing will happen and the middleware
// is a no-op.
options.EnableFor = new[] { "/info", "/api/.*" };
});
// Alternatively, options can be loaded from a configuration section.
services.Configure<RequestTracingMiddlewareOptions>(
_configuration.GetSection(nameof(RequestTracingMiddlewareOptions)));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Make sure this is sufficiently early in the request pipeline.
app.UseRequestTracing();
// ...
app.UseMvc();
}
}
Only requests that match a path configured in RequestTracingMiddlewareOptions.EnabledFor
will be traced;
This is done because enabling tracing may have an impact on performance, as the request and the response needs buffering.
In order to trace all requests, just use a catch-all regular expression: ".*"
.
The logger category is AspNetCoreRequestTracing.RequestTracingMiddleware
.
The LogLevel
used for request is always LogLevel.Trace
.
For the responses, it depends on the StatusCode
:
- Any status code below 400 is logged using
LogLevel.Trace
- Any status code above 400 and below 500 is logged using
LogLevel.Warning
- Any status code above 500 is logged using
LogLevel.Error
Event ids used for the various messages:
Event id | Event Name | Description |
---|---|---|
300 | RequestTrace | Incoming request |
310 | ResponseTrace | Successful response |
311 | ResponseWarning | Response with a client error (4xx) |
312 | ResponseError | Response with a server error (5xx) |
To enable the logger, please consult the documentation regarding Logging in ASP.NET Core.
One way of configuring it is through the appsettings.json
file:
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"AspNetCoreRequestTracing.RequestTracingMiddleware": "Trace"
}
}
}
When adding Application Insights, by default all Warning
and Error
trace are captured,
which means that:
- no request information will be captured in Application Insights
- only responses with either a client error (4xx) or a server error (5xx) will be captured
To enable the capture for the requests and successful responses, please configure the
ApplicationInsightsLoggerProvider
to keep the Trace
level. This can be achieved through
the appsettings.json
file as well:
{
"Logging": {
"ApplicationInsights": {
"LogLevel": {
"AspNetCoreRequestTracing.RequestTracingMiddleware": "Trace"
}
},
"LogLevel": {
"Default": "Warning",
"AspNetCoreRequestTracing.RequestTracingMiddleware": "Trace"
}
}
}
Adding the middleware with no matching requests should have a negligible impact on the performance of the app. However, when a request path is matched, then several things need to happen to be able to fully trace the request and the response:
EnableRewind()
is called on theRequest
; this enables buffering for the requests- a secondary buffer for the
Response
is created to capture the writes in parallel to sending them back to the host server; this incurs additional processing and memory overhead; secondary buffered are pooled to minimize LOH allocations.
Please consult the CHANGELOG for more information about version history.
This project is licensed under the Apache 2.0 license - see the LICENSE file for details.
Please read CONTRIBUTING.md for details on the process for contributing to this project.
Be mindful of our Code of Conduct.
In order to mitigate the effect of allocating large buffers continuously, this
package uses pooled memory streams provided by the Microsoft.IO.RecyclableMemoryStream
package.