Skip to main content
Actionlogs in Joomla
On this page
# Topics

Actionlogs in Joomla

20 June 2026

Sooner or later, every website owner asks a question that starts with "who". Who unpublished the homepage last night? Who installed that extension nobody recognises? Did the new editor really delete twelve articles, or is the client mistaken?

Without a record, these questions have no answer, and you are left guessing.

Joomla answers them with a small but powerful core component called User Actions Log (com_actionlogs). It quietly records every important change on your site: saves, deletes, publishing, logins, installs, and configuration changes. Each record stores the user, the action, the time, and (optionally) the IP address. You do not need to install anything. It is already in your Joomla.

Who did what, when, and from where - recorded by Joomla without a single third-party extension.

This article explains how the Action Logs component works, what it records, how to read and filter the log, how notifications and CSV export work, and how to keep the log healthy on a busy site. The goal is to help website owners, administrators, and developers understand this quiet witness well enough to trust it the day they need it.

1. The Basics

1.1 What is the User Actions Log?

The User Actions Log (com_actionlogs) is Joomla's built-in audit-trail component. Joomla introduced it in version 3.9 (May 2018), and it has shipped in core ever since.

A few things make it special:

  • It writes one row per recorded action into a single table: #__action_logs.
  • It is driven by events, not polling. Every action emits a Joomla event, a plugin catches it, and a row is written.
  • Each row stores the user, the timestamp, the extension context, the item id, the IP address, and a language-keyed message.
  • It is read-only from the interface. Admins can view, filter, export, or purge the log, but they cannot edit individual rows.

That last point matters. An audit log you can edit is not really an audit log. Joomla deliberately offers no edit screen for log rows.

1.2 A Note on Naming: "Action Logs" vs "User Actions Log"

Before we go further, clear up one common source of confusion. Joomla uses two names for the same thing, and the inconsistency throws a lot of people off:

Where you see itName used
Admin menu item (J4 / 5 / 6) Users → Action Logs
Help screen title User Actions Log: Options
Toolbar heading on the list view User Actions Log
Official docs site User Actions Log
Component folder / internal name com_actionlogs
Recorder plugin label Action Log - Joomla (singular "Log")
Notifier plugin label System - Action Logs (plural "Logs")

"User Actions Log" is the formal, original name Joomla gave the feature in 3.9. It still appears in the help docs and the toolbar heading. "Action Logs" is the shorter label that ended up on the admin menu and in everyday speech. They refer to the same component, the same database tables, and the same plugins. There is no separate "User Action Logs" feature.

A historical wrinkle adds to the confusion. In Joomla 3.9 and 3.10 the menu item lived under System → User Actions Log. From Joomla 4 onward it moved to Users → Action Logs. Older tutorials and screenshots still show the old name and path. In this article "Action Logs" and "User Actions Log" mean the same thing; when in doubt, the canonical identifier is com_actionlogs.

1.3 Where Do I Find It?

In the Joomla 6 backend, these places are relevant:

Users  → Action Logs                      (the log viewer)
Users  → Action Logs → Options            (settings + ACL)
Users  → Action Logs Notifications        (per-user email alerts)
System → Manage → Plugins → Action Log - Joomla   (the recorder)
System → Manage → Plugins → System - Action Logs  (the notifier)

The component lives at administrator/components/com_actionlogs/. The two plugins live at plugins/actionlog/joomla/ (the recorder) and plugins/system/actionlogs/ (the notifier).

One note that trips people up: the component sits under Users, not under System. Some older screenshots suggest otherwise.

1.4 The Three Pieces

Action Logs is built from three parts that work together:

PartRole
com_actionlogs Backend list view, filters, CSV export, purge.
plg_actionlog_joomla Listens to events and writes the log rows.
plg_system_actionlogs Sends notification emails and renders messages.

All three ship enabled by default in Joomla 6. Disable the recorder and the log goes silent. Disable the notifier and the log still grows, but no emails go out.

1.5 Your First Look at the Log

Open Users → Action Logs. The list is sorted newest first. A typical entry looks like this:

