Terug naar hoofdinhoud
Actionlogs in Joomla
Op deze pagina
# Topics

Actionlogs in Joomla

20 juni 2026

Vroeg of laat stelt elke website-eigenaar een vraag die begint met "wie". Wie heeft gisteravond de homepage gedepubliceerd? Wie heeft die extensie geïnstalleerd die niemand herkent? Heeft de nieuwe redacteur echt twaalf artikelen verwijderd, of vergist de klant zich?

Zonder registratie hebben deze vragen geen antwoord en blijft je gissen.

Joomla beantwoordt ze met een kleine maar krachtige kerncomponent genaamd User Actions Log (com_actionlogs). Deze registreert stilletjes elke belangrijke wijziging op je site: opslaan, verwijderen, publiceren, inloggen, installeren en configuratiewijzigingen. Elke registratie bevat de gebruiker, de actie, het tijdstip en (optioneel) het IP-adres. Je hoeft niets te installeren. Het zit al in Joomla.

Wie wat deed, wanneer en vanaf waar, automatisch vastgelegd door Joomla zonder één enkele extensie van derden.

In dit artikel leggen we uit hoe de component Action Logs werkt, wat er wordt geregistreerd, hoe je het logboek kunt lezen en filteren, hoe meldingen en CSV-export werken en hoe je het logboek gezond houdt op een drukbezochte website. Het doel is om website-eigenaren, beheerders en ontwikkelaars voldoende inzicht te geven in deze stille getuige, zodat ze erop kunnen vertrouwen op de dag dat het nodig is.

1. De basis

1.1 Wat is het User Actions Log?

Het User Actions Log (com_actionlogs) is Joomla's ingebouwde auditlogcomponent. Joomla introduceerde deze in versie 3.9 (mei 2018) en sindsdien maakt deze standaard deel uit van de core.

Een aantal zaken maakt deze component bijzonder:

  • Voor elke geregistreerde actie wordt één record opgeslagen in één tabel: #__action_logs.
  • Het systeem werkt op basis van events, niet via polling. Elke actie genereert een Joomla-event, een plugin vangt dit op en schrijft een record weg.
  • Elk record bevat de gebruiker, de tijdstempel, de extensiecontext, het item-ID, het IP-adres en een bericht gebaseerd op een taalstring.
  • Het logboek is vanuit de interface alleen-lezen. Beheerders kunnen het bekijken, filteren, exporteren of opschonen, maar niet afzonderlijke records bewerken.

Dat laatste is belangrijk. Een auditlog die je kunt wijzigen is eigenlijk geen auditlog. Joomla biedt daarom bewust geen bewerkscherm voor logregels.

1.2 Een opmerking over de naamgeving: "Action Logs" versus "User Actions Log"

Voordat we verdergaan, is het goed om een veelvoorkomende bron van verwarring weg te nemen. Joomla gebruikt twee namen voor hetzelfde onderdeel, en die inconsistentie zorgt regelmatig voor verwarring:

Waar je het zietGebruikte naam
Menu-item in het beheer (J4 / 5 / 6) Gebruikers → Actielogs
Titel van het helpscherm User Actions Log: Opties
Koptekst van de lijstweergave User Actions Log
Officiële documentatiesite User Actions Log
Componentmap / interne naam com_actionlogs
Naam van de registratieplugin Action Log - Joomla (enkelvoud "Log")
Naam van de notificatieplugin System - Action Logs (meervoud "Logs")

"User Actions Log" is de formele, oorspronkelijke naam die Joomla in versie 3.9 aan deze functie gaf. Deze naam komt nog steeds voor in de helpdocumentatie en in de titelbalk. "Action Logs" is de kortere benaming die uiteindelijk in het beheermenu en in het dagelijks gebruik terechtkwam. Beide verwijzen naar dezelfde component, dezelfde databasetabellen en dezelfde plugins. Er bestaat geen aparte functie genaamd "User Action Logs".

Een historisch detail maakt de verwarring nog iets groter. In Joomla 3.9 en 3.10 stond het menu-item onder System → User Actions Log. Vanaf Joomla 4 verhuisde het naar Gebruikers → Actielogs. Oudere handleidingen en schermafbeeldingen tonen daarom nog de oude naam en locatie. In dit artikel betekenen "Action Logs" en "User Actions Log" hetzelfde. Bij twijfel is de officiële identificatie com_actionlogs.

1.3 Waar vind ik het?

In de Joomla 6-beheeromgeving zijn de volgende locaties relevant:

Gebruikers → Actielogs                           (de logviewer)
Gebruikers → Actielogs → Opties                 (instellingen + ACL)
Gebruikers → Meldingen Actielogs                (e-mailmeldingen per gebruiker)
Systeem → Beheren → Plugins → Action Log - Joomla   (de recorder)
Systeem → Beheren → Plugins → System - Action Logs  (de notifier)

De component bevindt zich in administrator/components/com_actionlogs/. De twee plugins bevinden zich in plugins/actionlog/joomla/ (de recorder) en plugins/system/actionlogs/ (de notifier).

Een detail waar veel mensen over struikelen: de component staat onder Gebruikers en niet onder Systeem. Oudere schermafbeeldingen suggereren soms anders.

