Sitecore-Logging auf High-Traffic-Sites

Jeder Sitecore-Entwickler weiss mit Sicherheit, wie man Log-Einträge schreibt. Z.B.

Log.Error("Some error occurred!", typeof(MyClass));

Mit der standard-Sitecore-Konfiguration würde das einen Eintrag im Log des aktuellen Tages machen. Dieser Standardansatz funktioniert gut, solange nicht allzu viel Traffic auf der Site herrscht. Auf hoch frequentierten Sites hingegen, wird die Analyse von Logs sehr schwierig.

Hauptprobleme sind:

  1. Sitecore erzeugt selbst Log-Einträge, die mit applikations-spezifischen Einträgen vermischt werden –> viele Log-Einträge
  2. Die Logging-Konfiguration (z.B.  Ausgabemedien oder Log-Level) können nicht geändert werden ohne Zugang zu den Config-Dateien
  3. Es ist nur schwer möglich, Log-Einträge einem bestimmten Request oder einer bestimmten Session zuzuordnen.

Bestehende Lösungen

In diversen Blog Posts sind bereits verschiedene Wege beschrieben worden, wie die Standard-Sitecore-Logging-Konfiguration verbessert werden kann. Zum Beispiel kann mit einem eigenen log4net Appender und logger ein eigenes Log-File als Ausgabemedium genutzt werden.

Ein weiterer Weg, eigene Log-Einträge von den Sitecore-eigenen Einträgen zu unterscheiden ist, eigene Log-Einträge mit einem Präfix zu versehen. Log4net kann dann mittels Regex-Pattern diese Einträge gesondert in ein eigenes Log schreiben.

Ferner kann die Ausgabe auf andere Medien z.B. in eine SQL-Tabelle die Analyse einfacher machen. John West beschreibt in seinem Post verschiedene Möglichkeiten, dies umzusetzen.

Eigene Log-Einträge von den Sitecore-eigenen Einträgen gesondert zu behandeln ist also möglich. Dies löst aber noch nicht unsere anderen beiden Probleme.

  1. Ist es auch mit eigenem Log-File immer noch schwierig, Log-Einträge einem bestimmten Request zuzuordnen und
  2. Für Anpassungen von Log-Level und Ausgabemedien ist eine Änderung der web.config nötig, was Server-Zugriff voraussetzt.

Dies sind die Gründe, wieso wir uns dafür entschieden haben, einen anderen Ansatz zu wählen.

Unser Ansatz

Die Grundidee ist, die Sitecore-Logging-Funktionen über eine eigene Logger-Klasse von unsrem Code zu entkoppeln. Das heisst konkret, dass wir eigene .Warn(), .Error(), usw. -Methoden implementieren.

 

Logger.Error("Some error occurred!");

Wird eine dieser Methoden aufgerufen, startet unser Logger dynamisch Processors für spezifische Ausgabemedien (ähnlich wie log4net appenders), die zur Laufzeit ein/ausgeschaltet und konfiguriert werden können.

Auf diese Weise können wir die ursprünglichen drei Probleme lösen:

  1. Unsere eigenen Log-Einträge können von denen des Sitecore-Systems getrennt werden, da wir eigene Log-Einträge über unsren eigenen Logger schreiben.
  2. Die Konfiguration von Log-Levels und Ausgabemedien kann zur Laufzeit über das Sitecore-Backend vorgenommen werden.
  3. Durch Implementieren eines Browser-Console-Log, können wir Log Events eines spezifischen Requests direkt zur Browser-Konsole ausgeben via HTTP- Headers. Dazu haben wir das FirePHP  Protokoll in .NET umgesetzt.

Mit diesem Ansatz gewinnen wir viel Flexibilität punkto Logging. Speziell in komplexen Infrastrukturen mit mehreren Servern und ohne direkten Zugang zu Config-Dateien kann dies eine grosse Hilfe beim Analysieren von Problemen sein.