标题:使用 Prometheus 在 C# 中收集 API 调用的指标
我有一个 REST API 服务,我想收集有关我的所有 API 调用的信息。我尝试使用中间件来收集指标并将
httpContext.Request.Path
作为 api_name
标签传递。这种方法在大多数情况下都可以正常工作,但是当 API 路径中包含参数时,例如 api/{version}/{id}/doStuff
,就会变得具有挑战性。在这种情况下,API 路径中的参数组合对应的标签会很多.
为了解决这个问题,我想到在我的端点上使用一个名为
ActionFilterAttribute
的 TelemetryAttribute
。以下是如何实施的示例:
public class TelemetryAttribute : ActionFilterAttribute
{
public TelemetryAttribute(string requestId)
{
RequestId = requestId;
}
public string RequestId { get; set; }
public override void OnActionExecuting(ActionExecutingContext context)
{
context.HttpContext.Items["CustomItem"] = RequestId;
base.OnActionExecuting(context);
}
}
通过在我的端点上使用此属性,我认为我可以将请求的给定 id 添加到
httpContex
。但是,ActionFilterAttribute
仅在 _next(httpContext)
开始执行后才起作用,如 Microsoft 文档中所述。
Prometheus 不允许在创建指标实例后更改标签。所以我无法准确设置标签。
我可能可以使用秒表和
Histogram
提供的观察方法。但这不是我想要的。
这是中间件代码块:
public class ApiCallsMetricMiddleware
{
private readonly ITelemetryCollector _telemetryCollector;
private readonly RequestDelegate _next;
public ApiCallsMetricMiddleware(ITelemetryCollector telemetryCollector, RequestDelegate next)
{
_telemetryCollector = telemetryCollector;
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
var apiName = httpContext.Items["RequestId"] as string ?? httpContext.Request.Path;
using (_telemetryCollector.NewHistogramTimer(MetricsDefinitionDeclarations.ApiCallsHistogram, apiName))
{
await _next(httpContext);
}
}
}
你已经拥有了你所需要的一切
GetRouteData()
,除非我遗漏了一些东西:
public async Task Invoke(HttpContext httpContext)
{
var routeData = httpContext.GetRouteData();
//init apiName out of routeData
using (_telemetryCollector.NewHistogramTimer(MetricsDefinitionDeclarations.ApiCallsHistogram, apiName))
{
await _next(httpContext);
}
}