1.4 De drie onderdelen

Action Logs bestaat uit drie onderdelen die samenwerken:

OnderdeelFunctie
com_actionlogs Backend-lijstweergave, filters, CSV-export en opschonen.
plg_actionlog_joomla Luistert naar events en schrijft logregels weg.
plg_system_actionlogs Verstuurt meldingsmails en verwerkt berichten.

Alle drie worden in Joomla 6 standaard ingeschakeld meegeleverd. Schakel je de recorder uit, dan wordt er niets meer geregistreerd. Schakel je de notifier uit, dan blijft het logboek groeien maar worden er geen e-mails meer verzonden.

1.5 Eerste kennismaking met het logboek

Open Gebruikers → Actielogs. De lijst wordt standaard gesorteerd op nieuwste eerst. Een typische regel ziet er als volgt uit:

KolomVoorbeeld
Actie Gebruiker article-editor heeft ingelogd in het beheer.
Datum 2026-05-28 09:14:02 (relatief: "een paar seconden geleden")
Extensie com_users
Gebruiker admin
IP-adres 10.10.10.1 (of "Uitgeschakeld" als IP-registratie uit staat)

Klik op de actietekst en Joomla klapt de regel open. Je ziet dan het onderliggende berichtsjabloon en de JSON-gecodeerde context. Op die JSON komen we terug in sectie 6.

1.6 De lijst filteren

De filterbalk boven de lijstweergave biedt vier hulpmiddelen:

  • Zoeken: vrije tekst op basis van het weergegeven bericht.
  • Gebruiker: filter op activiteiten van één gebruiker.
  • Extensie: alleen com_content, alleen com_users, enzovoort.
  • Datumbereik: een begin- en einddatum selecteren.

De meest bruikbare combinatie is Gebruiker + Datumbereik. Daarmee beantwoord je de dagelijkse vraag "laat alles zien wat Alice afgelopen woensdag heeft gedaan" met slechts twee klikken.

Naar boven

2. Wat wordt er gelogd?

2.1 De standaard gelogde extensies

U bepaalt zelf welke componenten worden gevolgd via Opties → Gelogde extensies. Dit is een meerkeuzelijst waarin standaard alle core-componenten zijn ingeschakeld:

com_banners     com_cache       com_categories   com_checkin
com_config      com_contact     com_content      com_fields
com_guidedtours com_installer   com_media        com_menus
com_messages    com_modules     com_newsfeeds    com_plugins
com_redirect    com_scheduler   com_tags         com_templates
com_users

Verwijder je een extensie uit deze lijst, dan worden de gebeurtenissen ervan stilzwijgend genegeerd. Er worden geen logregels meer aangemaakt. Het beperken van deze lijst is de meest effectieve manier om logvervuiling op een drukke website te verminderen.

2.2 Gebeurtenissen in de contentlevenscyclus

Voor elke logbare component abonneert de recorder-plugin zich op drie content-events:

EventWat wordt gelogd
onContentAfterSave Aanmaken of bijwerken, inclusief ID, titel en een nieuwe/bijgewerkte status.
onContentAfterDelete Verwijderen, inclusief ID en titel (vastgelegd vóór verwijdering).
onContentChangeState Publiceren, depubliceren, archiveren of naar de prullenbak verplaatsen, inclusief de nieuwe status.

Elke keer dat je een artikel opslaat, een categorie verwijdert of een menu-item publiceert, wordt er dus een logregel aangemaakt.

2.3 Gebeurtenissen in de gebruikerslevenscyclus

Gebruikersgebeurtenissen zijn het belangrijkst voor het opsporen van misbruik van accounts:

EventWat wordt gelogd
onUserAfterLogin Succesvolle login (frontend of backend, maar nooit API-logins).
onUserLoginFailure Mislukte login, maar alleen als de gebruikersnaam bestaat.
onUserLogout Expliciet uitloggen.
onUserAfterSave Aanmaken of bewerken van een gebruiker (inclusief groepswijzigingen).
onUserAfterDelete Verwijderen van een gebruiker.
onUserAfterRemind Aanvraag voor "Gebruikersnaam vergeten".
onUserAfterResetRequest Aanvraag voor een wachtwoordresetlink.
onUserAfterResetComplete Voltooien van een wachtwoordreset.

Een detail dat veel mensen verrast: mislukte logins met een onbekende gebruikersnaam worden niet gelogd. De plugin controleert eerst of de gebruiker bestaat, waardoor geautomatiseerde scans en bots niet in het auditlog terechtkomen.

2.4 Gebeurtenissen rond extensies

Alles wat wijzigingen aanbrengt in de extensietabel wordt geregistreerd:

EventWat wordt gelogd
onExtensionAfterInstall Installatie, inclusief type, naam en versie.
onExtensionAfterUpdate Update van oude naar nieuwe versie.
onExtensionAfterUninstall Deïnstallatie.
onExtensionAfterSave Bewerking, bijvoorbeeld het in- of uitschakelen van een plugin.
onJoomlaAfterUpdate Bijwerken van de Joomla-coreversie.

Dit is bijzonder waardevol bij onderzoek na een incident. De vraag "wanneer hebben we die kwetsbare plugin geïnstalleerd?" is dan met één zoekopdracht te beantwoorden.

