Fachliches und technisches Logging mit Serilog

Logging, wie wir es typischerweise implementieren, entspricht einem technischen Logging. Hierbei wird die Programmlogik und für die Entscheidungsfindung relevante Informationen ins Logfile geschrieben. Zudem werden Fehlermeldung und womöglich deren Ursachen protokolliert.

Beim fachlichen Logging geht es mehr darum, dass man Ereignisse in einer Anwendung festhält. Das könnte z.B. das Kopieren einer Datei, das Erstellen eines Auftrags oder ähnliches sein. Auch hier macht es Sinn die Parameter mit aufzuzeichnen, aber nicht aus technischer Sicht, sondern um einem Anwender später eine Möglichkeit zu bieten, dass er alle kopierten Dateien sehen kann. Oder dass man leicht erkennen kann, warum eine Datei nicht kopiert wurde; dafür könnte in einem Log eine Meldung stehen wie „Datei ‚foo.docx‘ wurde nicht kopiert, weil ihr Status ‚Entwurf‘ ist“.

Aus technischer Sicht mag das genau dem gewünschten Verhalten entsprechen und womöglich nur einer „Verbose“ Meldung wert sein. Aus fachlicher Sicht mag das aber sehr wichtig sein.

Um solch ein Logging umzusetzen braucht man im Prinzip zwei Logger. Einen für das technische und einen für das fachliche Logging. Im Code könnte das so aussehen:

_logger.Debug("Trying to copy file {filename} with {fileStatus}", fileName, fileStatus);
_logger.ForContext("AuditLog", true).Information("Die Datei {fileName} wurde nicht kopiert, weil ihr Status {fileStatus} ist", fileName, fileStatus);

Durch das ForContext("AuditLog", true) wird dem Logger für diese Logmeldung eine zusätzliche Information mitgegeben. Somit kann das Logging-Framework entscheiden, was mit dieser Logmeldung passieren soll. In unserem Beispiel sollen Audit-Log Meldungen in ein eigenes Logfile geschrieben werden und nicht in dem technischen Log erscheinen. Dazu sieht die Konfiguration des Loggers wie folgt aus:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Logger(lc => lc
        .Filter.ByExcluding(Matching.WithProperty("AuditLog"))
        .WriteTo.File("technical.log")
    )
    .WriteTo.Logger(lc=>lc
        .Filter.ByIncludingOnly(Matching.WithProperty("AuditLog"))
        .WriteTo.File("audit.log")
    )
    .CreateLogger();

Somit werden die Logeinträge automatisch umgeleitet. Der erste Logger (Zeile 2) filtert dabei alle Einträge heraus, die das Attribut “AuditLog” haben, während der zweite Logger (Zeile 6) nur die Einträge berücksichtigt, die eben dieses Attribut aufweisen. Somit werden die Meldungen auf die beiden Logger aufgeteilt. An dieser Stelle könnte man natürlich auch unterschiedliche Sinks verwenden, so dass die Audit-Meldungen auf der Konsole landen oder in einer Datenbank oder was auch immer. Ebenso könnte man in dem ersten Logger auch einfach alle Meldungen erfassen, aber in diesem Szenario (technisches vs. fachliches Logging) will man die Einträge ja nicht mischen, da es sich um komplett unterschiedliche Zielgruppen handelt.

Nach oben scrollen