Joomla-Logger einrichten. Logs in Datei schreiben. (Joomla-Klasse "Log" für's Debuggen nutzen.)
In der Joomla-Konfiguration findet sich ein Feld "Protokollverzeichnis". Im Normalfall wurde dieser Ordnerpfad durch ein Wunderwerk bereits gefüllt. Selten schaut der "normale" Benutzer in das Verzeichnis mal rein. Man findet darin gar nichts oder eine bis mehrere PHP-Dateien, so genannte Log-Dateien, die das Joomla oder Erweiterungen befüllen; mit unterschiedlichsten Infos, Warnungen, Fehlern und mehr.
Randbemerkungen
- PHP-Dateien sind diese Log-Dateien nur, damit sie nicht direkt per Internetbrowser gelesen werden können. Sie haben eine Zeile drinnen, die den eigentlichen Inhalt der Datei davor schützt. Man liest sie im einfachsten Fall in einem stinknormalen Texteditor, nachdem man sie z.B. per FTP heruntergeladen hat. Verwendet man den unten vorgestellten Code, muss man sich um eine solche Absicherung vor "Fremdlesern" der Logbücher nicht selbst kümmern. Allerdings kann man diesen Schutz auch deaktivieren (siehe unten Konfigurations-Option
text_file_no_php
). - In einem Joomla gibt es meist zwei Ordner namens
/logs/.
Welcher der aktive ist, findet man in oben erwähntem Feld "Protokollverzeichnis" in der Joomla-Konfiguration. Meist liegt er im/administrator/
-Verzeichnis. Theoretisch kann man dort einen eigenen eintragen, doch wozu? Möchte man für den eigenen Logger einen eigenen Pfad definieren, geht das (siehe unten Konfigurations-Optiontext_file_path
). - In einem Joomla, das schon mal ein Update erlebt hat, findet man ziemlich sicher die Datei
joomla_update.php
. Und, welch Wunder, darin das Protokoll der letzten Joomla-Updates. - In Joomla 4 gibt es unterhalb des Feldes "Protokollverzeichnis" die Einstellungen "Protokollieren" und "Veraltete (deprecated) API protokollieren". Wenn man diese aktiviert, werden nahezu in jedem Joomla die Dateien
everything.php
unddeprecated.php
angelegt. Bei Interesse kann man ja mal reinschauen, sollte allerdings nicht glauben, dass besonders zweitere für das alltägliche Debuggen sonderlich hilfreich ist. - Logrotation bis Joomla 4: PHP-Logdateien im Protokollverzeichnis werden regelmäßig gelöscht. Zuständig ist dafür das Core-Plugin namens "System – Protokollrotation". Mir ist das meist zu knapp eingestellt. Muss jeder selber entscheiden. Es ist möglich, mehrere, durchnummerierte Logdateien des selben Typs vorzuhalten. Auch das bedeutet eine größere Lebenszeit der Logbücher-Einträge und die einzelnen Dateien werden nicht so groß. Muss jeder...
- Logrotation ab Joomla 5: Das o.g. Plugin gibt es nicht mehr. Man muss unter "Aufgaben" eine Aufgabe vom Typ "Protokollrotation" einrichten und konfigurieren, damit PHP-Logdateien im Protokollverzeichnis regelmäßig gelöscht werden. Es ist möglich, mehrere, durchnummerierte Logdateien des selben Typs vorzuhalten. Auch das bedeutet eine größere Lebenszeit der Logbücher-Einträge und die einzelnen Dateien werden nicht so groß.
- Nettes Feature, wenn man den Joomla-Logger verwendet. Server-Pfade werden in der Protokolldatei als
[ROOT]
maskiert. Z.B.:[ROOT]/templates/j51_robyn/less/template.less
Einen eigenen Logger einrichten und verwenden
Die Joomla-eigene PHP-Klasse Log
ermöglicht es, eigene Meldungen in eine eigene Datei im konfigurierten logs/
-Verzeichnis zu schreiben, ohne, dass der Seitenbesucher etwas davon mitbekommt. Zwar gibt es auch eine Variante, die sowohl Texte in die Logs schreibt als auch auf der Webseite anzeigt, aber die ist hier nicht Thema.
Im Beispiel verwende ich ein eigenes System-Plugin "lessghsvs" von mir. Ist aber wurst, da man einen Logger in nahezu jeder Joomla-PHP-Datei, in jeder Erweiterung, jedem Override, Template usw., initialisieren kann. Und danach hat jede andere PHP-Datei im Joomla-Ablauf Zugriff darauf, um zu loggende Nachrichten in's eigene Logbuch zu schreiben. Ich nutze meinen Logger allerdings nur innerhalb meines Plugins in der Hauptdatei /plugins/system/lessghsvs/lessghsvs.php
., um einzelne Schritte als Infos, Warnungen oder Konfigurations-Fehler in den Plugin-Einstellungen, die zum Abbruch führten, aufzuzeichnen.
Schritt 1: Eine use
-Zeile an den Anfang der initialisierenden Datei
Ich gebe im Folgenden zusätzlich Alternativen an, wenn man auf diese verzichten möchte oder nicht weiß, wo diese Zeile hingehört.
use Joomla\CMS\Log\Log;
Schritt 2: Den eigenen Logger initialiseren, dem Joomla-System bekannt machen
$options = array(
'text_file' => 'plgSystemLessghsvs.php',
'text_entry_format' => '{DATETIME} {PRIORITY} {MESSAGE}',
);
Log::addLogger(
$options,
Log::ALL,
array('lessghsvs')
);
In Zeilen 1 bis 4 stelle ich die Konfigurations-Optionen für den Logger zusammen. Als text_file
sollte man immer eine eigene, individuelle Datei angeben und aus Sicherheitsgründen die Endung *.php
verwenden. Joomla verwendet sonst error.php
, was aber durchaus zu Kuddelmuddel im Logbuch führen kann.
Das Ausgabeformat für meine Debug-Notizen, text_entry_format
, in Zeile 3 gebe ich an, weil ich nur die drei Spalten Datum, Nachrichten-Art (siehe unten Log-Levels) und natürlich den Meldungstext sehen will. Lässt man diese Konfigurations-Option weg, verwendet Joomla eine Voreinstellung wie z.B.
{DATE} {TIME} {PRIORITY} {CLIENTIP} {CATEGORY} {MESSAGE}
Da kann ja das Interessierte:Inne selber rumprobieren, was für es "hübsch" ist.
Zeilen 6 bis 10 übergeben nun an die Log
-Klasse meinen Wunsch "Ich hätte gerne folgenden Logger eingerichtet.". Log::ALL
in Zeile 8, auf die ich ansonsten nicht weiter eingehe, garantiert uns, dass wirklich alle übergebenen Nachrichten aufgezeichnet werden, egal welche "PRIORITY", welchen Log-Level (siehe unten) sie haben. Zeile 9 enthät ein Array mit in meinem Fall nur 1 "CATEGORY", auf die mein Loggersystem lauschen soll. Nur, wenn ich die später mitgebe, weiß die Log
-Klasse, welches Logbuch verwendet werden soll. Die CATEGORY-Kürzel sind beliebig. Ich könnte auch "firlefanz" genommen haben oder "lessghvs" UND "firlefanz" UND...
Code-Alternative, wenn man keine use
-Zeile verwendet
$options = array(
'text_file' => 'plgSystemLessghsvs.php',
'text_entry_format' => '{DATETIME} {PRIORITY} {MESSAGE}',
);
\Joomla\CMS\Log\Log::addLogger(
$options,
\Joomla\CMS\Log\Log::ALL,
array('lessghsvs')
);
Falls Interesse: Weitere Konfiguration-$options
text_file_no_php
Setzt man den Parameter auf true
, schreibt Joomla NICHT in die Logdatei die einleitende Zeile #<?php die('Forbidden.'); ?>
. Damit ist also der oben erwähnte Schutz vor direkten Browserzugriffen nicht mehr gegeben.
text_file_path
Wenn man einen anderen Pfad für die Log-Datei verwenden möchte als Joomla ihn ermittelt, trägt man einen absoluten Server-Pfad ein. Vor- oder Nachteil(?): Die oben erwähnte Logrotation greift in einem eigenen Ordner nicht.
defer
Setzt man den Parameter auf true
, schreibt der Logger nicht sofort in die Log-Datei, sondern sammelt erst mal im Hintergrund alle Meldungen zusammen, um sie später in einem Schwung einzutragen. Nachteil dabei: Wird der PHP-Programmablauf durch einen fatalen Fehler abgebrochen, kann es sein, dass die Meldungen nicht festgehalten werden.
Schritt 3: Die eigene Log-Datei nutzen
So schreibt man eine Debug-Nachricht in seine Log-Datei und kann natürlich hier oder dort beliebig viele ähnliche Zeilen im System nutzen, um weitere aufzuzeichnen:
$msg = 'Keine Lust mehr. Ich breche ab!';
Log::add($msg, Log::ERROR, 'lessghsvs');
Nun finde ich in meiner Datei /administrator/logs/plgSystemLessghsvs.php
die Zeile
2022-10-15T20:12:29+00:00 ERROR Keine Lust mehr. Ich breche ab!
Code-Alternative, wenn man keine use
-Zeile verwendet
Man sieht schon, dass eine use
-Zeile am Anfang der Datei meist praktischer ist. Aber, dran denken, wenn man die Kurzform in anderen Dateien nutzt, brauchen die ebenso eine use
-Zeile. Abwägungssache, was letzendlich mehr nervt.
$msg = 'Keine Lust mehr. Ich breche ab!';
\Joomla\CMS\Log\Log::add($msg, \Joomla\CMS\Log\Log::ERROR, 'lessghsvs');
Log-Levels, PRIORITY
Im letzten Code-Block verwende ich ein komisches Log::ERROR
. In unserem einfachen Beispiel steckt da gar nicht viel Magie dahinter. In unserer Logbuch-Zeile wird das übersetzt nach "ERROR". Bei komplexer eingerichteten Logger-Instanzen, haben diese Log-Level unter Umständen tieferen Sinn. Deshalb verwende ich brav diese Log-Level-Konstanten wie in Joomla definiert. Je nachdem, wie ich meine Logzeile auszeichnen möchte-
const EMERGENCY = 'emergency';
const ALERT = 'alert';
const CRITICAL = 'critical';
const ERROR = 'error';
const WARNING = 'warning';
const NOTICE = 'notice';
const INFO = 'info';
const DEBUG = 'debug';