2.5 Configuratiewijzigingen

Joomla registreert ook het opslaan van configuraties:

  • onApplicationAfterSave: de Algemene Configuratie is opgeslagen.
  • onExtensionAfterSave met context com_config.component: het Opties-scherm van een component is opgeslagen.

In beide gevallen wordt vastgelegd welke instellingengroep is gewijzigd, maar niet welke waarden precies zijn veranderd. Als je een exacte vergelijking tussen oude en nieuwe waarden nodig heeft, is daarvoor een kleine maatwerkplugin nodig (zie sectie 11).

2.6 Operationele gebeurtenissen

Ook enkele onderhoudsacties worden geregistreerd:

EventWat wordt gelogd
onAfterCheckin Een beheerder heeft een vergrendeld item geforceerd ingecheckt.
onAfterPurge De cache is geleegd.
onAfterLogPurge Het actielogboek is opgeschoond.
onAfterLogExport Een CSV-export is gedownload.

Ja, het opschonen van het logboek wordt zelf ook gelogd. Na een opschoning blijft er precies één regel over: "Gebruiker admin heeft de actielogs opgeschoond." Het auditspoor documenteert zichzelf.

2.7 API-verzoeken (optioneel)

Als je Opties → API-endpoints loggen = Ja inschakelt, registreert Joomla iedere Web Services API-aanroep tijdens de verwerking. Met een tweede optie, Gelogde HTTP-methoden, bepaal je welke verzoektypen worden vastgelegd. Standaard staat alleen GET aan, maar op productiesites kiest men meestal minimaal ook voor POST, PUT, PATCH en DELETE.

Een waarschuwing: API-logging vult de tabel erg snel. Schakel het in tijdens een onderzoek en schakel het daarna weer uit voor normaal gebruik. In sectie 8 bekijken we de impact op de omvang van het logboek.

Naar boven

3. Meldingen

3.1 Het opt-inmodel

Elke gebruiker kan zich aanmelden voor e-mailmeldingen van één of meer extensies via Gebruikers → Meldingen Actielogs. Deze voorkeuren worden opgeslagen in #__action_logs_users:

user_id    notify (0/1)    extensions  (komma-gescheiden lijst met contexten)
  • Een gebruiker die niet in deze tabel voorkomt, ontvangt geen meldingen.
  • Een gebruiker met notify = 1 en extensions = com_users,com_installer ontvangt een e-mail telkens wanneer iemand gebruikers of extensies wijzigt.

Meldingen zijn een persoonlijke keuze per gebruiker en geen sitebrede instelling. Power users en security officers melden zich aan, terwijl andere gebruikers geen berichten ontvangen.

3.2 Hoe ziet de e-mail eruit?

De notifier gebruikt hetzelfde leesbare bericht als in de lijstweergave, aangevuld met:

  • Een directe link naar het betreffende item, indien beschikbaar.
  • De naam van de gebruiker die de actie uitvoerde.
  • Een link naar de betreffende logregel.

De e-mail wordt verzonden via de ingestelde mailserver. Controleer daarom de configuratie onder Systeem → Algemene Configuratie → Server → E-mail voordat je op meldingen vertrouwt. In een lokale Docker-omgeving kan een tool zoals MailHog alle uitgaande berichten opvangen zodat je veilig kunt testen.

3.3 De rol van de systeemplugin

Het helpt om de twee plugins duidelijk uit elkaar te houden:

  • De plugin Action Log - Joomla schrijft uitsluitend logregels weg.
  • De plugin System - Action Logs verzorgt meldingen per e-mail en de verwerking van berichten.

Als je de systeemplugin uitschakelt, blijft het logboek gewoon groeien en blijven de berichten zichtbaar, maar worden er geen meldingsmails meer verstuurd. Laat beide plugins in productie ingeschakeld. Schakel de systeemplugin alleen tijdelijk uit als je e-mailstormen wilt voorkomen tijdens een grote migratie.

Naar boven

4. Exporteren en opschonen

4.1 CSV-export

De lijstweergave bevat twee exportknoppen in de werkbalk:

KnopWat wordt geëxporteerd
Geselecteerde exporteren Alleen de regels die je hebt geselecteerd.
Alles exporteren Het volledige logboek, rekening houdend met de actieve filters.

Het scheidingsteken is instelbaar via Opties → CSV-scheidingsteken. Kies een puntkomma (;) als je spreadsheetprogramma (zoals de Nederlandse versie van Excel) komma's als decimaalteken gebruikt.

De export wordt streamend uitgevoerd, één regel tegelijk. Daardoor raakt zelfs een logboek met een miljoen records niet door het beschikbare PHP-geheugen heen.

4.2 Bescherming tegen CSV-injectie

Joomla ontsnapt automatisch elke cel die begint met =, +, -, @, een tabteken of een carriage return door er een enkele apostrof voor te plaatsen. Dit voorkomt de klassieke aanval via "Excel-formule-injectie", waarbij een gelogde gebruikersnaam zoals =cmd|'/c calc'!A1 anders als formule zou worden uitgevoerd zodra een beheerder het CSV-bestand opent.

Als je ooit een eigen exportfunctie ontwikkelt, behoud deze beveiliging. Die is er met een goede reden.

