Understanding the audit log
One table, every state change, every Impulse module. How audit entries are shaped, where to filter them, the default retention behaviour, and the SQL fallback for grep-at-scale queries.
Last updated 20 days ago
Understanding the audit log
Every state change across every Impulse module writes to one place: mod_impulsecore_audit_log. Admin clicks, customer self-service actions, cron tasks, system reconciliations β all land in the same table with the same shape.
Where entries come from
The log is populated by Core itself plus every module that calls Core's audit helper:
ImpulseCore::audit('impulseminio', 'server.provisioned', [ 'server_id' => 42, 'region' => 'us-central-dallas',]);Modules are contractually required to audit anything that mutates customer-visible or operationally-significant state. In practice:
- Provisioning events (server provisioned, service created, service destroyed).
- Lifecycle transitions (suspended, unsuspended, terminated, restored).
- Quota and configuration changes (plan upgraded, region added).
- Customer self-service actions (access keys rotated, custom domains added).
- Security & Maintenance events (CVE detected, patch scheduled, snapshot taken, rollback triggered).
- Cron failures β if a registered task throws, Core captures the exception and writes an
errorentry under the module's slug. - License events (verified, expired, re-activated).
Read-only operations (rendering a tab, fetching a status) don't audit. Only state changes do.
What's in each entry
Filtering from the admin tab
Open ImpulseCore β Audit. The default view is the last 100 events across all modules, newest first. Filters on the left:
- Module β narrow to one module's events.
- Action β narrow to a specific dotted action name.
- Source β admin / cron / customer / system.
- Severity β surface only
warnanderrorwhen triaging. - Time range β last 24h / 7d / 30d / 90d / custom.
- Service ID / Admin ID / Client ID β trace one customer's full timeline, or one admin's actions for the day.
Each module's own addon also has a Tools β Audit Log sub-tab pre-filtered to that module. Same data, narrower default view.
What writes here automatically vs. what doesn't
Admin-initiated changes through any Impulse module's admin tab are captured automatically β the module's facade calls handle the audit write for you.
Webhook handlers and cron-internal flows don't write here unless they explicitly route through ImpulseCore::audit(). If you're writing a custom hook or a one-off reconciliation script, call the helper yourself β otherwise the action will happen but won't show up in the log.
Retention
Default retention is 90 days, enforced by Core's audit_purge task running daily. To change it:
- Increase the cutoff under Settings β Audit β Retention (caps at 365 days from the UI; longer than that, edit
mod_impulsecore_settingsdirectly). - Set the cutoff to
0to disable the purge and keep entries indefinitely. - Export periodically via the Audit tab's Export CSV button (respects the active filter). Pair with a monthly job that ships the export to your archive of choice.
The audit log is one of the largest tables in any production install. 90 days at moderate volume is typically a few hundred MB; multi-year retention at high volume can run to tens of GB. Plan disk and backup capacity accordingly.
SQL fallback for grep-at-scale
When the admin filters aren't enough β compliance reports, post-incident analysis, quarterly reviews β query the table directly:
-- Everything one customer triggered in the last 7 daysSELECT created_at, module_slug, source, action, detailFROM mod_impulsecore_audit_logWHERE client_id = 1234 AND created_at > NOW() - INTERVAL 7 DAYORDER BY created_at DESC;-- Every cron error in the last 24h, grouped by module + actionSELECT module_slug, action, COUNT(*) AS n, MAX(created_at) AS last_seenFROM mod_impulsecore_audit_logWHERE source = 'cron' AND severity = 'error' AND created_at > NOW() - INTERVAL 1 DAYGROUP BY module_slug, actionORDER BY n DESC;Security events are a parallel stream
The Security & Maintenance pipeline also writes to mod_impulsecore_security_events in addition to the main audit log. Same events, but with extra structured fields (CVE id, snapshot id, patch outcome) that make security-focused queries cheaper. Use that table when investigating "what happened during last Tuesday's patch?"; use the main audit log when investigating "what did this admin click last week?"