How does ASP.NET Core know which middleware was executed for a request?
The first step is to add a nuget package reference
Two Nuget packages need to be added: Microsoft.AspNetCore.MiddlewareAnalysis
and Microsoft.Extensions.DiagnosticAdapter
. The former is the core code implementation of the analysis and recording middleware and the latter is Used to receive log output. Since the DiagnosticSource method is used to record logs, you need to use the SubscribeWithAdapter method of the DiagnosticListener object to subscribe.
The second step is to implement an analysis and diagnosis adapter
This adapter is to facilitate us to output the log objects received from DiagnosticSource to the console. The specific code is implemented as follows
public class AnalysisDiagnosticAdapter
{
private readonly ILogger _logger;
public AnalysisDiagnosticAdapter(ILogger logger)
{
_logger = logger;
}
[DiagnosticName("Microsoft.AspNetCore.MiddlewareAnalysis.MiddlewareStarting")]
public void OnMiddlewareStarting(HttpContext httpContext, string name, Guid instance, long timestamp)
{
_logger.LogInformation($"Middleware-Start: '{name}'; Request Path: '{httpContext.Request.Path}'");
}
[DiagnosticName("Microsoft.AspNetCore.MiddlewareAnalysis.MiddlewareException")]
public void OnMiddlewareException(Exception exception, HttpContext httpContext, string name, Guid instance, long timestamp, long duration)
{
_logger.LogInformation($"Middleware-Exception: '{name}'; '{exception.Message}'");
}
[DiagnosticName("Microsoft.AspNetCore.MiddlewareAnalysis.MiddlewareFinished")]
public void OnMiddlewareFinished(HttpContext httpContext, string name, Guid instance, long timestamp, long duration)
{
_logger.LogInformation($"Middleware-End: Time-consuming [{duration/10000}] '{name}'; Status: '{httpContext.Response.StatusCode}'");
}
}
The third step is to register related services to enable the functions of the analysis middleware
- Register middleware analysis service
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMiddlewareAnalysis();
- Subscribe to our analytics diagnostic adapter
var listener = app.Services.GetRequiredService();
var observer = ActivatorUtilities.CreateInstance(app.Services);
using var disposable = listener.SubscribeWithAdapter(observer);
This basically completes the function of the analysis and recording middleware. Start the program to see the effect
The log has been successfully output to our console, but there are only four middlewares. There should be more than that. Add a code where to register the middleware analysis service
var builder = WebApplication.CreateBuilder(args);
//Add the following code
builder.Services.Insert(0, ServiceDescriptor.Transient());
builder.Services.AddMiddlewareAnalysis();
Now let’s take a look at the effect and find that there are 8 middlewares and four more middlewares
After compiling in Release mode, the execution efficiency of the middleware is found to be very high and it takes up almost no time
I won’t post pictures of the exception record here. Friends who are interested can try it themselves.
It is quite convenient to know which middleware is executed for a request in three simple steps. If you want to know the implementation principle, you can take a look at the Microsoft.AspNetCore.MiddlewareAnalysis library. There are only four files in total and it seems easy.