What Gets Logged
The audit log captures every significant admin action across seven categories. Each event is recorded with full context including who performed it, what changed, and when it happened.
| Category | Events | Severity |
|---|---|---|
| Authentication | login_success, login_failed, logout |
info / warning |
| Plugins | plugin_activated, plugin_deactivated, plugin_updated, plugin_deleted |
notice / warning / critical |
| Themes | theme_switched, theme_updated |
warning / notice |
| Options | option_updated |
notice |
| Users | role_changed, user_created, user_deleted |
warning / notice / critical |
| Posts | post_status_changed |
info |
| Core Updates | core_updated |
notice |
Options logging automatically skips noisy internal WordPress options such as cron, transient, _site_transient, rewrite_rules, and any option prefixed with adminlocks_. Only scalar values are logged to avoid storing massive serialized arrays.
Log Entry Fields
Each audit log entry is a row in the adminlocks_audit table with the following fields:
| Field | Type | Description |
|---|---|---|
id |
bigint | Auto-incrementing primary key |
event_type |
varchar | Machine-readable event identifier (e.g., login_success) |
severity |
varchar | One of: info, notice, warning, critical |
actor_id |
bigint | WordPress user ID of the person who performed the action (0 for system/anonymous) |
actor_email |
varchar | Email of the acting user at the time of the event |
actor_ip |
varchar | IP address from $_SERVER['REMOTE_ADDR'] |
object_type |
varchar | What was affected: user, plugin, theme, option, post, page, etc. |
object_id |
bigint | ID of the affected object (user ID, post ID, etc.) |
object_name |
varchar | Human-readable name of the affected object |
description |
text | Full-sentence description of what happened |
meta_before |
longtext | JSON snapshot of the state before the change (nullable) |
meta_after |
longtext | JSON snapshot of the state after the change (nullable) |
created_at |
datetime | UTC timestamp of when the event occurred |
Change Diffs
For events that modify data, the meta_before and meta_after fields store JSON representations of the relevant state. This allows you to see exactly what changed.
// Example: theme switch diff
{
"meta_before": { "theme": "twentytwentyfour" },
"meta_after": { "theme": "astra" }
}
// Example: user role change diff
{
"meta_before": { "roles": ["editor"] },
"meta_after": { "role": "administrator" }
}
// Example: option update diff
{
"meta_before": { "value": "My Old Site Title" },
"meta_after": { "value": "My New Site Title" }
}
Browsing the Log
The audit log is accessible through the REST API at GET /wp-json/adminlocks/v1/audit-log. The endpoint requires the manage_options capability and returns a paginated list of entries.
// GET /wp-json/adminlocks/v1/audit-log?per_page=20&page=1
{
"items": [
{
"id": 847,
"event_type": "plugin_activated",
"severity": "notice",
"actor_id": 1,
"actor_email": "admin@example.com",
"actor_ip": "192.168.1.10",
"object_type": "plugin",
"object_id": 0,
"object_name": "woocommerce/woocommerce.php",
"description": "Plugin activated: woocommerce/woocommerce.php",
"meta_before": null,
"meta_after": null,
"created_at": "2026-03-05 14:22:10"
}
],
"total": 1247
}
The meta_before and meta_after fields are automatically decoded from JSON strings to objects in the REST response, so you can work with them directly in JavaScript without an additional parse step.
Filtering & Search
The audit log query method supports several filter parameters that can be combined in any combination.
| Parameter | Type | Description |
|---|---|---|
per_page |
integer | Items per page, 1-100. Default: 20 |
page |
integer | Page number. Default: 1 |
event_type |
string | Filter by exact event type (e.g., login_failed) |
severity |
string | Filter by severity level: info, notice, warning, critical |
actor_id |
integer | Filter by the WordPress user ID of the actor |
search |
string | Full-text search across description, object_name, and actor_email |
date_from |
string | Start date in Y-m-d H:i:s format (UTC) |
date_to |
string | End date in Y-m-d H:i:s format (UTC) |
orderby |
string | Sort column: id, created_at, event_type, severity. Default: created_at |
order |
string | ASC or DESC. Default: DESC |
// Find all failed logins in the last 24 hours
GET /wp-json/adminlocks/v1/audit-log
?event_type=login_failed
&date_from=2026-03-04T14:00:00
&per_page=50
// Search for actions related to WooCommerce
GET /wp-json/adminlocks/v1/audit-log
?search=woocommerce
&severity=warning
Exporting Data
The audit log can be exported in CSV or JSON format through a dedicated export endpoint. Exports fetch up to 10,000 entries in a single request and return a file download with an appropriate Content-Disposition header.
Export Endpoint
// Export as CSV (default)
GET /wp-json/adminlocks/v1/audit-log/export
// Export as JSON
GET /wp-json/adminlocks/v1/audit-log/export?format=json
// Export filtered data
GET /wp-json/adminlocks/v1/audit-log/export
?format=csv
&severity=critical
&date_from=2026-02-01
&date_to=2026-03-01
The export endpoint accepts the same filter parameters as the main audit log endpoint: event_type, severity, search, date_from, and date_to.
The CSV export includes the columns: id, event_type, severity, message, actor_id, actor_email, object_type, object_id, ip_address, and created_at. Files are named adminlocks-audit-YYYY-MM-DD.csv (or .json).
Exports are capped at 10,000 entries per request. If your log contains more entries than this, use the date filters to export in time-based batches.
Retention & Cleanup
AdminLocks runs a daily cron job (adminlocks_audit_cleanup) that removes entries older than the configured retention period.
Configuration
| Setting | Option Key | Default | Description |
|---|---|---|---|
| Retention Period | adminlocks_audit_days |
14 days | Number of days to keep audit entries. Set to 0 for unlimited retention. |
| Audit Enabled | adminlocks_audit_enabled |
true |
Set to false to disable all audit logging entirely. |
// Set retention to 90 days via the REST API
PUT /wp-json/adminlocks/v1/settings
{
"audit_days": 90
}
// Disable the audit log entirely
PUT /wp-json/adminlocks/v1/settings
{
"audit_enabled": false
}
Cloud-connected sites can set retention to 0 (unlimited) because log data is also synced to the AdminLocks Cloud dashboard where it can be queried across all your sites in a single view.
The cleanup cron runs the SQL query DELETE FROM {table} WHERE created_at < DATE_SUB(NOW(), INTERVAL {days} DAY), removing all entries beyond the retention window in a single operation. If the retention value is 0 or negative, the cleanup function returns immediately without deleting anything.