Audit-Log
Der Audit-Log ist ein Core-Modul des Weinhold Frameworks – er ist immer aktiv und kann nicht deaktiviert werden. Er protokolliert alle relevanten Aktionen im gesamten Multisite-Netzwerk in einer gemeinsamen Tabelle, getrennt nach Site-ID.
Allgemein
Was wird protokolliert?
Der Audit-Log ist in drei Kategorien unterteilt:
WordPress-Ereignisse – werden automatisch vom Modul erfasst:
Auth – Login (erfolgreich & fehlgeschlagen), Logout, Passwort-Reset-Anfragen und Resets inkl. IP-Adresse
Benutzer & Rollen – Registrierung, Löschung, Rollenwechsel, Profiländerungen, Zuweisung zu und Entfernung aus einzelnen Sites
E-Mail – Erfolgreicher Versand und fehlgeschlagene E-Mails inkl. Betreff und Empfänger
Content – Erstellung, Aktualisierung und Löschung von Beiträgen, Seiten, Medien, Kommentaren sowie Taxonomie-Begriffen
System – Plugin-Aktivierungen und -Deaktivierungen, Theme-Wechsel, Update-Prozesse
Framework – Änderungen an Weinhold-Framework-Einstellungen (netzwerkweit & pro Site)
Weinhold-Module – registrieren sich selbst über einen Filter (z.B. Kalender, Security Manager, Highlights)
Eigene Plugins – externe Plugins können sich über einen separaten Filter eintragen
Zwei Admin-Ansichten
Pro Site unter Weinhold → Audit-Log – zeigt ausschließlich Einträge der aktuellen Website, blätterbar (25/50/100/200 pro Seite, Sprung zu beliebiger Seite)
Netzwerkweit unter Weinhold Netzwerk → Audit-Log – zeigt Einträge aller Sites im Netzwerk, mit zusätzlichem Filter nach Site
Filtern & Exportieren
Beide Ansichten lassen sich filtern nach: Modul, Aktion, Status (ok / warning / error / info), Benutzer und Freitextsuche in Nachricht und Kontext. Alle gefilterten Einträge können als CSV exportiert werden – der Export selbst wird ebenfalls im Log protokolliert.
Statistiken
Der Tab Statistiken gibt einen grafischen Überblick über die Aktivität im gewählten Zeitraum. Filterbar nach Site, Zeitraum (7 / 14 / 30 / 90 / 180 / 365 Tage) und Modul.
Kacheln – Gesamtanzahl der Ereignisse sowie Aufschlüsselung nach Status (ok, warning, error, info)
Verlauf – Tägliches Balkendiagramm der Ereignisanzahl im gewählten Zeitraum
Ereignisse nach Modul – Horizontale Balken zeigen welche Module am aktivsten sind
Top Aktionen – Die 15 häufigsten Modul-Aktions-Kombinationen
Einstellungen
Die Einstellungen sind in drei Blöcke gegliedert:
WordPress-Ereignisse – Einzelne Kategorien (Auth, Benutzer, E-Mail Erfolg/Fehler, Content, System, Framework) lassen sich netzwerkweit ein- oder ausschalten
Weinhold-Module – Master-Schalter + pro Modul individuell aktivierbar/deaktivierbar
Eigene Plugins – Master-Schalter + pro Plugin individuell aktivierbar/deaktivierbar
Screenshot
Zusätzlich gibt es eine Aufbewahrungsfrist (1–3650 Tage, Standard: 90 Tage).
Pro-Site-Overrides
Jede Untersite kann den Netzwerk-Standard für jede einzelne Kategorie und für jedes einzelne Modul übersteuern – mit drei Optionen: Vererben (Netzwerk-Standard), Aktivieren oder Deaktivieren. So lässt sich z.B. die Gerätesicherheit nur auf einer bestimmten Untersite aktivieren, während sie auf den anderen vererbt-deaktiviert bleibt.
Aufbewahrung
Ein täglicher Cron-Job löscht automatisch alle Einträge die älter als die konfigurierte Aufbewahrungsfrist sind – in Batches von 500 Einträgen um die Datenbank nicht zu belasten.
Dateien
modules/audit_log_core.php – Lade-Stub (nur Modul-Header, wird vom Framework-Core erkannt und geladen)
modules/audit_log/audit_log.php – Daten- und Hook-Logik: Einstellungen, Datenbank-Installation, alle WordPress-Event-Hooks, die öffentliche API (log_event, get_rows, count_rows, get_stats, get_user_history). Wird auf jedem Seitenaufruf geladen, auch im Frontend.
modules/audit_log/admin.php – Die komplette Admin-Oberfläche: Formular-Verarbeitung, CSV-Export sowie das Rendering aller Tabs (Log, Statistiken, Einstellungen, Bereinigung). Wird nur im WordPress-Backend geladen (is_admin()-Prüfung in audit_log.php) – auf normalen Website-Seiten muss PHP diese Datei gar nicht erst einlesen.
Kein eigenes CSS oder JS – das Modul nutzt ausschließlich WordPress-Admin-Standardstile.
Für Entwickler
Alle Funktionen in diesem Abschnitt liegen in modules/audit_log/audit_log.php (siehe „Dateien“ oben) – sie sind unabhängig vom Admin-Bereich nutzbar.
Es gibt zwei separate Registrierungswege – je nachdem ob es sich um ein Weinhold-Modul oder ein externes Plugin handelt:
Weinhold-Module – Schritt 1: Modul registrieren
add_filter( ‚weinhold_audit_modules‘, function( $modules ) {
$modules[‚mein_modul‘] = array(
‚label‘ => ‚Mein Modul‘,
‚description‘ => ‚Kurzbeschreibung für die Einstellungsseite.‘,
‚actions‘ => array(
‚eintrag_erstellt‘ => ‚Eintrag erstellt‘,
‚eintrag_geloescht‘ => ‚Eintrag gelöscht‘,
),
);
return $modules;
} );
Eigene Plugins – Schritt 1: Plugin registrieren
add_filter( ‚weinhold_audit_custom_modules‘, function( $modules ) {
$modules[‚mein_plugin‘] = array(
‚label‘ => ‚Mein Plugin‘,
‚description‘ => ‚Kurzbeschreibung.‘,
‚actions‘ => array(
‚aktion_a‘ => ‚Aktion A‘,
),
);
return $modules;
} );
Schritt 2 – Event auslösen (gleich für beide)
if ( function_exists( ‚weinhold_audit_log_log_event‘ ) ) {
weinhold_audit_log_log_event(
‚mein_modul‘, // module_id (muss mit Registrierung übereinstimmen)
‚eintrag_erstellt‘, // action
‚Neuer Eintrag wurde angelegt.‘,
array(
’status‘ => ‚ok‘,
‚context‘ => array( ‚eintrag_id‘ => 42 ),
)
);
}
Die Funktion prüft selbst ob das Logging für das Modul aktiv ist und ob der jeweilige Master-Schalter gesetzt ist – kein eigenes Checking nötig.
Verfügbare Kontext-Felder
Feld Typ Bedeutung
status string ok, warning, error oder info
context array Beliebige zusätzliche Daten – werden als JSON gespeichert und sind durchsuchbar
actor_user_id int Wer hat die Aktion ausgelöst (Standard: eingeloggter Nutzer)
target_user_id int Wer ist betroffen (optional)
site_id int Für welche Site (Standard: aktuelle Site)
Datenstruktur eines Log-Eintrags
So sieht ein gespeicherter Eintrag in der Datenbank aus:
Spalte Typ Bedeutung
id bigint, Auto-Increment Primärschlüssel
created_at_gmt datetime Zeitstempel in UTC
site_id bigint Welche Site im Netzwerk
actor_user_id bigint, NULL möglich Wer hat die Aktion ausgelöst (NULL = System)
target_user_id bigint, NULL möglich Wen betrifft es (optional)
module varchar(64) Modul-ID, z.B. auth, content, mein_modul
action varchar(100) Aktion, z.B. login, post_updated
status varchar(20) ok / warning / error / info
message text Lesbare Beschreibung
context longtext JSON-String mit Zusatzdaten – durchsuchbar
Daten lesen
Funktion Beschreibung
weinhold_audit_log_get_rows( array $filters, int $limit = 50, int $offset = 0 ): array Gibt gefilterte Log-Einträge zurück. Filter: site_id, module, action, status, user_id, search, date_from, date_to. $limit ist auf 50.000 begrenzt.
weinhold_audit_log_count_rows( array $filters ): int Gesamtanzahl für Pagination – gleiche Filter wie oben.
weinhold_audit_log_get_stats( int $site_id = 0, int $days = 30, string $module_filter = “ ): array Liefert die Daten hinter dem Statistiken-Tab: Gesamtanzahl, Status-Aufschlüsselung, täglicher Verlauf, Ereignisse nach Modul, Top-Aktionen.
weinhold_audit_log_get_user_history( int $user_id, int $site_id = 0, int $limit = 20 ): array Letzte Aktionen eines bestimmten Benutzers.
Registrierte Module abfragen
Funktionen
weinhold_audit_get_weinhold_modules(): array // Nur Weinhold-eigene Module
weinhold_audit_get_custom_modules(): array // Nur externe/eigene Plugins
weinhold_audit_get_registered_modules(): array // Beide kombiniert
Wo die Einstellungen gespeichert werden
Option Speicherort Enthält
weinhold_audit_log_settings Netzwerk-Option Bool-Schalter pro WP-Kategorie, log_weinhold_modules/log_custom_modules (Master-Schalter), weinhold_toggles/custom_toggles (Array pro Modul-ID), retention_days
weinhold_audit_log_site_overrides Pro-Site-Option Gleiche Felder wie oben, aber dreiwertig: inherit / on / off. Modul-Overrides in weinhold_module_overrides / custom_module_overrides
Besonderheiten
Keine IP-Adress-Spalte in der Datenbank – IP-Adressen landen im context-JSON statt in einer eigenen Spalte. Die Freitextsuche durchsucht auch context, eine eigene Spalte war daher nicht nötig.
weinhold_audit_log_get_user_history() existiert, wird aber bewusst nicht im Benutzerprofil angezeigt – die Funktion ist fertig und nutzbar, aber (noch) an keiner Stelle im Admin verlinkt.
Kein doppeltes Logging bei neuen Beiträgen – transition_post_status überspringt Übergänge, bei denen der alte Status new oder auto-draft war, weil die Erstellung bereits über den save_post-Hook erfasst wird.
DB-Migrationen laufen versioniert – Pattern: aktuelle Version aus get_site_option(‚weinhold_audit_log_db_version‘, 0) lesen, dann if ($installed_version < N) { … }-Blöcke nacheinander abarbeiten. So bleiben Updates idempotent, auch wenn jemand mehrere Versionen überspringt.