4.3 Het logboek opschonen

Met de knop Opschonen in de werkbalk verwijder je alle records uit #__action_logs. Daarna schrijft Joomla direct één nieuwe logregel weg, zodat er altijd één record overblijft waarin staat wie het logboek heeft opgeschoond en wanneer.

Veelvoorkomende redenen om het logboek op te schonen:

  • Na een langdurige migratieperiode, wanneer je met een schone lei wilt beginnen.
  • Voordat je uitsluitend recente activiteiten wilt exporteren.

Er is geen mogelijkheid om dit ongedaan te maken en Joomla bevat geen ingebouwde functie voor automatisch opschonen. Voor geautomatiseerde opruiming kun je een Taakplanner-taak gebruiken (zie sectie 8).

Naar boven

5. IP-logging en privacy

5.1 Standaardinstelling: IP-logging uitgeschakeld

Standaard staat Opties → IP-logging = Nee. Wanneer IP-logging is uitgeschakeld, wordt in iedere logregel een tijdelijke aanduiding opgeslagen in plaats van een echt IP-adres en toont de lijstweergave "Uitgeschakeld".

Wanneer je IP-logging inschakelt, leest Joomla het IP-adres van de bezoeker uit en houdt het rekening met de headers X-Forwarded-For en X-Real-IP wanneer het verzoek afkomstig is van een vertrouwde proxy. Vertrouwde proxyservers configureer je via Algemene Configuratie → Server. Als de gevonden waarde geen geldig IP-adres is, wordt in het logboek "Invalid" opgeslagen.

5.2 AVG-overwegingen

Een IP-adres is volgens de AVG (GDPR) persoonsgegeven. Wanneer je IP-logging inschakelt, moet je daarom rekening houden met het volgende:

  1. Zorg voor een geldige grondslag. Gerechtvaardigd belang voor beveiliging is meestal voldoende.
  2. Vermeld IP-logging in je privacyverklaring.
  3. Definieer een bewaartermijn. Het onbeperkt bewaren van IP-adressen is lastig te rechtvaardigen.

Praktische standaardinstellingen voor een publieke Joomla-website:

  • IP-logging ingeschakeld, je zult blij zijn dat je het hebt wanneer er ooit een beveiligingsincident plaatsvindt.
  • Een bewaartermijn van ongeveer 90 dagen, verwijder oudere records automatisch via een Taakplanner-taak.
  • Een vermelding in de privacyverklaring onder het kopje "Beveiligingslogboeken".

5.3 Verzoeken op grond van het recht om vergeten te worden

Wanneer een gebruiker vraagt om verwijdering van zijn gegevens, hoef je niet het volledige auditspoor te vernietigen. Anonimiseren is meestal voldoende:

  1. Verwijder de gebruiker via com_users. Hierdoor wordt nog één laatste logregel aangemaakt waarin naar het verwijderde account-ID wordt verwezen.
  2. Voer vervolgens een SQL-update uit om historische gegevens te anonimiseren:
UPDATE jos_action_logs
SET user_id    = 0,
    ip_address = '0.0.0.0',
    message    = REPLACE(message, 'OldUsername', 'deleted-user')
WHERE user_id = 123;

Het auditspoor blijft intact, alleen de persoonlijk identificeerbare gegevens worden verwijderd. Vervang jos_ door het daadwerkelijke databasevoorvoegsel van je website.

Naar boven

6. Onder de motorkap

6.1 De vier tabellen

Action Logs gebruikt vier databasetabellen:

#__action_logs              één record per gelogde actie
#__action_logs_extensions   de lijst met deelnemende extensies
#__action_log_config        hoe elk contenttype wordt weergegeven
#__action_logs_users        meldingsvoorkeuren per gebruiker

De belangrijkste tabel is #__action_logs. De drie andere zijn relatief kleine referentietabellen.

6.2 De hoofdlogtabel

De belangrijkste velden van #__action_logs zijn:

id                   auto-increment primaire sleutel
message_language_key sjabloonsleutel, bijvoorbeeld PLG_ACTIONLOG_JOOMLA_CONTENT_UPDATED
message              JSON met de plaatsvervangende waarden
log_date             tijdstip waarop de actie plaatsvond
extension            context, bijvoorbeeld com_content.article
user_id              uitvoerende gebruiker (0 = gast of systeem)
item_id              ID van het betrokken item (0 indien niet van toepassing)
ip_address           echt IP-adres, "Disabled" of "Invalid"

De tabel bevat verschillende indexen op user_id, (user_id, log_date), (user_id, extension) en (extension, item_id). Dankzij deze indexen blijft een filter zoals "toon alle acties van gebruiker X" snel werken, zelfs wanneer het logboek miljoenen records bevat.

6.3 De JSON-berichtenstructuur

Hier wordt het interessant. De kolom message bevat niet de uiteindelijke tekst die je in het logboek ziet. In plaats daarvan bevat deze een JSON-object met plaatsvervangende waarden:

{
  "action": "update",
  "type": "PLG_ACTIONLOG_JOOMLA_TYPE_ARTICLE",
  "id": 42,
  "title": "About Us",
  "itemlink": "index.php?option=com_content&task=article.edit&id=42",
  "userid": 100,
  "username": "admin",
  "accountlink": "index.php?option=com_users&task=user.edit&id=100"
}

