DevDome Activity Log is a free WordPress activity tracker and user activity log. It keeps an audit trail of recorded site activity in a dedicated table in your own database, with filters, search and CSV export. The coverage list below states what it records and what it does not record; anything outside that list is not recorded.
What it records
- Authentication: review login history covering logins, logouts, failed login attempts, password reset requests and completed resets. Repeated failed logins and reset requests are counted into one row per source, per attempted account, per hour by a single atomic database statement, so concurrent attempts cannot create duplicate rows or lose increments.
- Users: accounts created and deleted, roles set, added and removed, email changes (both addresses masked) and other profile changes. Passwords are never recorded, only the fact that one changed.
- Content: posts, pages and custom post types created, updated, trashed, restored or deleted, with a summary of what changed. Bodies are compared by hash and never stored.
- Plugins, themes and core: installs, updates (with the previous and new version when it can be observed), activations, deactivations, deletions, theme switches and core updates. A plugin or theme update after which the installed version did not change is recorded as a failed update; when the previous version could not be observed, an update the upgrader reported as failed is recorded as failed too.
- Media and comments: uploads, deletions and comment status changes (approved, spam, trash, restored).
- Settings: changes to a fixed allowlist of nine important options: site title, site URL, home URL, admin email, open registration, default role, permalink structure, the site time zone and the UTC offset (the clock decides what every stored timestamp means).
- The log itself: every change to its own policy with the previous and new value, every CSV export, every retention purge, every personal-data erasure and every storage migration. These records cannot be switched off by the settings they describe.
Not recorded (yet)
So there is no ambiguity, this plugin does
not currently record: comment creation, editing or permanent deletion; media edits and file replacements; term, taxonomy, menu, widget, Customizer, block-template or post-meta changes; rolled-back core updates and the reason an update failed (only the fact that it did not complete); application passwords; session destruction; the plugin/theme file editor; capability changes outside roles; network-level multisite actions; WooCommerce or other third-party events; and site options outside the nine-option allowlist.
Concurrency, performance and scale
- Failed logins and reset requests use one
INSERT ... ON DUPLICATE KEY UPDATE statement against a unique bucket key. The counter is incremented by the database and never read into PHP first. The automated test suite asserts exact totals for 1, 10, 100, 1,000 and 500 synchronized attempts and for rotating usernames against the per-source row cap.
- Grouping uses a site-secret keyed fingerprint of the exact client address, so two machines in the same /24 are not merged into one attacker identity, while the stored address is still the truncated form.
- Events are written to a dedicated indexed table, never the options table. The settings tracker checks its allowlist on its first line and returns immediately for every other option.
- Queries are bounded: pages, page size, search length and date range are validated and refused with a clear error rather than run as an unbounded scan. CSV export reads with a keyset cursor inside a snapshot, so a concurrent write cannot duplicate or skip rows, and it does not repeat a
COUNT(*) per page.
- Query plans have not been benchmarked on multi-million-row tables; the indexes are chosen by reasoning, and a very large log with a free-text search over the details column will be slow.
Access control
Reading the log, exporting it, changing its policy, purging it, viewing the diagnostics, repairing the storage and seeing full IP addresses are seven separate capabilities (
devdacti_read,
devdacti_export,
devdacti_manage,
devdacti_purge_log,
devdacti_integrity,
devdacti_repair,
devdacti_view_ip), each with its own filter. They are granted to the administrator role on activation, and any role you grant
devdacti_read to can read the log without being able to export or purge it. Administrators hold all seven. Reducing what gets recorded requires an explicit confirmation; every policy change is written in one statement and recorded with its outcome, and a change that could not be stored is recorded as a failure.
Filter, search and export
- Filter by user, activity group, individual action, object type, severity and date range, or search the object, details and username columns. Filters are reflected in the URL.
- Export the current filtered view to CSV. Every cell is neutralised against spreadsheet formula execution, including formulas hidden behind leading spaces, tabs, newlines, a byte-order mark or invisible Unicode characters.
AI agents and MCP
On WordPress 6.9 and newer the plugin registers eleven abilities through the WordPress Abilities API (and lists them as tools on the official WordPress MCP Adapter when it is installed): get-status, get-settings, get-events, get-recent-activity, get-user-activity, get-login-events, get-plugin-changes, find-suspicious-changes, update-settings, run-purge and repair-storage. Every read checks the same read capability as the screen and is recorded like a screen read; update-settings needs the manage capability and refuses a change that reduces coverage until it is confirmed; run-purge and repair-storage need their own capabilities and an explicit confirmation. No raw e-mail address and no server path leaves the site through an ability. On older WordPress nothing is registered.
Free
Every tracker, filter, the dashboard, retention control and CSV export are free. There is no paid tier and no locked feature inside the log.
Known limitations
These are deliberate, and named here rather than implied away:
- The log is a normal database table. A site administrator or anyone with database access can edit or delete rows in it, and this plugin does not detect that. There is no hash chaining or signed batching, so the log is evidence of what happened on a site you still control, not evidence that survives a compromise of it.
- Event details are stored as a readable sentence rather than a structured, versioned payload. That makes them easy to read and search, and it means a personal-data erasure clears the whole sentence for the account concerned instead of individual fields.
- CSV export is synchronous and capped. Very large exports should be narrowed by date range rather than run in one request; there is no background export job with progress and resume.
- The user filter offers the 200 most recently active accounts and says so; it is not a complete, pageable directory.
- On multisite, events are stored per site and are read per site. There is no network-wide screen that queries every blog at once.
- Query plans have not been benchmarked against multi-million-row tables.
- A personal-data erasure runs as a single pass over the table; on a very large log it can be slow.