Typischerweise werden Anwendungsprotokolle von den Hintergrundprozessen geschrieben, prinzipiell können sie aber an beliebige Stellen genutzt werden. Die Anwendungsprotokolle haben eine gemeinsame Basis-Datentabelle (Basis.Anwendungsprotokoll / OrmLogBase). Daher kann man eigene Datentabellen davon ableiten und bestehende erweitern. Eine konkrete Datentabelle Anwendungsprotokoll / OrmLogDefault ist ebenfalls vorhanden. Diese kann genutzt werden, wenn keine speziellen Eigenschaften benötigt werden.

Anwendungsprotokolle sollten nicht mit einer UnitOfWork erstellt werden, stattdessen sollte es eine eigene Session haben, so dass fehlgeschlagene Transaktionen das Protokollieren nicht verhindert.

Erstellen / Speichern

Innerhalb eines Workers wird das Protokoll vom System erstellt und verwaltet, man sollte lediglich den Prozess auf den Auswahlwert EnumLogProcesses seines Prozesse setzen.

LoggingProcess =  EnumLogProcessesExtension.MyLog;

Anschließend kann man Einträge hinzufügen. Das Protokoll wird spätestens beim Hinzufügen des ersten Eintrags erstellt. Genaueres kann man ggf. über LoggingMode steuern.

Soll ein bestimmtes, existierendes Anwendungsprotokoll (weiter) geschrieben werden, Setzt man dazu im Konstruktor seines Workers die OID des Logs.

public MyWorker() : base()
{
   // ...
   LoggingProcess =  EnumLogProcessesExtension.MyLog;
   LoggerGuid = myLogGuid;
   LoggingMode = WorkerLoggingMode.Always;
   // ...
}

Wenn man spezielle Anforderungen bzgl. der Erstellung des Anwendungsprotokolls wie z.B. eine eigene Log-Datentabelle hat, kann man InitLogger() überschreiben.

protected override void InitLogger()
{
    // Special logger type
    OrmMySpecialLog logger = LoggerGuid == Guid.Empty
        ? new OrmMySpecialLog(Api.ORM.GetNewSession(), LoggingProcess, Name)
        : Api.ORM.GetOrm<OrmMySpecialLog>(LoggerGuid, Api.ORM.GetNewSession());
    Logger = logger;
    // set properties
    logger.Title = "My Title";
    logger.MyProeprty = 42;
}

Protokolleinträge

Das Hinzufügen von Einträgen ist thread-safe, asynchron und ohne LockingExceptions. Die Einträge bleiben auch dann erhalten, wenn die aktuelle UnitOfWork wegen eines Fehlers zurückgerollt wird. Keinsesfalls darf Logger.Save() während der Protokollierung verwendet werden!

Als Standard Api stehen folgende Methoden zur Verfügung.

public void AddInfo(string text, params object[] para)
public void AddWarning(string text, params object[] para)
public void AddError(string text, params object[] para)
public void AddFatal(string text, params object[] para)
public void AddDebug(string text, params object[] para)

Mehrzeilige Einträge dürfen nicht mit mehrfachen Aufruf der Add Methoden erzeugt werden, da die Auswertung dadurch erheblich erschwert wird. Stattdessen wird es mit \n Mehrzeilig gestaltet.

Beispiel:

Logger.AddInfo("Text mit {0} {1}", 2, "Platzhalter");
Logger.AddInfo("[INSERT TRANSLATION GUID]", 2, "Platzhalter");
Logger.AddInfo("Zeile 1\nZeile 2\Zeile 3");

Protokollsprache

In den Anwendungseinstellungen wird die “Inhaltssprache für Protokollierung” festgelegt. Daher muss man darauf achten nicht die üblichen Übersetzungsmethoden String.Translate() und Api.Text zu verwenden.

Die eigentlichen Api Methoden übersetzen selbst. Zusätzlich ist auf OrmLogBase eine entsprechende Translate() Methode vorhanden.

TranslatableException

Die Ausnahme TranslatableException kann genutzt werden, um Informationen für Protokolleinträge zu werfen. Siehe

Die entsprechend abgefangen werden sollte.

catch (TranslatableException tex)
{
    logger.AddEvent(tex);
}

Einrückungen im Protokoll

Einrückungen im Protokoll dienen für die Strukturierung und damit zur besseren Lesbarkeit. Beim Aufruf von CreateSubEvents() erhält man als Ergebnis einen Helper, der den Kontext bis zu seinem Dispose-Aufruf aufrecht erhält. Typischer Anwendungsfall:

Logger.AddInfo("Starting work XXX");
using (Logger.CreateSubEvents())
    foreach (wasauchimmer)
    {
        Logger.AddInfo("Jetzt bei YYY");
    }

Solche Kontexte können geschachtelt werden.

Es ist allerdings nicht zulässig, die Einrückung zu erhöhen, ohne vorher ein Event erzeugt zu haben. Alle neuen Einträge innerhalb des Sub-Entries-Kontextes werden zum letzten Event davor zugeordnet.
Im Besonderen sollte das nicht verwendet werden, um ein zusammengehöriges, mehrzeiliges Event zu ersetzen.

Falls die Protokollierung in dasselbe Log über verschiedene Log-Instanzen erfolgt, hat jede ihren eigenen Einrückungskontext. Dieser wird nicht gespeichert. Immer wenn ein Log neu geöffnet wird, um Einträge hinzuzufügen, beginnt man wieder im Top-Level.