De message_language_key verwijst naar een sjabloon, bijvoorbeeld:

"User {username} updated {type} {title}."

Tijdens het weergeven vervangt Joomla de JSON-waarden door de daadwerkelijke gegevens en maakt het van de gebruikersnaam en titel klikbare links. Dit is precies waarom het logboek vertaalbaar is: het bericht bestaat uit een sleutel en niet uit een vaste tekst. Installeer je het Nederlandse taalpakket, dan verandert "User admin updated..." automatisch in "Gebruiker admin heeft ... bijgewerkt."

6.4 De contenttype-mapping

De tabel #__action_log_config vertelt de renderer hoe elk contenttype moet worden verwerkt. Voor ieder type wordt vastgelegd welke kolom het ID bevat, welke kolom de titel bevat, welke tabel gebruikt wordt en welke tekstprefix nodig is om de juiste taalstring op te bouwen:

type_alias              id_holder     title_holder   table_name
com_content.article     id            title          #__content
com_categories.category id            title          #__categories
com_redirect.link       id            old_url        #__redirect_links
com_modules.module      id            title          #__modules
...ongeveer 23 regels in Joomla 6

Een maatwerkcomponent kan zijn eigen contenttype registreren door hier een extra record toe te voegen. Ontwikkelaars gebruiken dit mechanisme om hun eigen extensies compatibel te maken met Action Logs (zie sectie 11).

Naar boven

7. Rechten en toegang

7.1 ACL-acties

Onder Opties → Rechten vind je de standaard componentrechten:

ActieWat wordt beheerd
Configureren De componentinstellingen wijzigen.
Toegang tot beheerinterface De lijstweergave van Action Logs openen.
Verwijderen Het logboek opschonen.

Opvallend is wat ontbreekt: er bestaat geen recht voor Aanmaken en geen recht voor Bewerken. Je kunt via de interface geen logregels handmatig toevoegen of wijzigen. Dat is een bewuste ontwerpkeuze.

7.2 Wie zou toegang moeten hebben?

Een logische rechtenstructuur ziet er ongeveer zo uit:

RolBekijkenOpschonen
Super User Ja Ja
Security officer (alleen-lezen groep) Ja Nee
Contentredacteur Nee Nee

De configuratie "wel bekijken maar niet opschonen" is het klassieke auditofficier-model. Geef een aparte groep het recht Toegang tot beheerinterface, maar niet het recht Verwijderen. Zo kunnen zij alles controleren zonder iets te kunnen wijzigen.

Naar boven

8. Prestaties en schaalbaarheid

8.1 Hoe snel groeit het logboek?

Voor een gemiddeld contentteam blijft het logboek relatief klein. Een team van vijf redacteuren genereert bijvoorbeeld ongeveer:

~50 artikelwijzigingen per dag + ~20 menu-/modulewijzigingen per dag + ~10 logins per dag
= ongeveer 80 records per dag = ~2.400 records per maand = ~30.000 records per jaar

Elke logregel neemt ongeveer 500 bytes in beslag. Eén jaar aan gegevens komt daarmee neer op circa 15 MB. Dat vormt geen enkel probleem.

API-logging verandert dit beeld volledig. Een website die via de API gemiddeld 10 verzoeken per seconde verwerkt, genereert al snel 864.000 logregels per dag. Schakel deze functie daarom niet zonder goede reden in.

8.2 Strategieën voor opschonen

Een Taakplanner-taak is de meest nette manier om het logboek beheersbaar te houden. Een eenvoudige opschoontaak verwijdert alles wat ouder is dan 90 dagen:

DELETE FROM jos_action_logs
WHERE log_date < NOW() - INTERVAL 90 DAY;

Een slimmere aanpak bewaart beveiligingsrelevante gebeurtenissen langer en verwijdert alleen routinematige contentwijzigingen:

DELETE FROM jos_action_logs
WHERE log_date < NOW() - INTERVAL 90 DAY
  AND extension NOT IN ('com_users', 'com_installer', 'com_config');

Logins, extensie-installaties en configuratiewijzigingen zijn doorgaans waardevoller voor forensisch onderzoek dan gewone opslagacties. Hun belang neemt vaak juist toe naarmate ze ouder worden.

8.3 Snelle en trage query's

Dankzij de aanwezige indexen blijven query's die filteren op gebruiker, datum, extensie of item-ID snel:

-- Snel: alle acties van één gebruiker in de afgelopen 7 dagen
SELECT * FROM jos_action_logs
WHERE user_id = 100 AND log_date > NOW() - INTERVAL 7 DAY
ORDER BY log_date DESC;

Vrije-tekstzoekopdrachten in het JSON-bericht beschikken echter over geen bruikbare index en moeten de volledige tabel doorzoeken:

-- Traag: vrije-tekstzoekactie in het bericht
SELECT * FROM jos_action_logs
WHERE message LIKE '%phishing%';

De zoekfunctie in de lijstweergave gebruikt precies zo'n LIKE '%...%'-query. Voor incidenteel gebruik door een beheerder is dat prima, maar gebruik dit niet als basis voor geautomatiseerde monitoring of polling.