ColumnExample
Action User article-editor logged in to administrator.
Date 2026-05-28 09:14:02 (relative: "a few seconds ago")
Extension com_users
User admin
IP Address 10.10.10.1 (or "Disabled" if IP logging is off)

Click the action text and Joomla expands the row, showing the underlying message template and the JSON-encoded context. We come back to that JSON in section 6.

1.6 Filtering the List

The filter bar on the list view gives you four tools:

  • Search: free text against the rendered message.
  • User: narrow down to one user's activity.
  • Extension: only com_content, only com_users, and so on.
  • Date Range: a start and end date picker.

The most useful combination is User + Date Range. It answers the everyday question "show me everything Alice did last Wednesday" in two clicks.

Back to top

2. What Gets Logged

2.1 The Default Loggable Extensions

You decide which components are watched under Options → Logged Extensions. This is a multi-select that ships with every core component already enabled:

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

Remove an extension from this list and its events are silently dropped. No rows are written for it. Trimming this list is the single most effective way to reduce log noise on a busy site.

2.2 Content Lifecycle Events

For every loggable component, the recorder plugin subscribes to three content events:

EventWhat it logs
onContentAfterSave Create or update, with id, title, and a new/updated flag.
onContentAfterDelete Delete, with id and title (captured before deletion).
onContentChangeState Publish, unpublish, archive, or trash, with the new state.

So every article you save, every category you trash, and every menu item you publish writes one row.

2.3 User Lifecycle Events

User events are the most important for spotting account abuse:

EventWhat it logs
onUserAfterLogin Successful login (frontend or backend, but never API logins).
onUserLoginFailure Failed login, but only if the username exists.
onUserLogout Explicit logout.
onUserAfterSave Create or edit a user (also captures group changes).
onUserAfterDelete Delete a user.
onUserAfterRemind "Forgot username" requested.
onUserAfterResetRequest "Forgot password" link requested.
onUserAfterResetComplete Password reset finished.

One detail surprises people: failed logins with an unknown username are not logged. The plugin checks for an existing user first, which keeps automated scanner traffic out of the audit trail.

2.4 Extension Lifecycle Events

Anything that touches the extensions table is recorded:

EventWhat it logs
onExtensionAfterInstall Install: type, name, version.
onExtensionAfterUpdate Update: old version to new version.
onExtensionAfterUninstall Uninstall.
onExtensionAfterSave Edit, for example enable or disable a plugin.
onJoomlaAfterUpdate Core Joomla version bump.

This is pure gold for forensics after an incident. The question "when did we install that vulnerable plugin?" becomes one query away.

2.5 Configuration Changes

Joomla also records configuration saves:

  • onApplicationAfterSave: Global Configuration was saved.
  • onExtensionAfterSave with context com_config.component: a per-component Options screen was saved.

Both record which fieldset changed, but not the before and after values. If you need the exact diff, that takes a small custom plugin (see section 11).

2.6 Operational Events

A few housekeeping actions are logged too:

EventWhat it logs
onAfterCheckin An admin force-checked-in a locked record.
onAfterPurge The cache was cleared.
onAfterLogPurge The action log itself was purged.
onAfterLogExport A CSV export was downloaded.

Yes, purging the log is itself logged. After a purge, you are left with exactly one row: "User admin purged the action logs." The audit trail is self-documenting.

2.7 API Requests (optional)

If you set Options → Log API Endpoints = Yes, Joomla records every Web Services API call as it dispatches. A second option, Logged HTTP Verbs, lets you choose which methods to capture. It defaults to GET only, but most production sites that enable this want POST, PUT, PATCH, and DELETE at minimum.

A warning: API logging fills the table fast. Turn it on for an investigation, then turn it off for steady-state operation. See section 8 for the numbers.

Back to top

3. Notifications

3.1 The Opt-in Model

Each user can subscribe to email alerts for one or more extensions under Users → Action Logs Notifications. The preferences live in #__action_logs_users:

user_id    notify (0/1)    extensions  (comma-separated context list)
  • A user who is not in this table receives no notifications.
  • A user with notify = 1 and extensions = com_users,com_installer gets an email every time someone touches users or extensions.

