dotnet/aspnetcore

Request to make Kestrel BadHttpRequestException.Reason public

Open

#17,804 创建于 2019年12月12日

在 GitHub 查看
 (8 评论) (0 反应) (0 负责人)C# (10,653 fork)batch import
affected-very-fewarea-networkingenhancementfeature-kestrelhelp wantedseverity-nice-to-have

仓库指标

Star
 (37,933 star)
PR 合并指标
 (平均合并 16天 9小时) (30 天内合并 258 个 PR)

描述

Is your feature request related to a problem? Please describe.

I'm implementing metrics telemetry for my web application and would like to have counters for different reasons we reject requests--whether it is due to Kestrel rejecting the request in its code or our application code rejecting the request.

I can't use BadHttpRequestException.Message because I can't guarantee the string doesn't have parameterized data in it (i.e. see use of {detail}/CoreStrings.FormatBadRequest). Pattern matching on the message would feel like unnecessary overhead. Parameterized messages would not be limited to a finite set of possible values, which would cause an explosion in the number of time series for the metrics collection.

Describe the solution you'd like

Please make BadHttpRequestException.Reason and enum RequestRejectionReason public. Then it would be trivial to have a counter like the code below.

To capture these counters, one could have a custom ILoggerFactory, which can create an ILogger for kestrel with a method that would be like the following code below. You could imagine that badRequestCounter may be a monotonically increasing counter whose storage is similar to Dictionary<string(bad request reason), ulong>. One may poll these values on an interval to put in a time-series database to calculate bad requests/second and set alerts. One could probably use scopes and a more sophisticated Log method to add additional dimensions to this counter.

internal void Log<TState>(LogLevel logLevel, string categoryName, string eventIdName, string originalFormat, Func<TState, Exception, string> formatter, TState state, Exception exception)
{
    if (exception is BadHttpRequestException bre)
    {
        badRequestCounter.Increment(bre.Reason.ToString())
    }
}

Additional context

Related #11208

贡献者指南