8.4 Praktische SQL-query's voor onderzoek

Mislukte logins van gisteren, een handige indicator voor brute-force-aanvallen:

SELECT user_id, COUNT(*) AS attempts
FROM jos_action_logs
WHERE message_language_key = 'PLG_ACTIONLOG_JOOMLA_USER_LOGIN_FAILED'
  AND log_date > NOW() - INTERVAL 1 DAY
GROUP BY user_id
HAVING attempts > 5
ORDER BY attempts DESC;

Recente extensie-installaties, een nuttige controle op ongewenste software:

SELECT log_date, user_id, message
FROM jos_action_logs
WHERE extension = 'com_installer'
  AND log_date > NOW() - INTERVAL 7 DAY
ORDER BY log_date DESC;

Vergeet niet jos_ te vervangen door het daadwerkelijke databasevoorvoegsel van je Joomla-installatie.

Naar boven

9. Veelvoorkomende fouten en valkuilen

9.1 "Er wordt niets gelogd"

Doorloop deze controlelijst in volgorde:

  1. Is de plugin Action Log - Joomla ingeschakeld?
  2. Staat de betreffende component in de lijst Gelogde extensies?
  3. Is de actie daadwerkelijk geslaagd? De recorder werkt met "after"-events, dus een opslagactie die faalt door validatiefouten wordt niet geregistreerd.
  4. Controleer je het juiste datumbereik in de filters?

9.2 "Niet alle mislukte logins worden gelogd"

Dat is bewust zo ontworpen. De plugin negeert mislukte inlogpogingen voor niet-bestaande gebruikersnamen om te voorkomen dat geautomatiseerde scanners de tabel vullen met nutteloze gegevens. Alleen mislukte pogingen voor bestaande gebruikers worden geregistreerd.

9.3 "Artikelwijzigingen worden dubbel gelogd"

Dit is geen fout. De recorder luistert naar onContentAfterSave voor zowel het backend-bewerkscherm (com_content.article) als het frontend-inzendformulier (com_content.form). Hetzelfde event wordt dus in verschillende contexten gebruikt. Controleer de kolom extension om te zien welke context de gebeurtenis heeft veroorzaakt.

9.4 "De weergegeven gebruiker heeft de actie niet uitgevoerd"

De recorder registreert de gebruiker die op het moment van de gebeurtenis is geauthenticeerd. CLI-scripts en Taakplanner-taken draaien als gastgebruiker en verschijnen daarom met user_id = 0.

Een waarde van user_id = 0 betekent meestal één van de volgende situaties:

  • Een niet-geauthenticeerde frontendactie, zoals een verzoek voor een wachtwoordreset.
  • Een geplande taak of CLI-commando.
  • Een maatwerkplugin die buiten een HTTP-verzoek wordt uitgevoerd.

De kolom extension en, indien ingeschakeld, het IP-adres helpen meestal om het verschil tussen deze situaties te herkennen.

9.5 "Het bericht toont 'User undefined updated ...'"

Dit wijst op een ontbrekende taalstring. Dat gebeurt wanneer een maatwerkextensie wel een event genereert maar geen bijbehorende PLG_ACTIONLOG_...-taalstrings bevat, of wanneer de actieve taalvertaling de betreffende sleutel mist.

De oplossing is het toevoegen van de ontbrekende taalstring aan het taalbestand of het registreren van de juiste prefix in #__action_log_config.

9.6 "Opschonen heeft mijn bewijsmateriaal verwijderd"

Er bestaat geen mogelijkheid om een opschoning ongedaan te maken. Voordat je ooit het logboek opschoont:

  1. Maak eerst een CSV-export via de knop Alles exporteren.
  2. Bewaar het CSV-bestand buiten de Joomla-installatie.
  3. Voer pas daarna de opschoning uit.

Voor websites die moeten voldoen aan compliance- of auditvereisten geldt een eenvoudige regel: verwijder nooit loggegevens zonder eerst een export te maken en vast te leggen wie de opschoning heeft uitgevoerd.

9.7 "Ik kan Action Logs niet vinden in het menu"

De component bevindt zich onder Gebruikers en niet onder Systeem. Daarnaast verbergt Joomla automatisch de menulink voor gebruikers die niet beschikken over het recht Toegang tot beheerinterface. Een gewone redacteur zal de optie daarom simpelweg niet zien.

Naar boven

10. Beveiliging en compliance

10.1 Het auditspoor is zelf ook een doelwit

Een aanvaller die beheerderstoegang verkrijgt, wil vaak niet alleen iets kwaadaardigs uitvoeren, maar ook de sporen wissen. Het actielogboek maakt dat moeilijker, maar biedt geen volledige garantie. Een Super User kan het logboek opschonen, de recorder uitschakelen of zelfs afzonderlijke records verwijderen via directe SQL-opdrachten.

Verstandige maatregelen zijn onder meer:

  • Beperk het recht Verwijderen tot één speciaal beveiligingsaccount.
  • Sla loggegevens ook extern op, zodat de lokale kopie niet de enige bron van waarheid is.
  • Controleer actief op meta-gebeurtenissen, zoals het opschonen van het logboek of het uitschakelen van de recorder-plugin.

