Bei der Anmeldung in ASP.NET-Anwendungen (Teil 1...wahrscheinlich) (Deutsch (German))

Bei der Anmeldung in ASP.NET-Anwendungen (Teil 1...wahrscheinlich)

Comments

NOTE: Apart from English (and even then it's questionable, I'm Scottish). These are machine translated in languages I don't read. If they're terrible please contact me.
You can see how this translation was done in this article.

Sunday, 27 October 2024

//

10 minute read

Einleitung

Logging ist OF COURSE ein kritischer Teil von Anwendungen, aber ich sehe es oft missverstanden / missbraucht in ASP.NET-Anwendungen. Dies ist Teil Post und Teil Manifest, wie man effektiv in ASP.NET Anwendungen anmelden.

Dies ist keine vollständige Anleitung zum Protokollieren; es gibt LOTS von denen da draußen; es geht mehr darum, eine effektive Protokollierungsstrategie für Ihre ASP.NET-Anwendungen zu wählen.

In der Hauptprotokollierung sollte NUTZLICH sein; ob es sich um die Protokollierung während der Entwicklung oder der Protokollierung in der Produktion handelt, es sollte nützlich für Sie / Ihr Team / Ihre Benutzer sein.

Das Problem

Zu oft wird Logging als das "nur tun, wenn es Ausnahmen" Sache gesehen. Ich denke, das missversteht, was Logging sein sollte.

LOGGING ist nicht nur für Exzeptionen

Im Allgemeinen sollten Sie in der Lage sein, einen wesentlichen Teil Ihrer Anwendung lokal auszuführen; in diesem Zusammenhang log.LogInformation ist dein Freund.

Die Lösung

Protokollierungserfolg

Im Laufe der 30 Jahre habe ich Code geschrieben Ich habe ein paar Beispiele für gute Protokollierung und WAY mehr Beispiele für schlechte Protokollierung gesehen.

Grundsätze des guten Holzeinschlags:

  1. Logging in Development sollte ausreichende Informationen darüber geben, wie Ihre Anwendung läuft, um zu verstehen, was passiert, wenn.
  2. Die Anmeldung in der Produktion sollte Ihnen einen super schnellen und einfachen Mechanismus geben, um zu verstehen, wie Ihre Anwendung fehlschlägt.
  3. Zuviel Protokollierung in der Produktion ist ein negatives; es kann Ihre Anwendung verlangsamen und es schwieriger machen, die wichtigen Sachen zu finden.

Denken Sie daran; das Protokollieren IMMER zieht Ihre Anwendungsleistung herunter; Sie sollten protokollieren, was Sie benötigen, um ein Problem zu diagnostizieren, aber nicht mehr in der Produktion / wo Leistung kritisch ist (z.B. führen Sie keinen Leistungstest durch, wenn Sie volle Debug-Protokollierung verwenden).

Arten der Anmeldung in ASP.NET

Serilog vs Microsoft.Extensions.Logging

In ASP.NET haben Sie bereits ein Build in der Protokollierung System; Microsoft.Extensions.Logging......................................................................................................... Das ist ein gutes Protokollierungssystem, aber es ist nicht so flexibel wie Serilog. Serilog ist ein flexibleres Protokollierungssystem, mit dem Sie sich an mehreren Waschbecken (Ausgänge) anmelden und Ihre Protokolle mit zusätzlichen Informationen bereichern können.

BootStrap-Protokollierung

Dies ist die Protokollierung, die passiert, wenn Ihre Anwendung startet. Es ist das erste, was passiert, und es ist das erste, was Sie sehen sollten, wenn Sie Ihre Anwendung ausführen. In ASP.NET vor allem, wenn Sie die Konfiguration verwenden, ist es wichtig, dass Sie verstehen, was passiert, wenn Ihre Anwendung startet. Es ist eine super gemeinsame Quelle von Problemen in ASP.NET-Anwendungen.

Zum Beispiel in Serilog können Sie dies tun:

Log.Logger = new LoggerConfiguration()
             .WriteTo.Console()
             .WriteTo.File("logs/boot-*.txt", rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7)
             .CreateBootstrapLogger();

HINWEIS: Dies ist begrenzt, da Sie an dieser Stelle keinen Zugriff auf die Konfiguration haben, um z.B. AppInsights zu verwenden, die Sie wahrscheinlich brauchen würden. #if RELEASE Blockieren, um den entsprechenden Schlüssel zu setzen.

