Compartir a través de


Diagnóstico en Kestrel

Por Sourabh Shirhatti

En este artículo se proporcionan instrucciones para recopilar diagnósticos de Kestrel para ayudar a solucionar problemas. Temas cubiertos:

  • Registro: registros estructurados escritos en el registro de .NET Core. Los marcos de trabajo de la aplicación usan ILogger para escribir registros, y los usuarios, para su propio registro en una aplicación.
  • Métricas: representación de medidas de datos a lo largo de intervalos de tiempo, por ejemplo, solicitudes por segundo. Las métricas se emiten mediante EventCounter y se pueden observar con la herramienta de línea de comandos dotnet-counters o con Application Insights.
  • DiagnosticSource: DiagnosticSource es un mecanismo para el registro en tiempo de producción con las cargas de datos enriquecidos para su uso dentro del proceso. A diferencia del registro, que supone que los datos abandonarán el proceso y espera datos serializables, DiagnosticSource funciona bien con datos complejos.

Registro

Al igual que la mayoría de los componentes de ASP.NET Core, Kestrel usa Microsoft.Extensions.Logging para emitir información de registro. Kestrel emplea el uso de varias categorías, lo que le permite ser selectivo en los registros que escucha.

Nombre de la categoría de registro Eventos de registro
Microsoft.AspNetCore.Server.Kestrel ApplicationError, ConnectionHeadResponseBodyWrite, ApplicationNeverCompleted, RequestBodyStart, RequestBodyDone, RequestBodyNotEntirelyRead, RequestBodyDrainTimedOut, ResponseMinimumDataRateNotSatisfied, InvalidResponseHeaderRemoved, HeartbeatSlow
Microsoft.AspNetCore.Server.Kestrel.BadRequests ConnectionBadRequest, RequestProcessingError, RequestBodyMinimumDataRateNotSatisfied
Microsoft.AspNetCore.Server.Kestrel.Connections ConnectionAccepted, ConnectionStart, ConnectionStop, ConnectionPause, ConnectionResume, ConnectionKeepAlive, ConnectionRejected, ConnectionDisconnect, NotAllConnectionsClosedGracefully, NotAllConnectionsAborted, ApplicationAbortedConnection
Microsoft.AspNetCore.Server.Kestrel.Http2 Http2ConnectionError, Http2ConnectionClosing, Http2ConnectionClosed, Http2StreamError, Http2StreamResetAbort, HPackDecodingError, HPackEncodingError, Http2FrameReceived, Http2FrameSending, Http2MaxConcurrentStreamsReached
Microsoft.AspNetCore.Server.Kestrel.Http3 Http3ConnectionError, Http3ConnectionClosing, Http3ConnectionClosed, Http3StreamAbort, Http3FrameReceived, Http3FrameSending

Registro de conexiones

Kestrel también admite la capacidad de emitir registros de nivel de Debug para la comunicación a nivel de bytes y se puede habilitar según un esquema por puntos de conexión. Para habilitar el registro de conexiones, consulte Configuración de puntos de conexión para Kestrel

Métricas

Las métricas son una representación de medidas de datos a lo largo de intervalos de tiempo, por ejemplo, solicitudes por segundo. Los datos de las métricas permiten observar el estado de una aplicación en un general. Las métricas Kestrel se emiten mediante EventCounter.

Nota

Los contadores connections-per-second y tls-handshakes-per-second tienen nombres incorrectos. Los contadores:

  • No siempre contienen el número de conexiones nuevas o protocolos de enlace TLS por segundo.
  • Muestran el número de conexiones nuevas o protocolos de enlace TLS del último intervalo de actualización conforme a lo solicitado como consumidor de eventos a través del argumento EventCounterIntervalSec en filterPayload a KestrelEventSource.

Se recomienda que los consumidores de estos contadores escalen el valor de métrica en función de la propiedad DisplayRateTimeScale de un segundo.

Nombre Nombre para mostrar Descripción
connections-per-second Velocidad de conexión Número de nuevas conexiones entrantes por intervalo de actualización
total-connections Conexiones totales Número total de conexiones
tls-handshakes-per-second Velocidad del protocolo de enlace TLS Número de nuevos protocolos de enlace TLS por intervalo de actualización
total-tls-handshakes Protocolos de enlace TLS totales Número total de protocolos de enlace TLS
current-tls-handshakes Protocolos de enlace TLS actuales Número de protocolos de enlace TLS en curso
failed-tls-handshakes Protocolos de enlace TLS con errores Número total de protocolos de enlace TLS erróneos
current-connections Conexiones actuales Número total de conexiones, incluidas las conexiones inactivas
connection-queue-length Longitud de cola de conexión Número total de conexiones en cola en el grupo de subprocesos. En un sistema correcto en estado estable, este número siempre debe aproximarse a cero
request-queue-length Longitud de la cola de solicitudes Número total de solicitudes en cola en el grupo de subprocesos. En un sistema correcto en estado estable, este número siempre debe aproximarse a cero. Esta métrica es diferente de la cola de solicitudes de IIS/Http.Sys y no se puede comparar.
current-upgraded-requests Solicitudes actualizadas actuales (WebSockets) Número de solicitudes activas de WebSocket

DiagnosticSource

Kestrel emite un evento DiagnosticSource para las solicitudes HTTP rechazadas en el nivel de servidor, como las solicitudes incorrectas y las infracciones de protocolos. Por lo tanto, estas solicitudes nunca se convierten en la capa de hospedaje de ASP.NET Core.

Kestrel emite estos eventos con el nombre de evento Microsoft.AspNetCore.Server.Kestrel.BadRequest y IFeatureCollection como carga del objeto. La excepción subyacente se puede recuperar accediendo a IBadRequestExceptionFeature en la colección de características.

Resolver estos eventos es un proceso de dos pasos. Se debe crear un observador para DiagnosticListener:

class BadRequestEventListener : IObserver<KeyValuePair<string, object>>, IDisposable
{
    private readonly IDisposable _subscription;
    private readonly Action<IBadRequestExceptionFeature> _callback;

    public BadRequestEventListener(DiagnosticListener diagnosticListener, Action<IBadRequestExceptionFeature> callback)
    {
        _subscription = diagnosticListener.Subscribe(this!, IsEnabled);
        _callback = callback;
    }
    private static readonly Predicate<string> IsEnabled = (provider) => provider switch
    {
        "Microsoft.AspNetCore.Server.Kestrel.BadRequest" => true,
        _ => false
    };
    public void OnNext(KeyValuePair<string, object> pair)
    {
        if (pair.Value is IFeatureCollection featureCollection)
        {
            var badRequestFeature = featureCollection.Get<IBadRequestExceptionFeature>();

            if (badRequestFeature is not null)
            {
                _callback(badRequestFeature);
            }
        }
    }
    public void OnError(Exception error) { }
    public void OnCompleted() { }
    public virtual void Dispose() => _subscription.Dispose();
}

Suscríbase a DiagnosticListener de ASP.NET Core con el observador. En este ejemplo, se crea una devolución de llamada que registra la excepción subyacente.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
var diagnosticSource = app.Services.GetRequiredService<DiagnosticListener>();
using var badRequestListener = new BadRequestEventListener(diagnosticSource, (badRequestExceptionFeature) =>
{
    app.Logger.LogError(badRequestExceptionFeature.Error, "Bad request received");
});
app.MapGet("/", () => "Hello world");
app.Run();

Comportamiento con el depurador asociado

Algunos tiempos de espera y límites de velocidad no se aplican cuando hay un depurador asociado a un proceso Kestrel. Para más información, consulte Comportamiento con el depurador asociado.