Ook je eigen beheerders verdienen controle. Het logboek is een afschrikmiddel en een forensisch hulpmiddel, geen absolute garantie.

10.2 Loggegevens omzetten in actie

Een logboek dat je pas achteraf bekijkt benut slechts de helft van zijn waarde. Action Logs kunnen ook gebruikt worden als basis voor automatische detectie en waarschuwingen:

  • Waarschuwingen bij brute-force-aanvallen: een Taakplanner-taak voert periodiek de query voor mislukte logins uit en verstuurt een melding via Slack of e-mail zodra een drempelwaarde wordt overschreden.
  • Meldingen bij verdachte installaties: een webhook die reageert op extensie-installaties en direct het beveiligingsteam informeert. Een plugin-installatie om 03:00 uur door een beheerder die normaal alleen overdag werkt, is bijvoorbeeld verdacht.
  • Bewaking van privilege-escalatie: een melding wanneer iemand wordt toegevoegd aan de groep Super Users. Dit hoort slechts zelden voor te komen.

Het actielogboek vormt je detectielaag. Combineer het met een reactielaag, bijvoorbeeld via Joomla-plug-ins, Taakplanner-taken of een extern monitoringsysteem.

10.3 Een minimale maar effectieve beveiligingsconfiguratie

Voor een productiewebsite die echt belangrijk is, levert ongeveer twintig minuten configuratiewerk veel extra veiligheid op:

  1. Action Logs inschakelen voor com_users, com_installer, com_config, com_plugins, com_modules en com_templates.
  2. IP-logging inschakelen en een bewaartermijn van 90 dagen instellen via een geplande taak.
  3. Meldingen inschakelen voor Super User-accounts, met toezicht op com_users en com_installer.
  4. Het recht Verwijderen beperken tot één speciaal beveiligingsaccount.
  5. Dagelijks de query voor mislukte logins controleren, of een dashboard gebruiken dat dezelfde informatie toont.

De investering betaalt zich terug zodra iemand probeert slimmer te zijn dan het systeem.

Naar boven

11. Aanpassingen voor ontwikkelaars

11.1 Een eigen component registreren voor logging

U kunt een eigen component compatibel maken met Action Logs in twee stappen, zonder een aparte plugin te schrijven. Voeg de component eerst toe aan de lijst met logbare extensies:

INSERT INTO jos_action_logs_extensions (extension)
VALUES ('com_mycomponent');

Voeg vervolgens één of meer contenttype-definities toe zodat Joomla weet hoe berichten moeten worden opgebouwd:

INSERT INTO jos_action_log_config
  (type_title, type_alias, id_holder, title_holder, table_name, text_prefix)
VALUES
  ('myitem', 'com_mycomponent.item', 'id', 'name',
   '#__mycomponent_items', 'PLG_ACTIONLOG_MYCOMPONENT');

Lever daarna taalstrings mee die beginnen met PLG_ACTIONLOG_MYCOMPONENT_... voor iedere actie die je wil registreren. Zolang je component standaardevents zoals onContentAfterSave en vergelijkbare gebeurtenissen uitzendt met de juiste context, verwerkt de bestaande recorder-plugin de rest automatisch.

11.2 Logregels vanuit eigen code toevoegen

Voor een eenmalige logregel vanuit een controller, model of importscript kun je rechtstreeks het Action Logs-model gebruiken:

$model = $this->app->bootComponent('com_actionlogs')
    ->getMVCFactory()
    ->createModel('Actionlog', 'Administrator');

$model->addLog(
    [['action' => 'custom', 'detail' => 'Handmatige registratie vanuit importscript']],
    'COM_MYCOMPONENT_LOG_IMPORT_RAN',
    'com_mycomponent.import',
    $userId   // 0 = huidige gebruiker
);

Dit is bijzonder handig voor batchprocessen of importscripts die een spoor in het auditlog moeten achterlaten zonder gebruik te maken van het eventsysteem.

11.3 Geautomatiseerd opschonen

Joomla bevat geen ingebouwd bewaarbeleid voor Action Logs, maar met de Taakplanner kun je dat in enkele minuten zelf regelen. Ga naar Systeem → Beheren → Taken → Nieuw en maak een database-opruimtaak aan:

VeldWaarde
Titel Action Logs opschonen
Taak Database-opruiming, SQL-bewerkingen
Query DELETE FROM #__action_logs WHERE log_date < NOW() - INTERVAL 90 DAY
Schema Cron-notatie: 0 3 * * * (elke nacht om 03:00 uur)

De Taakplanner voert deze opschoning vervolgens automatisch uit. Voor de meest betrouwbare werking is het verstandig de Taakplanner te activeren via een echte cronjob op de server, in plaats van afhankelijk te zijn van websiteverkeer.

Naar boven

12. Action Logs versus andere logbestanden

12.1 Action Logs versus het systeemlogboek

Joomla beschikt ook over een technisch systeemlogboek dat wordt gevuld via Log::add(). Beide logsystemen hebben een ander doel:

AspectAction LogsSysteemlogboek
Gebruiksvriendelijke interface Ja Nee, tekstbestanden
Opslaglocatie Database Bestanden
Vertaalbare berichten Ja Nee
Meldingen per gebruiker Ja Nee
Beste toepassing Audittrail voor contentbeheer (wie deed wat) Technische gebeurtenissen (fouten, prestaties)