Was dies tut, ist, Ihnen Daten über alle Startprobleme in Ihrer Anwendung zu geben; es schreibt sowohl an Konsole und eine Datei. Es ist auch wichtig, sicherzustellen, dass Sie nicht alle Protokolldateien speichern; Sie können hier sehen, dass wir nur 7 Tage im Wert von Protokollen speichern.

Sie möchten auch Ihre Start-Methode wickeln (in dieser App verwende ich die neue Program.cs Methode) in einem Versuch / fangen und protokollieren Sie alle Ausnahmen, die dort passieren.

try
 {
        ..all your startup code
 }
catch (Exception ex)
{
    if(args.Contains("migrate"))
    {
        Log.Information("Migration complete");
        return;
    }
    Log.Fatal(ex, "Application terminated unexpectedly");
}
finally
{
    Log.CloseAndFlush();
}

Der Log.CloseAndFlush() ist wichtig, da er sicherstellt, dass alle Protokolle auf die Festplatte geschrieben werden (Ihre App stürzt ab, sonst wird sie beendet, bevor sie dies tut).

Hier erkenne ich auch, ob die App in einem Migrationsmodus läuft und wenn ja, logge ich das und beende.

Log.Fatal ist die schwerste Log-Ebene; es wird verwendet, wenn Ihre Anwendung im Begriff ist, zu stürzen. Nicht alle Ausnahmen sind tödlich - Sie sollten Log.Error für diejenigen (es sei denn, sie bedeuten die APP (nicht der Antrag) kann nicht über diesen Punkt hinausgehen).

Protokollebenen

In ASP.NET (und.NET allgemeiner) haben Sie eine Reihe von Log-Levels:

  1. Log.Fatal - Dies ist die schwerste Log-Ebene; es wird verwendet, wenn Ihre Anwendung im Begriff ist, abstürzen.
  2. Log.Error - Dies wird verwendet, wenn eine Ausnahme auftritt, die bedeutet, dass die APP (nicht die Anfrage) nicht über diesen Punkt hinausgehen kann.
  3. Log.Warning - Dies wird verwendet, wenn etwas passiert, das kein Fehler ist, aber etwas ist, das Sie beachten sollten (z.B. ein degradierter Service / etwas nicht ganz richtig aber kein Irrtum).
  4. Log.Information - Dies wird für allgemeine Informationen über das, was in Ihrer Anwendung geschieht, verwendet.
  5. Log.Debug - Dieses wird für Informationen verwendet, die nur nützlich sind, wenn Sie Ihre Anwendung debuggen (es ist EVERYWHERE in der Entwicklung, aber sollte in der Produktion deaktiviert werden).

Für die Produktion würde ich in der Regel die Protokollierung als Log.Fatal, Log.Error und Log.Warning Nur.

Laufzeitprotokollierung

Im Gegensatz zum Startprotokollieren ist dies die Protokollierung, die passiert, wenn Ihre Anwendung läuft. Dies ist die Protokollierung, die Ihnen sagt, was in Ihrer Anwendung zu jeder Zeit geschieht.

Zum Beispiel, um diese in Serilog zu verwenden, würden Sie dies tun:

  "Serilog": {
    "Enrich": ["FromLogContext", "WithThreadId", "WithThreadName", "WithProcessId", "WithProcessName", "FromLogContext"],
    "MinimumLevel": "Warning",
    "WriteTo": [
        {
          "Name": "Seq",
          "Args":
          {
            "serverUrl": "http://seq:5341",
            "apiKey": ""
          }
        },
      {
        "Name": "Console"
      },
      {
        "Name": "File",
        "Args": {
          "path": "logs/applog-.txt",
          "rollingInterval": "Day"
        }
      }

    ],
    "Properties": {
      "ApplicationName": "mostlylucid"
    }
  },

Anreicherungen

Wie Sie sehen werden, bin ich ein ziemlich großer Fan von Serilog; es ist eine großartige Logging-Bibliothek, die sehr flexibel ist. Eines der Dinge, die ich daran mag, ist die Fähigkeit, Ihre Protokolle mit zusätzlichen Informationen zu bereichern. Dies kann sehr nützlich sein, um Probleme in Ihrer Anwendung zu diagnostizieren. Im obigen Beispiel sehen Sie, dass ich meine Protokolle mit der Thread-ID, dem Thread-Namen, der Prozess-ID und dem Prozess-Namen anreichere. Dies kann sehr nützlich sein, um Probleme in Ihrer Anwendung zu diagnostizieren.

