laravel-enso/actionlogger
Laravel Enso Action Logger provides an audit trail for your application by recording user actions and model changes. It captures who did what and when, with configurable logging and an easy way to review activity.
Install the package via Composer and run its migrations:
composer require laravel-enso/actionlogger
php artisan vendor:publish --tag=actionlogger-config
php artisan migrate
Enso packages assume the wider Enso core (laravel-enso/enso), so if you are not already on that stack, expect to pull in a few dependencies before this package is useful on its own. Once installed, the first place to look is the published config file (config/enso/actionlogger.php or config/actionlogger.php, depending on your Enso version) — this is where you declare which models should be observed. Then inspect the generated action_logs table and the bundled ActionLog model to understand the shape of the records you will be querying.
The first real use case is straightforward: you have models like Post, Invoice, or User, and you want an audit trail of who created, updated, or deleted a record. Add the package trait to each model you care about (typically LogsActions or similar — confirm the exact trait name in src/Traits), register the model in the config allow-list, and thereafter any Eloquent save/delete through that model writes a row automatically. Reads are done with the ActionLog model or its relationships, e.g. ActionLog::where('model_id', $post->id)->where('model_class', Post::class)->latest()->get().
Opt-in per model, not global. Keep the config whitelist tight. Start with the two or three models that genuinely need an audit trail (billing, permissions, content), then widen once you have confirmed the write overhead is acceptable. Treating this as a global hook across every model is how you end up with a multi-million-row table within a quarter.
Display in Enso's UI, or roll your own. If you are on full Enso, the admin panel ships a screen for browsing action logs — check routes/ and the Vue components under resources/js before building a viewer. If you are outside Enso, the table is plain Eloquent and you can expose it through any controller or Nova/Filament resource.
Use the polymorphic link for timelines. The log rows carry a model class and id, so a morphMany relationship from your audited model back to ActionLog is the cleanest way to render a per-record history:
public function actionLogs()
{
return $this->morphMany(ActionLog::class, 'model');
}
Pair with the auth context. Records are stamped with the acting user id. In web requests this comes from the authenticated guard; in jobs, commands, or queue workers there is no user, so those rows will be null/system-attributed. If background changes matter for compliance, wrap the job in Auth::loginUsingId() temporarily or write a custom log entry describing the actor.
Report and alert on top of it. Because the data is a normal table, the highest-leverage integration is a scheduled report: deletions per day, privilege changes, or spikes in updates to sensitive models. A simple daily query against action_logs is often more valuable than the UI itself.
Pruning is a first-class concern. Plan a retention job from day one — a scheduled ActionLog::where('created_at', '<', now()->subMonths(12))->delete() in chunks — rather than discovering the table's size problem later.
Model::where(...)->update(...), insert(), and raw query-builder writes do not fire Eloquent events, so they will not produce log rows. If you need those captured, you must log them manually or route writes through model instances.deleted/restored events or only hard deletes; test explicitly before relying on it for compliance.php artisan config:clear or the change will silently not apply and you will spend an hour debugging why nothing is logged.body column) bloating rows, and consider excluding noisy attributes if the config supports it.user_id will be null unless you actingAs(...). This bites during test writing more often than in production.ActionLog model or composing your own listener rather than forking; check the src/ tree for an overridable service binding before you patch vendor code.How can I help you explore Laravel packages today?