dotnet/aspnetcore

Request to make Kestrel BadHttpRequestException.Reason public

Open

#17,804 opened on 2019年12月12日

GitHub で見る
 (8 comments) (0 reactions) (0 assignees)C# (10,653 forks)batch import
affected-very-fewarea-networkingenhancementfeature-kestrelhelp wantedseverity-nice-to-have

Repository metrics

Stars
 (37,933 stars)
PR merge metrics
 (平均マージ 16d 9h) (30d で 258 merged PRs)

説明

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

コントリビューターガイド