Notifications are a per-user choice, not a site-wide setting. Power users and security officers opt in; everyone else stays quiet.

3.2 What the Email Looks Like

The notifier renders the same human-readable message you see in the list view, plus:

  • A direct link to the affected item, where one applies.
  • The acting user's name.
  • A link to the action log entry itself.

The mail uses the system mailer, so check it is configured under System → Global Configuration → Server → Mail before relying on notifications. On a local Docker stack, a tool like MailHog catches every outgoing message so you can test safely.

3.3 The System Plugin's Role

It helps to keep the two plugins separate in your head:

  • The Action Log - Joomla plugin only writes rows.
  • The System - Action Logs plugin sends notifications and renders messages.

If you disable the system plugin, the log still grows and rendered messages still work, but no notification emails go out. Keep both enabled in production. Disable the system plugin only if you want to silence email blasts during a bulk migration.

Back to top

4. Export and Purge

4.1 CSV Export

The list view has two export buttons in the toolbar:

ButtonWhat it exports
Export Selected Only the rows you checked.
Export All The entire log, respecting the active filters.

The delimiter is configurable under Options → CSV Delimiter. Choose a semicolon (;) if your spreadsheet locale (for example Dutch Excel) treats commas as decimal separators.

The export is streamed one row at a time, so even a log with a million rows will not run the PHP worker out of memory.

4.2 CSV Injection Protection

Joomla escapes any cell that starts with =, +, -, @, a tab, or a carriage return by prepending a single quote. This blocks the classic "Excel formula injection" attack, where a logged username like =cmd|'/c calc'!A1 would otherwise run as a formula when an admin opens the CSV.

If you ever write a custom exporter, keep that escaping. It is there for a good reason.

4.3 Purging the Log

The Purge button in the toolbar wipes every row from #__action_logs. The purge then writes one row of its own, so afterwards you have a single entry recording who purged the log and when.

Common reasons to purge:

  • After a long migration period, when you want a clean slate.
  • Before exporting only fresh activity.

There is no undo and there is no built-in scheduled purge. For automatic clean-up, use a Scheduler task (section 8).

Back to top

5. IP Logging and Privacy

5.1 The Default: IP Logging Off

Out of the box, Options → IP Logging = No. When IP logging is off, every row stores a placeholder instead of a real IP, and the list view shows "Disabled".

When you turn it on, Joomla reads the visitor's IP and honours X-Forwarded-For and X-Real-IP headers when the request comes from a trusted proxy. You configure trusted proxies under Global Configuration → Server. If the resolved value is not a valid IP, the row records "Invalid" instead.

5.2 GDPR Considerations

An IP address is personal data under GDPR. Turning IP logging on means you should:

  1. Have a lawful basis. Legitimate interest for security is usually fine.
  2. Mention IP logging in your privacy policy.
  3. Define a retention policy. IPs kept forever are hard to justify.

Reasonable defaults for a public Joomla site:

  • IP logging on: you will want it the day you get hacked.
  • Retention of about 90 days: purge older rows with a Scheduler task.
  • A line in the privacy policy under "Security logs".

5.3 Right-to-be-forgotten Requests

When a user asks to be deleted, you do not have to destroy the whole audit trail. Anonymise instead:

  1. Delete the user through com_users. This writes one final log row that references the deleted account by id.
  2. Run an SQL update to scrub the historical rows:
UPDATE jos_action_logs
SET user_id    = 0,
    ip_address = '0.0.0.0',
    message    = REPLACE(message, 'OldUsername', 'deleted-user')
WHERE user_id = 123;

The audit trail stays intact; only the personally identifying parts are removed. Replace jos_ with your actual database prefix.

Back to top

6. Under the Hood

6.1 The Four Tables

Action Logs uses four database tables:

#__action_logs              one row per logged action
#__action_logs_extensions   the list of extensions that participate
#__action_log_config        how each content type renders
#__action_logs_users        per-user notification preferences

The main one is #__action_logs. The other three are small reference tables.

6.2 The Main Log Table

The core fields of #__action_logs are:

