Title: Who Changed It? – Activity Log &amp; Audit Trail
Author: Guido Schad
Published: <strong>August 4, 2026</strong>
Last modified: August 6, 2026

---

Search plugins

![](https://ps.w.org/who-changed-it/assets/banner-772x250.png?rev=3635256)

![](https://ps.w.org/who-changed-it/assets/icon-256x256.png?rev=3635256)

# Who Changed It? – Activity Log & Audit Trail

 By [Guido Schad](https://profiles.wordpress.org/cmdgw/)

[Download](https://downloads.wordpress.org/plugin/who-changed-it.0.8.0.zip)

 * [Details](https://vec.wordpress.org/plugins/who-changed-it/#description)
 * [Reviews](https://vec.wordpress.org/plugins/who-changed-it/#reviews)
 *  [Installation](https://vec.wordpress.org/plugins/who-changed-it/#installation)
 * [Development](https://vec.wordpress.org/plugins/who-changed-it/#developers)

 [Support](https://wordpress.org/support/plugin/who-changed-it/)

## Description

Who edited that page? Who deleted the post that was there yesterday? Who installed
that plugin, switched open registration on, or created a new administrator account
at three in the morning?

**Who Changed It?** answers those questions. It records what happens on your WordPress
site and shows it as one searchable, filterable list: logins, failed logins and 
logouts, user and role changes, plugin and theme installs, updates, activations 
and deletions, core updates, theme and plugin file editor use, post, page and media
edits — with the exact fields that changed — and changes to sensitive site settings.

#### Every event is classified

Most activity logs hand you a wall of identical rows and leave you to spot the one
that matters. This one sorts every event into three levels:

 * **Normal** — routine operation.
 * **Strange** — unusual but not necessarily harmful (a failed login, a settings
   change, a login at 3 AM).
 * **Dangerous** — high-risk activity you should look at now (brute-force login 
   bursts, new administrator accounts, theme/plugin file editor use, open registration
   being switched on).

Classification is a two-stage process: every event type has a base severity, and
contextual heuristics can escalate it — logins at unusual hours, logins from IP 
addresses never seen for that user, bursts of failed logins from one IP, bursts 
of deletions by one user. Every escalation is stored with a human-readable reason
shown in the log and in alert emails.

#### Tamper-evident by design

An activity log is only worth as much as its resistance to being edited. Every record
here stores a hash of its own contents plus the hash of the record before it, so
changing or removing an entry breaks every link that follows and is reported on 
the log screen.

Legitimate deletions are not silent either: retention purges, manual purges and 
GDPR erasures record the span they removed, so the chain still verifies across the
gap. Anything else is flagged. Redaction rewrites what a record shows while leaving
the hash that sealed it intact, so honouring a privacy request never costs you the
audit trail.

For evidence that holds up against database-level access, move the chain key out
of the database by adding `define( 'WHOCHITA_CHAIN_KEY', 'a long random string' );`
to `wp-config.php`. The settings screen tells you which mode you are in.

#### Features

 * Color-coded log screen with severity icons and per-severity count chips, free-
   text search, and filters for severity, event family, event type, user and date
   range
 * Field-level change diffs shown inline: see exactly what changed in a post, a 
   profile, or a setting
 * Immediate email alerts for dangerous events, throttled so a brute-force attack
   sends one email, not hundreds
 * **Append-only and hash-chained.** Each record hashes the one before it. Deleted
   or altered rows are detected and flagged on the log screen.
 * **Stays on your server.** No telemetry, no third-party log store. The only thing
   that ever leaves your site is a notification you switched on yourself.
 * **Alerts where you already work.** Forward flagged events to email, Slack, Discord
   or Telegram. Every channel is off until you paste in a destination, and a burst
   of events becomes one message, not hundreds.
 * **Retention and redaction.** Per-family retention windows; mask, hash, or drop
   IP addresses; redact personal data to satisfy GDPR requests without breaking 
   the chain.
 * **Scoped access.** Reading the log is its own capability. Even administrators
   can be excluded from it.
 * **Evidence you can hand over.** Export a signed, time-bounded record set as CSV
   or JSON for auditors and incident reports.
 * Answers WordPress’s own Export/Erase Personal Data tools
 * Mute individual event types to keep the log signal-heavy (events about the plugin
   itself can never be muted)
 * WooCommerce support: prices, coupons, orders, refunds, store and payment gateway
   settings
 * Lockora integration: record completed security-audit scores, finding counts, 
   and score deltas when Lockora is active
 * Extensible: log custom events, adjust severities, watch extra options, or forward
   events to external systems via hooks

#### What gets audited

Authentication (logins, failed logins, logouts, password resets), users and roles,
plugin and theme installs/updates/activations/deletions, WordPress core updates,
WordPress 7.0 AI connector and feature changes, theme/plugin file editor use, posts,
pages and media (with field-level diffs of what changed), a watched list of sensitive
site options, and data exports. On WooCommerce shops: product price changes, coupon
amounts, order status changes, refunds, store settings, and payment gateway configuration.

#### What it does not do

It does not phone home, does not require an account, and does not send your log 
to anyone else’s servers. On a default install it makes no outbound network requests
at all — a regression test over every shipped file enforces that, and asserts that
every notification channel ships switched off.

The single exception is the one you configure. If you enable Slack, Discord or Telegram
notifications, the plugin posts to that service and only that service:

 * **Slack** — messages go to the incoming webhook you paste in, on `hooks.slack.
   com`. [Terms](https://slack.com/terms-of-service) · [Privacy](https://slack.com/trust/privacy/privacy-policy)
 * **Discord** — messages go to the channel webhook you paste in, on `discord.com`.
   [Terms](https://discord.com/terms) · [Privacy](https://discord.com/privacy)
 * **Telegram** — messages go to the chat ID you name, via `api.telegram.org`, using
   your own bot token. [Privacy](https://telegram.org/privacy)

Webhook URLs are pinned to those hosts, so a compromised settings screen cannot 
redirect your log somewhere else. A notification carries the event type, object,
user, IP address and time — the same fields the alert email sends, with the IP already
masked to whatever privacy setting you chose. Field-level diffs are never sent.

## Screenshots

[⌊The activity log: per-severity count chips, filters for severity, event type, 
user and date range, free-text search, and an expanded record showing the field-
level diff of what changed.⌉⌊The activity log: per-severity count chips, filters
for severity, event type, user and date range, free-text search, and an expanded
record showing the field-level diff of what changed.⌉[

The activity log: per-severity count chips, filters for severity, event type, user
and date range, free-text search, and an expanded record showing the field-level
diff of what changed.

[⌊The same log grouped by day, with a burst of related dangerous events collapsed
into a single entry and the reason it was escalated shown in plain language.⌉⌊The
same log grouped by day, with a burst of related dangerous events collapsed into
a single entry and the reason it was escalated shown in plain language.⌉[

The same log grouped by day, with a burst of related dangerous events collapsed 
into a single entry and the reason it was escalated shown in plain language.

## Installation

 1. Upload the plugin to `/wp-content/plugins/who-changed-it/`, or install it through
    the Plugins screen.
 2. Activate it through the Plugins screen. The log table is created automatically.
 3. Find the log under the new “Activity Log” menu item.

If your site runs behind a reverse proxy or CDN, map the real client IP header via
the `whochita_client_ip` filter — otherwise all events will appear to come from 
the proxy’s address.

## FAQ

### How do I find out who edited a page or post in WordPress?

Open the Activity Log screen and search for the page title, or filter the event 
family to “content”. Each edit shows the user, the time, the IP address, and a field-
level diff of what actually changed — title, slug, excerpt, author, content length,
password protection, parent.

### How do I see who deleted a post or a page?

Deletions are recorded like any other event, with the user who did it and the name
of the thing that was deleted. Filter by the “content” family, or search the title
of the missing item. A burst of deletions by one user is escalated to **Dangerous**
automatically.

### How do I see who installed, activated or deleted a plugin?

Filter the log by the “plugins” or “themes” family. Installs, updates, activations,
deactivations and deletions are all recorded with the user who performed them. Use
of the built-in theme and plugin file editor is classified **Dangerous** on sight,
because that is how a compromised administrator account usually plants code.

### How do I see failed login attempts and brute-force attacks?

Failed logins are recorded with the username tried and the originating IP. A burst
of failures from one IP is escalated to **Dangerous** and triggers an email alert—
throttled, so an attack sends you one message rather than hundreds.

### Will an activity log slow down my site?

It writes one row to its own database table when something happens, and nothing 
at all on ordinary page views by visitors. There are no external calls to wait on,
and retention keeps the table from growing without limit. The reporting and diff
work happens on the admin screen, not on the front end.

### How is this different from other activity log plugins?

Three things. Every event is classified as Normal, Strange or Dangerous with a stated
reason, so you are not scanning thousands of identical rows. The log is hash-chained,
so an attacker who cleans up after themselves is detected instead of trusted. And
exports are cryptographically signed, so what you hand an auditor or an insurer 
can be shown not to have been edited afterwards.

### Does it log activity from before it was installed?

No. It records events as they happen, starting at activation.

### How long are events kept?

3 months by default. Configure the retention window (or keep all data forever) on
the settings screen; developers can additionally use the `whochita_retention_days`
filter.

### Can I keep some events longer than others?

Yes. Events are grouped into families — authentication, users, content, plugins,
themes, core, settings, WooCommerce, and a catch-all — and each family can keep 
the default window, use its own, or keep everything forever.

### Can I change how events are classified?

Yes — override the base severity of any event type with the `whochita_base_severity_map`
filter, and extend the list of audited options with `whochita_watched_options`.

### Does it work with WooCommerce?

Yes. When WooCommerce is active, the plugin automatically also records product price
changes (a price drop of more than 50% raises the severity), coupon amount changes,
order status changes, refunds, store settings, and payment gateway configuration
changes. Gateway secrets and API keys are never stored in the log.

### Does the plugin send any data to external services?

Not unless you ask it to. Out of the box everything stays in your own WordPress 
database and the plugin makes no external calls whatsoever. If you turn on Slack,
Discord or Telegram notifications, it sends alert messages to that service and nothing
else — see “What it does not do” above for exactly what each message contains.

### Can I get activity alerts in Slack?

Yes. Create an Incoming Webhook for the channel you want, paste the URL into the
plugin settings, and choose whether you want dangerous events only, dangerous and
strange, or everything. Discord webhooks and Telegram bots work the same way. Alerts
are throttled per event type, so a brute-force attack sends one message rather than
hundreds, and several events in the same request arrive as a single grouped message.

### Can I send alerts to WhatsApp?

Not directly. WhatsApp has no webhook, and business-initiated messages need a message
template pre-approved by Meta, which does not suit alerts whose content changes 
every time. Telegram is the closest equivalent and takes about a minute to set up.

### How do I know the log has not been edited?

The log screen shows the chain status every time you open it. “Verify now” re-runs
the check on demand, walking every record and confirming its position, its link 
to the previous record, and that its stored fields still match the hash written 
when it was recorded.

### Can I hide the log from administrators?

Yes. Reading the log is governed by the `whochita_view_log` capability. Switch read
access to capability mode and grant it to the roles you choose; administrators then
see the log only if you grant it to them. Changing plugin settings still requires
the administrator role, so you cannot lock yourself out.

### Is it GDPR friendly?

Yes. IP addresses can be stored whole, masked to /24 (IPv4) or /48 (IPv6), stored
as a keyed digest, or not stored at all, and everything already recorded can be 
masked with one button. The plugin answers WordPress’s own Export and Erase Personal
Data tools; erasure redacts records rather than deleting them, so evidence about
other people’s actions survives and the chain still verifies.

### What does a signed export contain?

The records with their chain hashes, plus a manifest recording the site, the filters
and time bounds you exported, the record count, the chain positions covered, and
whether the chain verified at that moment. The manifest is covered by an HMAC-SHA256
signature, so neither the records nor the stated bounds can be altered afterwards
without invalidating it.

### What happens to my existing log when I update?

Records written before this version are sealed into the chain on upgrade, oldest
first. That proves they have not changed since the upgrade — it cannot prove anything
about what happened before it, and the plugin records that boundary rather than 
blurring it.

## Reviews

![](https://secure.gravatar.com/avatar/0790b422a8709f50614d0ea3a74ef5ec4da4089ad8abdaad7186e824147e1b1d?
s=60&d=retro&r=g)

### 󠀁[Excellent acitivty log for wordpress](https://wordpress.org/support/topic/excellent-acitivty-log-for-wordpress/)󠁿

 [jervais](https://profiles.wordpress.org/jervais/) August 7, 2026

Excellent alternative for the big oversized wordpress activity log plugins, small,
lightweight but does everything you need – plus you can export the log any time 
and the support answered me within minutes. 10/10.

![](https://secure.gravatar.com/avatar/01ca6885f4ee9e50021cd307793981c73288bec8c0e1ddc8364a2df8b6e09110?
s=60&d=retro&r=g)

### 󠀁[Finally, an activity log that doesn’t slow things down](https://wordpress.org/support/topic/finally-an-activity-log-that-doesnt-slow-things-down/)󠁿

 [michaelseri](https://profiles.wordpress.org/michaelseri/) August 5, 2026

Who Changed it plugin does exactly what it promises – a lightweight, field-level
activity log that actually tells you what changed and who did it, not just that 
something did. The before/after diffs on posts and settings are a huge time-saver,
and having every event automatically flagged as normal, unusual, or dangerous makes
it easy to spot suspicious activity. Very nice that CSV/JSON export isn’t locked
behind a premium tier. Setup was genuinely just activate-and-go, no config headaches.
Highly recommended!

 [ Read all 2 reviews ](https://wordpress.org/support/plugin/who-changed-it/reviews/)

## Contributors & Developers

“Who Changed It? – Activity Log & Audit Trail” is open source software. The following
people have contributed to this plugin.

Contributors

 *   [ Guido Schad ](https://profiles.wordpress.org/cmdgw/)

[Translate “Who Changed It? – Activity Log & Audit Trail” into your language.](https://translate.wordpress.org/projects/wp-plugins/who-changed-it)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/who-changed-it/), check
out the [SVN repository](https://plugins.svn.wordpress.org/who-changed-it/), or 
subscribe to the [development log](https://plugins.trac.wordpress.org/log/who-changed-it/)
by [RSS](https://plugins.trac.wordpress.org/log/who-changed-it/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 0.8.0

 * Forward flagged events to Slack, Discord or Telegram. Every channel ships switched
   off and stays inert until a destination is saved, so a default install still 
   makes no network requests — the regression suite asserts both.
 * Choose what gets forwarded: dangerous events only, dangerous and strange, or 
   everything.
 * Alert emails gained a settings screen: multiple recipients, the same severity
   choice, and a configurable quiet period.
 * Notifications are queued and sent when the request ends, so no admin action waits
   on a remote service, and several events in one request arrive as a single grouped
   message.
 * Webhook URLs are pinned to the vendor’s own host over HTTPS, so settings access
   cannot be turned into a request proxy. URLs and bot tokens are never written 
   to the log or included in an export.

#### 0.7.0

 * Added optional Lockora Security Audit integration via the `lockora_scan_completed`
   action. The plugin watches for Lockora rather than depending on it: nothing changes
   if Lockora is not installed.
 * Lockora scan events record the current score and pass, warning, and failure counts,
   plus score deltas when a previous scan is available. They are classified Normal
   and filed under the settings family, so per-family retention applies to them.
 * Minimum PHP requirement lowered from 8.1 to 7.4, so the plugin installs on older
   hosts.
 * Renamed to “Who Changed It? – Activity Log & Audit Trail”, with the plugin description
   rewritten around the questions the log answers.

#### 0.6.0

 * Append-only hash chain: every record now hashes the record before it, and altered
   or deleted rows are detected and flagged on the log screen and settings page.
 * Authorized removals — retention purges, manual purges and GDPR erasures — record
   the span they removed so the chain still verifies across the gap; anything else
   is reported as tampering.
 * Per-family retention: nine event families, each able to keep the default window,
   set its own, or keep everything.
 * Privacy controls: store IP addresses whole, masked to /24 (IPv4) or /48 (IPv6),
   as a keyed digest, or not at all — plus a button to mask everything already recorded.
 * The log now answers WordPress’s Export and Erase Personal Data tools. Erasure
   redacts records instead of deleting them, so evidence about other people’s actions
   survives and the chain still verifies.
 * Reading the log is now its own capability (`whochita_view_log`), grantable per
   role, with a mode in which administrators have no access unless granted.
 * Signed evidence export in CSV and JSON, carrying each record’s chain hashes and
   a manifest covering the filters, time bounds, record count, chain span and verification
   state.
 * Filter the log by event family.
 * Exports can be restricted to users who can change the plugin settings.
 * The chain key can be moved out of the database with the `WHOCHITA_CHAIN_KEY` 
   constant in wp-config.php.

#### 0.5.0

 * WordPress 7.0 AI connector connections and disconnections are now audited without
   storing API keys.
 * AI master-switch and individual WordPress AI plugin feature changes are now audited.
 * Admin styles and confirmation behavior now load through the WordPress enqueue
   APIs.
 * Plugin file metadata now uses WordPress APIs, and file-editor auditing verifies
   request nonces and permissions.
 * Internal identifiers now use a unique plugin prefix, filtered database queries
   are fully prepared, and generated badge markup is escaped at output.
 * Empty date filters now use valid database date boundaries, preventing MySQL DATETIME
   warnings on the activity-log screen.
 * A renamed pre-release predecessor is detected so two installed copies cannot 
   register duplicate menus or audit hooks.
 * AI connector deletions are audited without reading API-key options, and file-
   editor auditing now observes the core admin lifecycle hook.

#### 0.4.0

 * Field-level change tracking: post updates now record what changed (title, slug,
   excerpt, author, content word counts, password protection, parent), profile updates
   record email/display name/website changes, and the log screen displays these 
   diffs inline.
 * Free-text search across object names, usernames, event types, IPs, and escalation
   reasons — the CSV export honors the search too.
 * Per-event mute list in the settings: uncheck any event type to stop recording
   it. Events about the plugin itself can never be muted.
 * WooCommerce support: product price changes (a >50% price drop escalates the severity),
   coupon amount changes, order status changes, refunds, store settings, and payment
   gateway configuration changes (classified dangerous; secret values are never 
   stored).

#### 0.3.0

 * Configurable log retention: keep all data, or delete events older than a chosen
   number of days/months, with the next scheduled purge shown and a “Purge Old Data”
   button to run it immediately.
 * Events timestamp setting: display log times in UTC or in the timezone configured
   on the WordPress site (storage stays UTC).
 * Factory reset button for the plugin settings (log data untouched) and a purge
   button that wipes the activity log; the purge is recorded as the first event 
   of the fresh log and classified as dangerous.

#### 0.2.0

 * Settings screen: restrict who can change plugin settings (only me / all administrators),
   grant log viewing to specific users or roles, and customize the From address 
   and display name of alert emails.
 * Severity badges now carry icons (check / caution sign / crossed circle) and the
   log shows clickable per-severity count chips.
 * Plugin settings changes are themselves logged as auditable events.

#### 0.1.1

 * Neutralize formula-leading values in CSV exports.
 * Rate-limit failed-login audit records and add the supporting query index.
 * Apply database schema updates automatically after plugin updates.

#### 0.1.0

 * Initial release: activity capture, normal/strange/dangerous classification with
   escalation heuristics, log screen, email alerts, CSV export, retention purge.

## Meta

 *  Version **0.8.0**
 *  Last updated **6 days ago**
 *  Active installations **10+**
 *  WordPress version ** 6.0 or higher **
 *  Tested up to **7.0.3**
 *  PHP version ** 7.4 or higher **
 *  Language
 * [English (US)](https://wordpress.org/plugins/who-changed-it/)
 * Tags
 * [Activity Log](https://vec.wordpress.org/plugins/tags/activity-log/)[audit log](https://vec.wordpress.org/plugins/tags/audit-log/)
   [audit trail](https://vec.wordpress.org/plugins/tags/audit-trail/)[security](https://vec.wordpress.org/plugins/tags/security/)
   [user activity](https://vec.wordpress.org/plugins/tags/user-activity/)
 *  [Advanced View](https://vec.wordpress.org/plugins/who-changed-it/advanced/)

## Ratings

 5 out of 5 stars.

 *  [  2 5-star reviews     ](https://wordpress.org/support/plugin/who-changed-it/reviews/?filter=5)
 *  [  0 4-star reviews     ](https://wordpress.org/support/plugin/who-changed-it/reviews/?filter=4)
 *  [  0 3-star reviews     ](https://wordpress.org/support/plugin/who-changed-it/reviews/?filter=3)
 *  [  0 2-star reviews     ](https://wordpress.org/support/plugin/who-changed-it/reviews/?filter=2)
 *  [  0 1-star reviews     ](https://wordpress.org/support/plugin/who-changed-it/reviews/?filter=1)

[Your review](https://wordpress.org/support/plugin/who-changed-it/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/who-changed-it/reviews/)

## Contributors

 *   [ Guido Schad ](https://profiles.wordpress.org/cmdgw/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/who-changed-it/)