Protokollierung in C#-Anwendungen: Best Practices und Tools (.NET)
Protokollierung ist nicht nur das Schreiben von Nachrichten in eine Datei. Es ist eine entscheidende Komponente jeder Production-Anwendung in C#. Ohne ein qualitativ hochwertiges Protokollierungssystem arbeiten Sie im Blindflug: Fehler bleiben unbemerkt, die Leistung ist schwer zu analysieren, und das Debuggen wird zum Ratespiel. In diesem Artikel behandeln wir die Best Practices für die Protokollierung im .NET-Ökosystem, betrachten beliebte Bibliotheken (Serilog, NLog), die richtigen Protokollierungsebenen und einen strukturierten Ansatz zur Datenerfassung.
1. Auswahl der Protokollierungsbibliothek: Serilog vs NLog
In der .NET-Welt gibt es mehrere ausgereifte Lösungen. Die beiden beliebtesten sind Serilog und NLog. Beide unterstützen asynchrone Protokollierung, zahlreiche Sinks (Ausgabeziele) und die Integration mit .NET Core/5+ über ILogger.
Serilog
Serilog ist bekannt für seine Philosophie der strukturierten Protokollierung. Anstelle einfacher Zeichenketten übergeben Sie Objekte, und Serilog serialisiert sie in JSON. Dies ist ideal für Systeme wie Elasticsearch, Seq oder Datadog.
// Beispiel Serilogusing Serilog;
Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .WriteTo.Console() .WriteTo.File("logs/app-.log", rollingInterval: RollingInterval.Day) .CreateLogger();
Log.Information("Benutzer {UserId} hat sich um {Time} angemeldet", userId, DateTime.UtcNow);NLog
NLog ist traditioneller, aber nicht weniger leistungsstark. Es eignet sich hervorragend für Projekte, die eine flexible Konfiguration über XML oder Code benötigen. Es unterstützt Dateirotation, E-Mail-Versand und die Integration mit Datenbanken.
// Beispiel NLogusing NLog;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
Logger.Info("Benutzer {UserId} hat eine Aktion ausgeführt", userId);Wann was wählen? Wenn Sie Microservices bauen oder den ELK-Stack verwenden, nehmen Sie Serilog. Wenn Sie eine einfache Einrichtung in Legacy-Projekten benötigen, nehmen Sie NLog. In jedem Fall unterstützen beide den Standard-ILogger aus Microsoft.Extensions.Logging.
2. Protokollierungsebenen: Wann und was schreiben
Einer der häufigsten Fehler ist es, alles wahllos auf der Ebene Information zu protokollieren oder umgekehrt überall Debug zu setzen. Verwenden Sie die richtigen Ebenen:
- Trace (0) — maximal detaillierte Informationen: Ein-/Austritt aus Methoden, Werte von Variablen. Wird nur beim Debuggen verwendet.
- Debug (1) — Debug-Meldungen, nützlich für den Entwickler, aber nicht für den Operator.
- Information (2) — Geschäftsereignisse: "Bestellung erstellt", "Benutzer registriert". Dies ist die primäre Arbeitsebene.
- Warning (3) — eine ungewöhnliche Situation, die die Anwendung nicht zum Absturz bringt: Request-Timeout, erneuter Verbindungsversuch.
- Error (4) — behandelte Ausnahmen, Fehler in der Geschäftslogik, Ausfälle in einem Modul.
- Critical (5) — fatale Fehler: Verbindungsverlust zur Datenbank, Speichermangel, Absturz der gesamten Anwendung.
// Beispiel für die korrekte Verwendung von Ebenenpublic async Task<Order> CreateOrderAsync(CreateOrderRequest request){ Log.Debug("Starte Erstellung der Bestellung für Benutzer {UserId}", request.UserId);
try { var order = new Order(request); await _repository.SaveAsync(order); Log.Information("Bestellung {OrderId} wurde von Benutzer {UserId} erstellt", order.Id, request.UserId); return order; } catch (DbException ex) { Log.Error(ex, "Datenbankfehler bei der Erstellung der Bestellung für Benutzer {UserId}", request.UserId); throw; // Nach oben weiterleiten }}3. Strukturierte Protokollierung: Warum ist das wichtig?
Traditionelle Protokollierung durch