id                   auto-increment primary key
message_language_key the template key, e.g. PLG_ACTIONLOG_JOOMLA_CONTENT_UPDATED
message              JSON with the placeholder values
log_date             when the action happened
extension            context, e.g. com_content.article
user_id              acting user (0 = guest or system)
item_id              affected item id (0 if not applicable)
ip_address           real IP, "Disabled", or "Invalid"

The table carries several indexes on user_id, (user_id, log_date), (user_id, extension), and (extension, item_id). These are what keep the "show all actions for user X" filter fast, even on a log with millions of rows.

6.3 The Message JSON

This is the clever part. The message column does not hold the rendered text. It holds a JSON object of placeholders:

{
  "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"
}

The message_language_key is the template, for example:

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

At display time, Joomla substitutes the JSON values into the template and wraps the user name and the title in links. This is exactly why the log is translatable: the message is a key, not a fixed string. Install the Dutch language pack and "User admin updated..." becomes "Gebruiker admin werkte ... bij."

6.4 The Content-type Map

The table #__action_log_config tells the renderer how to read each content type. For each type it stores which column holds the id, which holds the title, the table name, and a text prefix used to build the language key:

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
...about 23 rows in Joomla 6

A custom component can register its own type by inserting a row here. That is the hook developers use to make their own extensions log-aware (section 11).

Back to top

7. Permissions and Access

7.1 ACL Actions

Under Options → Permissions you find the standard component actions:

ActionWhat it controls
Configure Edit the component options.
Access Administration Interface Open the Action Logs list at all.
Delete Purge the log.

Notice what is missing: there is no Create and no Edit. You cannot add a row by hand through the interface, and you cannot edit one. That is by design.

7.2 Who Should Have Access?

A sensible access pattern looks like this:

RoleViewPurge
Super User Yes Yes
Security officer (view-only group) Yes No
Content editor No No

The "view but cannot purge" setup is the audit-officer pattern. Give a dedicated group Access Administration Interface but withhold Delete. They can see everything and change nothing.

Back to top

8. Performance and Scale

8.1 How Much Does It Grow?

For a normal content team, the log is tiny. A team of five editors might generate:

~50 article saves/day + ~20 menu/module saves/day + ~10 logins/day
= roughly 80 rows/day = ~2,400 rows/month = ~30,000 rows/year

Each row is around 500 bytes, so one year is about 15 MB. No problem at all.

API logging changes everything. A site serving 10 requests per second to its API would hit 864,000 rows per day. Do not enable it casually.

8.2 Pruning Strategies

A Scheduler task is the cleanest way to keep the log trimmed. A simple prune deletes everything older than 90 days:

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

For a smarter policy, keep the security-relevant events longer and prune only the routine content events:

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

Logins, installs, and config changes are worth keeping longer than ordinary saves. Their forensic value grows over time.

8.3 Fast Queries vs Slow Queries

Because of the indexes, queries that filter on user and date, or on extension and item, are fast:

-- Fast: all actions by one user in the last 7 days
SELECT * FROM jos_action_logs
WHERE user_id = 100 AND log_date > NOW() - INTERVAL 7 DAY
ORDER BY log_date DESC;

Free-text search through the JSON message has no usable index and scans the whole table:

-- Slow: free-text search through the message
SELECT * FROM jos_action_logs
WHERE message LIKE '%phishing%';

The list view's search box is exactly this kind of LIKE '%...%' scan. It is fine for the occasional admin lookup, but do not build scripted polling on top of it.

8.4 Triage SQL You Will Use Often

Yesterday's failed logins, the brute-force canary:

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;

Recent extension installs, a supply-chain alarm:

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;

Remember to replace jos_ with your real database prefix.

Back to top

9. Common Mistakes and Pitfalls

9.1 "Nothing is being logged"

Work through this checklist, in order:

  1. Is the Action Log - Joomla plugin enabled?
  2. Is the affected component in the Logged Extensions list?
  3. Did the action actually succeed? The recorder hooks the "after" events, so a save that fails validation never reaches it.
  4. Are you looking at the right time range in the filter?

9.2 "Failed logins are not all logged"

This is intentional. The plugin ignores failed logins for unknown usernames so that automated scanners do not flood the table. Only failures for an existing username get a row.