Gebruik Action Logs om te achterhalen wie wat heeft gedaan binnen Joomla. Gebruik het systeemlogboek voor technische gebeurtenissen. Beide vullen elkaar aan.

12.2 Action Logs versus serverlogs

Action Logs werken op het niveau van de applicatie. Alles wat het Joomla-eventsysteem niet bereikt, blijft onzichtbaar voor het actielogboek. Voor een compleet beeld heb je daarom ook de infrastructuurlaag nodig:

LaagWat wordt gezienWat ontbreekt
Action Logs CRUD-acties, logins, installaties, configuratiewijzigingen, wie deed wat Verzoeken die niet zijn verwerkt, PHP-fatals, serverblokkades
Apache/nginx access log Elk HTTP-verzoek: URL, statuscode, IP-adres en user-agent De Joomla-gebruiker, het betrokken item en de intentie
PHP-foutenlogboek Fatals, waarschuwingen en stacktraces Succesvolle acties en gebruikersidentiteit

Een voorbeeld maakt het verschil duidelijk. Een artikel dat een HTTP 500-fout veroorzaakt verschijnt in het PHP-foutenlogboek en in het access log, maar niet in Action Logs, omdat het opslag-event nooit werd uitgevoerd. Het omgekeerde geldt ook: een redacteur die stilletjes een pagina naar de prullenbak verplaatst, verschijnt duidelijk in Action Logs, terwijl het access log slechts een gewone POST-aanvraag met statuscode 200 laat zien.

Voor serieus forensisch onderzoek combineer je tijdstempels uit al deze bronnen. Action Logs beantwoorden de vraag wie, serverlogs beantwoorden de vraag hoe het verzoek binnenkwam. Samen vertellen ze wat er werkelijk is gebeurd.

Naar boven

13. Best practices

Als je slechts een paar dingen uit dit artikel onthoudt, laat het dan deze zijn:

  • Laat beide Action Logs-plug-ins ingeschakeld op productiewebsites.
  • Beperk de lijst met gelogde extensies om ruis op drukke websites te verminderen.
  • Schakel IP-logging in, maar combineer dit met een bewaartermijn en een vermelding in de privacyverklaring.
  • Voer nooit een opschoning uit zonder eerst een CSV-export veilig buiten Joomla op te slaan.
  • Beperk het recht Verwijderen tot één speciaal beveiligingsaccount.
  • Laat API-logging uitgeschakeld tenzij je actief onderzoek doet naar een probleem of incident.
Naar boven

14. In het kort

COMPONENT       Gebruikers → Action Logs
MELDINGEN       Gebruikers → Meldingen Action Logs
OPTIES          Gebruikers → Action Logs → Opties
RECORDER        Systeem → Plugins → Action Log - Joomla
NOTIFIER        Systeem → Plugins → System - Action Logs
HOOFDTABEL      #__action_logs
GELOGDE EXTS    Opties → Gelogde extensies (standaard 21)
IP-LOGGING      Opties → IP-logging (standaard UIT)
API-LOGGING     Opties → API-endpoints loggen (standaard UIT)
EXPORT          Werkbalk → Alles exporteren / Geselecteerde exporteren
OPSCHONEN       Werkbalk → Opschonen (geen undo, wordt zelf gelogd)
RETENTIE        com_scheduler → SQL Operations-taak
SINDS           Joomla 3.9 (mei 2018)
Naar boven

15. Samenvatting

Het User Actions Log is een van die Joomla-functies die weinig vraagt en veel oplevert. Het draait stil op de achtergrond, registreert iedere betekenisvolle wijziging en bewijst zijn waarde zodra een klant vraagt: "wie heeft de homepage gedepubliceerd?"

Met slechts enkele minuten configuratiewerk krijgt u:

  • Direct inzetbare auditing voor 21 core-componenten, zonder extra extensies.
  • Vertaalde en leesbare berichten die worden opgebouwd uit JSON-placeholders.
  • Meldingen per gebruiker met gedetailleerde opt-inmogelijkheden.
  • CSV-export met bescherming tegen formule-injecties voor veilig gebruik in spreadsheets.
  • Optionele IP-logging die standaard privacyvriendelijk is ingesteld.
  • Een geïndexeerde databasestructuur die moeiteloos miljoenen records aankan.

Het systeem is niet perfect. Het biedt op zichzelf geen bescherming tegen manipulatie en een vastberaden Super User kan nog steeds rechtstreeks wijzigingen in de database aanbrengen. Maar als detectielaag, gecombineerd met doordachte rechtenstructuren en een goed responsplan, verandert het de situatie van "we hebben geen idee wat er is gebeurd" naar "dit is precies wie wat heeft gedaan, en wanneer".

Beheer je een Joomla-website die belangrijk voor je is, schakel Action Logs dan in, stem de instellingen af op je situatie en leer het logboek lezen voordat je het echt nodig hebt.

Naar boven
Actionlogs in Joomla
Peter Martin
Peter Martin

Joomla specialist en Linux admin voor snelle, veilige en schaalbare websites.