标题:使用Prometheus收集C#中API调用的度量

我有一个REST API服务,我想收集所有API调用的信息.我try 使用中间件来收集指标,并将httpContext.Request.Path作为api_name标签传递.这种方法在大多数情况下都能正常工作,但是当API在路径中有参数时,例如api/{version}/{id}/doStuff,它就变得具有挑战性.在这种情况下,API路径中的参数组合将对应大量的标签.

为了解决这个问题,我想在我的终端上使用名为TelemetryAttribute ActionFilterAttribute.以下是如何实现它的一个示例:

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 documentation中所述.

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);
        }
    }
}

推荐答案

你有你需要的一切insdie 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);
    }
}

Csharp相关问答推荐

如何将ref T*重新解释为ref nint?

HttpContext. RequestAborted当Android APP失go 连接时未取消

MAUI查询参数单一字符串项将不起作用

C#.NET依赖项注入顺序澄清

无法创建';';类型的';DbContext';.异常';无法解析类型';Microsoft.EntityFrameworkCore.DbContextOptions`1[Comm的服务

如何使用新的Microsoft.IdentityModel.JsonWebToken创建JwtSecurityToken?

附加标题不起作用,而添加则起作用

在具有不同属性名称的两个类之间创建关系

如何捕获对ASP.NET核心应用程序的所有请求并将其发送到一个页面

调用Task.Run()与DoSomethingAsync()有什么不同?

C# CompareTo()和Compare()可以返回除-1和1以外的整数吗?

在swagger示例中添加默认数组列表

N层解决方案上的依赖注入-删除样板

有空容错运算符的对立面吗?

如何使用.NET6WPF打印车票?

C#多键字典和TryGetValue

CRL已过期,但ChainStatus告诉我RevocationStatus未知

从Base64转换为不同的字符串返回相同的结果

我是否应该注销全局异常处理程序

映射器-如何映射到多个实体