9.3 "Article saves are logged twice"

Not a bug. The recorder subscribes to onContentAfterSave for both the backend edit screen (com_content.article) and the frontend submit form (com_content.form). Same event, different context. Check the extension column to see which one fired.

9.4 "The user shown is not who did it"

The recorder logs the currently authenticated user at the moment the event fires. CLI scripts and Scheduler tasks run as the guest user, so they appear with user_id = 0. A user_id = 0 usually means one of three things:

  • A genuinely unauthenticated frontend event, such as a forgot-password request.
  • A scheduled task or CLI command.
  • A custom plugin running outside an HTTP request.

The extension column, and the IP address if logging is on, usually tell the cases apart.

9.5 "The message says 'User undefined updated ...'"

That is a missing language key. It happens when a custom extension fires an event but does not ship the matching PLG_ACTIONLOG_... strings, or when the active language pack lacks the key. The fix is to add the key to the language file or register the prefix in #__action_log_config.

9.6 "Purge wiped my evidence"

There is no undo. Before you ever purge:

  1. Export to CSV first (toolbar, Export All).
  2. Archive the CSV outside the Joomla install.
  3. Then purge.

For any site under a compliance regime, the rule is simple: never purge without an exported copy and a record of who did it.

9.7 "I cannot find Action Logs in the menu"

It is under Users, not System. And ACL hides the link from any user who lacks the Access Administration Interface permission, so an editor account simply will not see it.

Back to top

10. Security and Compliance

10.1 The Audit Trail Is Itself a Target

An attacker who gains admin access often wants to do something malicious and then hide the evidence. The action log makes hiding harder, but it is not bulletproof. A super-user can purge the log, disable the recorder, or delete specific rows with raw SQL.

Sensible mitigations:

  • Restrict the Delete permission to a single dedicated account.
  • Stream the log offsite so a local copy alone cannot be the only record.
  • Watch for the meta-events: a purge, or the recorder plugin being disabled.

Trust but verify applies to your own admins. The log is a deterrent and a forensic tool, not a guarantee.

10.2 Turning Logs Into Action

A log you only read after the fact gives you half its value. Action logs can also feed automated responses:

  • Brute-force alerting: a Scheduler task runs the failed-login query and pushes an alert to Slack or email when attempts cross a threshold.
  • Suspicious-install pager: a webhook on extension installs that pings the security team. An extension installed at 03:00 by a normally 9-to-5 admin is a red flag.
  • Privilege-escalation watch: alert when anyone is added to the Super Users group. This should almost never happen.

The action log is your detection layer. Pair it with a response layer, either inside Joomla via Scheduler tasks and plugins, or wired to an external monitoring system.

10.3 The Minimum-viable Security Setup

For a production site you actually care about, about twenty minutes of setup buys you a lot:

  1. Action Logs enabled for com_users, com_installer, com_config, com_plugins, com_modules, and com_templates.
  2. IP logging on, with a 90-day retention task.
  3. Notifications on for super-user accounts, watching com_users and com_installer.
  4. The Delete permission restricted to a single dedicated security account.
  5. A daily look at the failed-login query, or its dashboard equivalent.

It pays off the first time someone tries to be clever.

Back to top

11. Customisation for Developers

11.1 Registering a Custom Component for Logging

You can make your own component log-aware in two steps, without writing a plugin. First, add it to the loggable list:

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

Second, add content-type rows so the renderer knows how to format the messages:

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');

Then ship language strings that start with PLG_ACTIONLOG_MYCOMPONENT_... for each action. As long as your component emits the standard onContentAfterSave and similar events with the right context, the existing recorder handles the rest.

11.2 Logging From Your Own Code

For a one-off log entry from a controller, model, or import script:

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

$model->addLog(
    [['action' => 'custom', 'detail' => 'Manual entry from import script']],
    'COM_MYCOMPONENT_LOG_IMPORT_RAN',
    'com_mycomponent.import',
    $userId   // 0 = current user
);

This is handy for batch scripts that need to leave a footprint in the audit trail without going through the event system.

11.3 Scheduled Pruning