Ich habe auch das Logging auf mehrere 'Sinks' (Outputs) gesetzt; in diesem Fall schicke ich es an die Konsole, an eine Datei und an Seq (ein Logging-Dienst).

Mehrere Waschbecken zu haben ist praktisch, falls man versagt, in diesem Fall ist mein bevorzugter Logging-Service Seq, also schicke ich es zuerst dorthin. Wenn das fehlschlägt, schicke ich es an die Konsole und an eine Datei.

Ich habe auch die Eigenschaft ApplicationName in den Protokollen gesetzt; dies kann nützlich sein, wenn Sie mehrere Anwendungen haben, die sich auf denselben Dienst einloggen (was Sie häufig für verteilte Anwendungen tun werden; zusammen mit einer Korrelations-ID, um die Protokolle für eine einzige Anfrage zusammenzubinden).

Wenn Sie beispielsweise ein JS-Frontend und ein.NET-Backend haben, können Sie die Korrelations-ID im Frontend festlegen und an das Backend übergeben. Dies ermöglicht es Ihnen, alle Protokolle für eine einzelne Anfrage an einem Ort zu sehen. ODER wenn Sie HttpClient in Ihrem Backend verwenden, können Sie die Korrelations-ID in den Headern an den anderen Dienst übergeben.

Es gibt eine große Berichterstattung darüber, wie man das hier tun könnte: https://josef.codes/append-correlation-id-to-all-log-entries-in-asp-net-core/ aber ich werde es in einem zukünftigen Beitrag abdecken.

Strukturierte Protokollierung

Strukturierte Protokollierung ist eine Art der Protokollierung, die es einfacher macht, Ihre Protokolle zu suchen und zu filtern. In Serilog können Sie dies tun, indem Sie die Log.Information("This is a log message with {Property1} and {Property2}", property1, property2); Syntax. Dies erleichtert die Suche nach Protokollen mit einer bestimmten Eigenschaft.

Kontextprotokollierung

Mit Serilog können Sie auch LogContext.PushProperty Eigenschaften zu Ihren Protokollen hinzuzufügen, die nur für einen bestimmten Bereich relevant sind. Dies kann sehr nützlich sein, um Probleme in Ihrer Anwendung zu diagnostizieren.

Serilog-Einrichtung

Serilog ist super flexibel, da es Ihnen erlaubt, es sowohl im Code als auch über config zu konfigurieren. Zum Beispiel, um die Konfiguration oben zu verwenden, würden Sie dies tun:

builder.Host.UseSerilog((context, services, configuration) =>
{
    configuration
        .MinimumLevel.Warning()
        .Enrich.FromLogContext()
        .Enrich.WithThreadId()
        .Enrich.WithThreadName()
        .Enrich.WithProcessId()
        .Enrich.WithProcessName()
        .WriteTo.Seq("http://seq:5341", apiKey: "")
        .WriteTo.Console()
        .WriteTo.File("logs/applog-.txt", rollingInterval: RollingInterval.Day)
        .Enrich.WithProperty("ApplicationName", "mostlylucid");
});

Dies ist das gleiche wie die Konfiguration oben, aber im Code. Dies ist nützlich, wenn Sie Ihre Anmeldung in Code einrichten möchten; es liegt wirklich an Ihnen, wie Sie es tun.

Ausnahmefilter

In ASP.NET können Sie Exception Filter verwenden, um Ausnahmen zu fangen und zu protokollieren. Dies ist ein guter Weg, um sicherzustellen, dass Sie alle Ausnahmen in Ihrer Anwendung protokollieren. WIE auch immer, es ist kein Ersatz für Methode Ebene Protokollierung; Sie sollten immer noch auf der Methode Ebene log, so können Sie sehen, was in Ihrer Anwendung im Detail geschieht; die Ausnahme-Filter zeigt nur, was passiert, wenn die gesamte Anfrage Stack wurde ungewickelt und kann oft sehr verwirrend, um herauszufinden, was passiert ist.

Dies änderte sich in ASP.NET Core 8 und es gibt eine TON, die Sie mit diesen tun können neue Funktionen.

