如何在ASP.NET Core 2.0中编写中间件测量API请求处理耗时?
这问题我太有发言权了!用中间件统一处理API请求耗时统计,绝对是解决重复编码问题的最优方案,既能实现全局管控,又能轻松集成你的自定义指标工具。下面给你唠唠具体实现思路和核心代码示例:
核心思路
中间件的本质就是请求管道里的“拦截器”——在请求到达控制器之前记录开始时间,在请求处理完成(包括异步操作)之后计算耗时,最后调用你的自定义工具把数据发送到指标分析引擎。全程不用碰任何控制器方法,完美实现无侵入式统计。
具体实现(以.NET为例,其他技术栈逻辑类似)
1. 编写自定义计时中间件
创建一个中间件类,负责时间记录和指标上报:
public class RequestTimingMiddleware { private readonly RequestDelegate _next; // 可以注入你的自定义指标发送工具 private readonly ICustomMetricsSender _metricsSender; public RequestTimingMiddleware(RequestDelegate next, ICustomMetricsSender metricsSender) { _next = next; _metricsSender = metricsSender; } public async Task InvokeAsync(HttpContext context) { // 记录请求开始时间 var startTime = DateTime.UtcNow; try { // 把请求传递给下一个中间件/控制器 await _next(context); } finally { // 计算耗时(不管成功还是失败都要统计) var elapsedMilliseconds = (DateTime.UtcNow - startTime).TotalMilliseconds; // 收集额外维度数据(可选,比如请求路径、HTTP方法、状态码) var requestPath = context.Request.Path.ToString(); var httpMethod = context.Request.Method; var statusCode = context.Response.StatusCode; // 调用自定义工具发送指标 await _metricsSender.SendTimingMetrics( requestPath, httpMethod, statusCode, elapsedMilliseconds ); } } }
2. 注册中间件到请求管道
在Program.cs里把中间件加入管道,注意顺序——要确保它能拦截到所有需要统计的请求,一般放在路由之后、端点之前:
var builder = WebApplication.CreateBuilder(args); // 注册你的自定义指标发送工具(依赖注入) builder.Services.AddSingleton<ICustomMetricsSender, CustomMetricsSender>(); var app = builder.Build(); // 其他中间件(比如日志、静态文件等) app.UseRouting(); // 注册计时中间件 app.UseMiddleware<RequestTimingMiddleware>(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); app.Run();
3. 适配你的自定义指标工具
只需要实现ICustomMetricsSender接口,把耗时数据按照指标引擎的要求格式发送即可,比如:
public interface ICustomMetricsSender { Task SendTimingMetrics(string requestPath, string httpMethod, int statusCode, double elapsedMilliseconds); } public class CustomMetricsSender : ICustomMetricsSender { public async Task SendTimingMetrics(string requestPath, string httpMethod, int statusCode, double elapsedMilliseconds) { // 这里写你的自定义工具逻辑,把数据发送到指标分析引擎 // 示例:构造请求体、调用上报接口等 var metricsData = new { Path = requestPath, Method = httpMethod, StatusCode = statusCode, DurationMs = elapsedMilliseconds, Timestamp = DateTime.UtcNow }; // 假设你的工具是通过HTTP上报的 // await _httpClient.PostAsJsonAsync("https://your-metrics-engine.com/api/metrics", metricsData); } }
关键注意事项
- 中间件顺序:一定要放在正确的位置,避免被其他中间件短路(比如授权中间件如果提前终止请求,你的计时中间件就收不到后续事件)
- 异步兼容性:必须用
await等待请求处理完成,不然统计的只是同步代码的时间,会漏掉异步操作的耗时 - 异常覆盖:用
try-finally确保即使请求抛出异常,也能记录耗时并上报,避免数据缺失 - 维度扩展:可以根据业务需要添加更多维度(比如用户ID、客户端IP),让指标分析更精准
内容的提问来源于stack exchange,提问作者blue
相关产品推荐
相关产品推荐