Joomla has no built-in retention policy, but the Scheduler component gives you one in a minute. Go to System → Manage → Tasks → New and create a Database cleanup task:

FieldValue
Title Prune action logs
Task Database cleanup, SQL Operations
Query DELETE FROM #__action_logs WHERE log_date < NOW() - INTERVAL 90 DAY
Rule Cron-style: 0 3 * * * (every night at 03:00)

The Scheduler runs the cleanup automatically. For the most reliable timing, trigger the Scheduler from a real system cron job rather than relying on website traffic.

Back to top

12. Action Logs vs Other Logs

12.1 Action Logs vs the System Log

Joomla also has a low-level system log written by Log::add(). The two serve different goals:

AspectAction LogsSystem log
Editor-friendly UI Yes No, text files
Stored in Database Files
Translatable messages Yes No
Per-user notifications Yes No
Best for Editorial audit (who did what) Technical events (errors, performance)

Use Action Logs for "who did what in the CMS" and the system log for technical events. They complement each other.

12.2 Action Logs vs Server Logs

Action logs live at the application layer. They are blind to anything that never reaches the Joomla event system. For a full picture you also need the infrastructure layer:

LayerWhat it seesWhat it misses
Action log CRUD actions, logins, installs, config changes: who and what Requests that did not dispatch, PHP fatals, server-level blocks
Apache / nginx access log Every HTTP request: URL, status, IP, user-agent The Joomla user, the affected item, the intent
PHP error log Fatals, warnings, stack traces Successful actions, user identity

An example shows the difference. A 500-error on an article shows up in the PHP error log and the access log, but not in the action log, because the save event never fired. The opposite is also true: an editor quietly trashing a page shows up in the action log, but in the access log it is just one more POST with status 200.

For real forensic work you correlate timestamps across all of them. Action logs answer who; server logs answer how the request landed; together they tell you what actually happened.

Back to top

13. Best Practices

If you remember only a few things from this article, remember these:

  • Keep both Action Logs plugins enabled in production.
  • Trim the Logged Extensions list to cut noise on busy sites.
  • Turn on IP logging, but pair it with a retention task and a privacy-policy line.
  • Never purge without an exported CSV stored safely outside Joomla.
  • Restrict the Delete permission to one dedicated account.
  • Leave API logging off unless you are actively investigating something.
Back to top

14. Quick Reference

COMPONENT       Users → Action Logs
NOTIFICATIONS   Users → Action Logs Notifications
OPTIONS         Users → Action Logs → Options
RECORDER        System → Plugins → Action Log - Joomla
NOTIFIER        System → Plugins → System - Action Logs
MAIN TABLE      #__action_logs
LOGGED EXTS     Options → Logged Extensions (21 by default)
IP LOGGING      Options → IP Logging (OFF by default)
API LOGGING     Options → Log API Endpoints (OFF by default)
EXPORT          Toolbar → Export All / Export Selected
PURGE           Toolbar → Purge (no undo, self-logging)
PRUNE           com_scheduler → SQL Operations task
SINCE           Joomla 3.9 (May 2018)
Back to top

15. Summary

The User Actions Log is one of those Joomla features that asks for nothing and gives a lot. It sits quietly in the background, recording every meaningful change, and the first time a client asks "who unpublished the homepage?" it earns its keep many times over.

For a few minutes of setup you get:

  • Out-of-the-box auditing for 21 core components, with no extra extensions.
  • Translated, human-readable messages built from JSON placeholders.
  • Per-user notifications with opt-in granularity.
  • CSV export with injection protection for safe review in spreadsheets.
  • Optional IP logging that respects privacy by default.
  • An indexed schema that scales comfortably to millions of rows.

It is not perfect. It is not tamper-evident on its own, and a determined super-user can still edit the database directly. But as a detection layer, paired with sensible permissions and a response plan, it turns "we have no idea what happened" into "here is exactly who did what, and when". If you run a Joomla site you care about, switch it on, tune it, and learn to read it before you need it.

Back to top
Actionlogs in Joomla
Peter Martin
Peter Martin

Joomla specialist and Linux admin for fast, secure and scalable websites.