ImpulseCore
The unified audit log
Every state change across every Impulse module writes to one table. One search surface, one retention policy — whether the action came from an admin click, a cron tick, a customer self-service action, or a system reconciliation.
1. What gets audited
Section titled “1. What gets audited”Every module is contractually required to audit anything that mutates customer-visible or operationally-significant state through Core’s audit helper. In practice that means:
- Provisioning events — server provisioned, server destroyed, customer service created, customer service destroyed.
- Lifecycle transitions — service suspended, unsuspended, terminated, restored, purged.
- Quota / configuration changes — plan upgraded, limits adjusted, region added or removed.
- Customer self-service actions — access keys created or rotated, custom domains added, replication jobs started or stopped.
- Security & Maintenance events — CVE detected, patch scheduled, patch started/succeeded/failed, snapshot taken or held, customer deferral requested.
- Cron failures — if a registered cron task fails, Core writes a
cron.task.failedentry under the module slug at levelerror. - License events — failed checks, grace alerts, cleared keys.
- Admin proxy health — a module server that becomes degraded or unreachable (
admin_proxy.unreachable, levelwarn).
Read-only operations (fetching a status, rendering a tab) don’t audit — only state changes do.
2. The shape of an audit row
Section titled “2. The shape of an audit row”| Column | Holds |
|---|---|
created_at |
Timestamp at the moment of write. |
module_slug |
Which module emitted the event (impulseobjects, impulsepostgres, impulsecore). |
event |
Dotted event name like service.suspended, service.purged, module.activated, cron.task.failed. |
level |
debug, info (default), warn, error or critical. |
service_id |
The WHMCS service (tblhosting) if the event is scoped to one. |
client_id |
The WHMCS client (tblclients) if the event is scoped to one. |
project_id |
The ImpulseCore project, when the event is project-scoped. |
request_id |
The request id carried to a module server’s admin proxy, so a backend action can be traced end to end. |
context |
JSON with the structured details the module recorded — changed values, related ids, the admin who acted, error text. |
acknowledged_at |
Set when an error or critical event is acknowledged on the Overview’s Recent failures panel. |
3. Where to look at it
Section titled “3. Where to look at it”The Core Audit Log tab
Section titled “The Core Audit Log tab”Open ImpulseCore → Operations → Audit. It lists every event across all modules, newest first, 100 per page. Filters along the top:
- Level — show one level, e.g. only
errororcriticalentries when triaging. - Module — narrow to one module’s events.
- Event contains — match part of the event name, e.g.
licenseorsuspended.
Errors and criticals also appear on the Overview tab’s Recent failures panel until you acknowledge them; acknowledging hides them there, and the full record stays in the audit log.
Per-module audit views
Section titled “Per-module audit views”Some modules also show their own slice of this log on their admin pages. Same data, narrower default view.
Direct SQL
Section titled “Direct SQL”For ad-hoc queries (compliance reports, post-incident analysis, quarterly reviews):
-- Everything recorded against one customer in the last 7 daysSELECT created_at, module_slug, level, event, contextFROM mod_impulsecore_audit_logWHERE client_id = 1234 AND created_at > NOW() - INTERVAL 7 DAYORDER BY created_at DESC;
-- Every failed cron task in the last 24h, by moduleSELECT module_slug, JSON_UNQUOTE(JSON_EXTRACT(context, '$.task')) AS task, COUNT(*) AS n, MAX(created_at) AS last_seenFROM mod_impulsecore_audit_logWHERE event = 'cron.task.failed' AND created_at > NOW() - INTERVAL 1 DAYGROUP BY module_slug, task ORDER BY n DESC;4. Retention
Section titled “4. Retention”Retention is 90 days, enforced by the audit_purge cron task that runs daily and deletes entries older than the cutoff. The same task trims Core’s cron run log: successful runs after 14 days, failed runs after 90. The cutoff is fixed — there is no setting to lengthen it.
The Audit tab also has manual controls: Run log maintenance now (applies the same retention immediately), Purge old entries (delete entries older than a number of days you choose) and Purge entire audit log (type DELETE to confirm; the purge itself is recorded as the first entry of the new log).
For longer retention (compliance, legal hold, periodic review), copy the table out before entries age past 90 days — for example a scheduled mysqldump or SELECT … INTO OUTFILE of the previous month’s rows, shipped to your archive of choice.
5. Security events are a related, separate stream
Section titled “5. Security events are a related, separate stream”The Security & Maintenance pipeline writes to a parallel table (mod_impulsecore_security_events) in addition to the main audit log. Each security event has an audit twin, and the security row links back to it (audit_log_id); security events carry their own type, severity and structured context (CVE id, snapshot id, patch outcome) that make security-focused queries cheaper. The security_events_purge cron handles its own 90-day retention.
If you’re investigating “what happened during last Tuesday’s patch?” the security events table is the right place to start; if you’re investigating “what changed on this service last week?” the main audit log is.