Share via


Diagnose in Kestrel

Von Sourabh Shirhatti

In diesem Artikel erhalten Sie eine Anleitung, wie Sie Diagnosedaten aus Kestrel erhalten, die Sie beim Troubleshooting von Problemen unterstützen. Folgende Themen werden behandelt:

  • Protokollierung: Strukturierte Protokolle, die in die .NET Core-Protokollierung geschrieben werden. ILogger wird von App-Frameworks verwendet, um Protokolle zu schreiben, sowie von Benutzern für die eigene Protokollierung in einer App.
  • Metriken: Hierbei handelt es sich um eine Darstellung von Datenmesswerten über bestimmte Zeiträume hinweg, beispielsweise für Anforderungen pro Sekunde. Metriken werden mithilfe von EventCounter ausgegeben und können mithilfe des dotnet-counters-Befehlszeilentools oder mit Application Insights überwacht werden.
  • DiagnosticSource:DiagnosticSource ist ein Mechanismus für die Protokollierung zur Produktionszeit mit umfangreichen Datennutzlasten für die Verarbeitung innerhalb des Prozesses. Im Gegensatz zur Protokollierung, bei der davon ausgegangen wird, dass Daten den Prozess verlassen und serialisierbare Daten erwarten, funktioniert DiagnosticSource gut mit komplexen Daten.

Protokollierung

Wie die meisten Komponenten in ASP.NET Core verwendet KestrelMicrosoft.Extensions.Logging, um protokollbezogene Informationen auszugeben. Kestrel verwendet mehrere Kategorien, wodurch Sie selektiv auswählen können, an welchen Protokollen Sie lauschen.

Name der Protokollierungskategorie Protokollierungsereignisse
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

Verbindungsprotokollierung

Kestrel unterstützt auch die Möglichkeit, Protokolle auf Debug-Ebene für die Kommunikation auf Byteebene ausgeben zu können, und kann auf Endpunktbasis aktiviert werden. Informationen zum Aktivieren der Verbindungsprotokollierung finden Sie unter Konfigurieren von Endpunkten für Kestrel

Metriken

Bei Metriken handelt es sich um eine Darstellung von Datenmesswerten über bestimmte Zeiträume hinweg, beispielsweise für Anforderungen pro Sekunde. Metrikdaten ermöglichen die Überwachung des Zustands einer App auf einer hohen Ebene. Kestrel Kestrel-Metriken werden mithilfe von EventCounter ausgegeben.

Hinweis

Die Leistungsindikatoren connections-per-second und tls-handshakes-per-second werden falsch benannt. Hinweise zu Leistungsindikatoren:

  • Sie enthalten nicht immer die Anzahl neuer Verbindungen oder TLS-Handshakes pro Sekunde.
  • Sie zeigen die Anzahl der neuen Verbindungs- oder TLS-Handshakes im letzten Aktualisierungsintervall an, wie als Consumer von Ereignissen über das Argument EventCounterIntervalSec in filterPayload für KestrelEventSource angefordert.

Consumern dieser Leistungsindikatoren wird empfohlen, den Metrikwert basierend auf DisplayRateTimeScale eine Sekunde hochzuskalieren.

Name Anzeigename BESCHREIBUNG
connections-per-second Verbindungsrate Die Anzahl der neuen eingehenden Verbindungen pro Updateintervall
total-connections Verbindungen insgesamt Gesamtzahl der Verbindungen
tls-handshakes-per-second TLS-Handshakerate Die Anzahl der TLS-Handshakes pro Updateintervall
total-tls-handshakes TLS-Handshakes gesamt Die Gesamtzahl der TLS-Handshakes
current-tls-handshakes Aktuelle TLS-Handshakes Die Anzahl von ausgeführten TLS-Handshakes
failed-tls-handshakes Fehlgeschlagene TLS-Handshakes Die Gesamtzahl der fehlgeschlagenen TLS-Handshakes.
current-connections Aktuelle Verbindungen Die Gesamtanzahl der Verbindungen, einschließlich Verbindungen im Leerlauf
connection-queue-length Länge der Verbindungswarteschlange Die Gesamtzahl der Verbindungen in der Warteschlange für den Threadpool. In einem fehlerfreien System im stabilen Zustand sollte diese Zahl immer nahe null (0) sein.
request-queue-length Länge der Anforderungswarteschlange Die Gesamtzahl der Anforderungen in der Warteschlange für den Threadpool. In einem fehlerfreien System im stabilen Zustand sollte diese Zahl immer nahe null (0) sein. Diese Metrik ist ein anderes Prinzip als die IIS/Http.Sys-Anforderungswarteschlange und kann daher nicht mit ihr verglichen werden.
current-upgraded-requests Aktuelle Anforderungen, für die ein Upgrade durchgeführt wurde (WebSockets) Die Anzahl der aktiven WebSocket-Verbindungen

DiagnosticSource

Kestrel Kestrel gibt ein DiagnosticSource-Ereignis für HTTP-Anforderungen aus, die auf Serverebene abgelehnt werden, z. B. fehlerhafte Anforderungen und Protokollverletzungen. Daher werden diese Anforderungen nie in die Hostebene von ASP.NET Core verschoben.

Kestrel gibt diese Ereignisse mit dem Microsoft.AspNetCore.Server.Kestrel.BadRequest-Ereignisnamen und einem IFeatureCollection als Objektnutzlast aus. Die zugrunde liegende Ausnahme kann abgerufen werden, indem Sie auf IBadRequestExceptionFeature in der Featuresammlung zugreifen.

Das Auflösen dieser Ereignisse ist ein zweistufiger Prozess. Ein Beobachter für DiagnosticListener muss erstellt werden:

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

Abonnieren Sie DiagnosticListener von ASP.NET Core mit dem Beobachter. In diesem Beispiel erstellen Sie einen Rückruf, der die zugrunde liegende Ausnahme protokolliert.

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

Verhalten mit angefügtem Debugger

Bestimmte Timeouts und Ratenbegrenzungen werden nicht erzwungen, wenn ein Debugger an einen Kestrel-Prozess angefügt ist. Weitere Informationen finden Sie unter Verhalten mit angefügtem Debugger.