Udostępnij za pośrednictwem


Diagnostyka w programie Kestrel

Przez Sourabh Shirhatti

Ten artykuł zawiera wskazówki dotyczące zbierania danych diagnostycznych, Kestrel aby pomóc w rozwiązywaniu problemów. Omawiane tematy to m.in.:

  • Rejestrowanie: dzienniki ustrukturyzowane zapisywane w rejestrowaniu platformy .NET Core. ILogger jest używany przez struktury aplikacji do pisania dzienników i przez użytkowników na potrzeby własnego logowania w aplikacji.
  • Metryki: Reprezentacja miar danych w odstępach czasu, na przykład żądania na sekundę. Metryki są emitowane przy użyciu EventCounter polecenia i można je zaobserwować za pomocą narzędzia wiersza polecenia dotnet-counters lub aplikacji Szczegółowe informacje.
  • DiagnosticSource: DiagnosticSource to mechanizm rejestrowania w czasie produkcyjnym z zaawansowanymi ładunkami danych do użycia w ramach procesu. W przeciwieństwie do rejestrowania, które zakłada, że dane pozostawią proces i spodziewają się serializacji danych, DiagnosticSource dobrze współdziałają ze złożonymi danymi.

Rejestrowanie

Podobnie jak większość składników w programie ASP.NET Core, Kestrel używa Microsoft.Extensions.Logging metody do emitowania informacji dziennika. Kestrel wykorzystuje użycie wielu kategorii , które umożliwiają selektywne selektywne nasłuchiwanie dzienników.

Nazwa kategorii rejestrowania Rejestrowanie zdarzeń
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

Rejestrowanie Połączenie ionów

Kestrel Obsługuje również możliwość emitowania Debug dzienników na poziomie komunikacji na poziomie bajtów i może być włączona dla poszczególnych punktów końcowych. Aby włączyć rejestrowanie połączeń, zobacz konfigurowanie punktów końcowych dla Kestrel

Mierniki

Metryki to reprezentacja miar danych w odstępach czasu, na przykład żądania na sekundę. Dane metryk umożliwiają obserwację stanu aplikacji na wysokim poziomie. Kestrel metryki są emitowane przy użyciu polecenia EventCounter.

Uwaga

Liczniki connections-per-second i tls-handshakes-per-second są niepoprawnie nazwane. Liczniki:

  • Nie zawsze należy zawierać liczbę nowych połączeń ani uzgadniania protokołu TLS na sekundę
  • Wyświetl liczbę nowych połączeń lub uzgadniania protokołu TLS w ostatnim interwale aktualizacji zgodnie z żądaniem jako odbiorca zdarzeń za pośrednictwem argumentu EventCounterIntervalSecfilterPayload na .KestrelEventSource

Zalecamy użytkownikom tych liczników skalowanie wartości metryki na DisplayRateTimeScale podstawie jednej sekundy.

Imię i nazwisko/nazwa Nazwa wyświetlana Opis
connections-per-second Szybkość Połączenie ion Liczba nowych połączeń przychodzących na interwał aktualizacji
total-connections Łączna liczba Połączenie Całkowita liczba połączeń
tls-handshakes-per-second Szybkość uzgadniania protokołu TLS Liczba nowych uzgadniań protokołu TLS na interwał aktualizacji
total-tls-handshakes Łączna liczba uzgadniań protokołu TLS Całkowita liczba uzgadniań protokołu TLS
current-tls-handshakes Bieżące uzgadniania protokołu TLS Liczba uzgadniań protokołu TLS w procesie
failed-tls-handshakes Nieudane uzgadnianie protokołu TLS Całkowita liczba nieudanych uzgadniań protokołu TLS
current-connections Bieżące połączenia Całkowita liczba połączeń, w tym bezczynne połączenia
connection-queue-length Długość kolejki Połączenie ion Łączna liczba połączeń w kolejce do puli wątków. W systemie w dobrej kondycji w stanie stabilnym ta liczba powinna zawsze być zbliżona do zera
request-queue-length Długość kolejki żądań Łączna liczba żądań w kolejce do puli wątków. W zdrowym systemie w stanie stabilnym ta liczba powinna zawsze być zbliżona do zera. Ta metryka jest w przeciwieństwie do kolejki żądań IIS/Http.Sys i nie można jej porównać
current-upgraded-requests Bieżące uaktualnione żądania (WebSockets) Liczba aktywnych żądań protokołu WebSocket

DiagnosticSource

Kestrel Emituje DiagnosticSource zdarzenie dla żądań HTTP odrzuconych w warstwie serwera, takich jak źle sformułowane żądania i naruszenia protokołów. W związku z tym te żądania nigdy nie tworzą ich w warstwie hostingu ASP.NET Core.

Kestrel Emituje te zdarzenia z Microsoft.AspNetCore.Server.Kestrel.BadRequest nazwą zdarzenia i IFeatureCollection jako ładunkiem obiektu. Podstawowy wyjątek można pobrać, korzystając IBadRequestExceptionFeature z elementu w kolekcji funkcji.

Rozwiązywanie tych zdarzeń jest procesem dwuetapowym. Należy utworzyć obserwatora 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();
}

Zasubskrybuj ASP.NET Core DiagnosticListener za pomocą obserwatora. W tym przykładzie utworzymy wywołanie zwrotne, które rejestruje podstawowy wyjątek.

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

Zachowanie z dołączonym debugerem

Niektóre limity czasu i limity szybkości nie są wymuszane, gdy debuger jest dołączony do Kestrel procesu. Aby uzyskać więcej informacji, zobacz Zachowanie z dołączonym debugerem.