Fehler wieder die gleichen Prinzipien gelten; Sie sollten sich auf der Ebene der Methode anmelden, so dass Sie sehen können, was in Ihrer Anwendung im Detail geschieht; die Exception Filter / Status-Handler zeigen einfach, was passiert, wenn der gesamte Anfragestapel entwickelt wurde und kann oft sehr verwirrend sein, um herauszufinden, was passiert ist.

LOG NICHT ALLES IM PROD

Die Protokollierung sollte der Umgebung angemessen sein; in der Entwicklung protokollieren Sie alles, so dass Sie sehen können, was an jedem Punkt in Ihrer Anwendung geschieht, aber im Test benötigen Sie weniger Protokollierung (vielleicht Protokollinformationen hier) und in der Produktion benötigen Sie noch weniger (Warnung und oben).

Es ist verlockend, alles in der Produktion zu protokollieren, aber es ist eine schlechte Idee. Du solltest alles protokollieren, was du brauchst, um ein Problem zu diagnostizieren, aber nicht mehr. In Cloud-Anbietern können Sie leicht für die Menge an Daten, die Sie an den Logging-Dienst senden berechnet werden, so sollten Sie vorsichtig sein, was Sie protokollieren und wie lange Sie diese Protokolle für (Application Insights speichert Protokolle für 90 Tage standardmäßig; dies ist oft zu lang und wird Sie für so lange, wie diese Protokolldaten gespeichert werden).

Für eine sehr 'aktive' App benötigen Sie einfach keine Langzeitprotokollierung dieser Daten; Sie haben eine gute Vorstellung davon, was in der App aus den letzten Tagen der Protokolle passiert.

Protokollierung anfordern

Einmal häufiges Problem, das ich in der Produktion sehe, ist die Protokollierung fehlgeschlagener Anfragen; während diese interessant sein können (kein Mensch will eine 404 / 401), können diese eine riesige Menge an Daten sein und sehr teuer sein zu speichern. Du solltest nur Dinge protokollieren. Sie beabsichtigen, zu beheben, für eine 404 kann es sein, dass dies wichtig ist, da es einen kaputten Link in Ihrer Anwendung anzeigen kann; für eine 401 kann es sein, dass dies wichtig ist, da es ein kaputtes Authentifizierungssystem anzeigen kann.

Wie ich bereits erwähnt habe, werden diese in dem Code, in dem sie tatsächlich vorkommen (im Fall von 401), besser behandelt; es kann sein, dass diese auch als ein protokolliert werden sollten. Warning oder Error in dem Code, der tatsächlich den 401 erzeugt.

Zum Einrichten von Request Logging in Serilog können Sie Folgendes tun:

app.UseSerilogRequestLogging();

Dies wird alle Anfragen an Ihre Anwendung protokollieren; es ist eine gute Möglichkeit zu sehen, was in Ihrer Anwendung auf einem hohen Niveau geschieht; aber wieder sollten Sie vorsichtig sein, was Sie protokollieren und wie lange Sie diese Protokolle behalten.

Für Application Insights möchten Sie sich möglicherweise immer noch mit Hilfe von Information Level loggen, da es Ihnen die raffinierte User Journey Funktion geben wird; dies ist eine großartige Möglichkeit zu sehen, wie Benutzer Ihre Anwendung verwenden und sehr nützlich bei der Diagnose von Problemen sein können; jedoch wieder diese schnell Rack-up Kosten, so dass Sie vorsichtig sein sollten, was Sie loggen und wie lange Sie diese Protokolle behalten.

Schlussfolgerung

Das ist es also, ein schneller Durchlauf, wie man sich in ASP.NET-Anwendungen meldet. Ein Großteil davon ist eine Reaktion auf übereifrige, nutzlose Protokolle, die ich in vielen Produktionsanwendungen sehe. In der Entwicklung wollen Sie sehen wie die App läuft; in der Produktion wollen Sie sehen wie die App fehlschlägt. Logging ist zu oft ein nutzloser, teurer Teil der Anwendungsentwicklung. Wie bei allem in der Software-Entwicklung sollte Logging auf den USER konzentriert werden; ob seine Sie / andere Entwickler während der Arbeit an der App in Ihrer IDE / lokal oder die Lösung von Problemen in der Produktion schnell und effizient.

logo

©2024 Scott Galloway