Skip to content

Add endpoint metadata to disable HTTP metrics #56039

Closed
@JamesNK

Description

Background and Motivation

.NET 8 added support for metrics to ASP.NET Core. The most commonly used metric is http.server.request.duration, which captures request duration along with many other tags.

Today this metric is always captured, however there are situations where it is useful to disable collection. For example, system endpoints such as health checks and Prometheus scraping. These system endpoints are regularly polled and can distort expected results for people who want metrics to reflect true application usage.

There is high customer interest in solving this issue: #50654

Proposed API

There are two ways to specify metrics are disabled. The first is statically, per-endpoint, using metadata.

Assembly Microsoft.AspNetCore.Http.Abstractions:

namespace Microsoft.AspNetCore.Http.Metadata;

+ public interface IDisableHttpMetricsMetadata
+ {
+ }

Assembly Microsoft.AspNetCore.Http.Extensions:

namespace Microsoft.AspNetCore.Http;

+ public sealed class DisableHttpMetricsAttribute : Attribute, IDisableHttpMetricsMetadata
+ {
+ }

+ public static class HttpMetricsEndpointConventionBuilderExtensions
+ {
+     public static IEndpointConventionBuilder DisableHttpMetrics(this IEndpointConventionBuilder builder);
+ }

The second is dynamically disabling, per-request, using a feature.

namespace Microsoft.AspNetCore.Http.Features;

public interface IHttpMetricsTagsFeature
{
+     // This is a DIM property added to an existing interface.
+     // It's not ideal, but I don't think it is worth adding a new interface.
+     // I believe with a DIM property, setting it does nothing, and it will always return false. This is fine.
+     public bool MetricsDisabled { get; set; }
}

Usage Examples

Controller:

public class SystemController
{
    [DisableHttpMetrics]
    public IActionResult HealthCheck()
    {
        // ...
    }
}

Minimal API:

app.MapPrometheusScrapingEndpoint().DisableHttpMetrics();

Dynamically:

app.Use(async (context, next) =>
{
    // Disable metrics 50% of the time.
    if (Random.Shared.Next(0, 10) % 2 == 0)
    {
        context.Features.GetRequiredFeature<IHttpMetricsTagsFeature>().MetricsDisabled = true;
    }
    await next.Invoke();
});

Alternative Designs

Add a dedicated feature, e.g. IHttpMetricsDisableFeature, that would allow requests (or middleware) to decide whether to disable metrics dynamically.

Risks

Metadata

Assignees

No one assigned

    Labels

    api-approvedAPI was approved in API review, it can be implementedarea-hostingIncludes Hosting

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions