前言
为了性能监控的目的,我们使用了Middleware记录所有请求的Log。实现代码如下:
public class RequestLoggingMiddleware
{
...
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
finally
{
//Log
}
}
}
同时,我们在服务中加入了健康检查API,用于定时访问检查服务状态。
这就导致Log中记录了大量健康检查API的日志,需要有方法判断出这类请求,并忽略日志写入。
判断路由地址
健康检查API的实现代码如下:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddHealthChecks();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
endpoints.MapControllers();
});
}
因此,可以根据路由地址是否以/health
开头来判断。
判断DisplayName
上面的方法虽然可以实现要求,但是感觉太low了!
而且,如果把Middleware做成公共组件,那就不能限制健康检查API的路由地址的格式。
需要重新找到一个不变的数据值用于判断。
查看Maphealthchecks的实现代码,发现这样一句代码:
private static IEndpointConventionBuilder MapHealthChecksCore(IEndpointRouteBuilder endpoints, string pattern, HealthCheckOptions? options)
{
...
return endpoints.Map(pattern, pipeline).WithDisplayName(DefaultDisplayName);
}
而DisplayName是个常量:
private const string DefaultDisplayName = "Health checks";
因此,我们只需判断Endpoint的DisplayName即可:
public class RequestLoggingMiddleware
{
...
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
finally
{
if (context.GetEndpoint()?.DisplayName == "Health checks")
{
}
else
{
//Log
}
}
}
}
结论
现在,我们已经可以轻松识别出健康检查API请求。
推荐使用DisplayName方式,容错性更高。