emran-alhaddad/statamic-logbook
Statamic Logbook adds a simple audit trail to your Statamic site, recording content changes, user actions, and other events so you can see who did what and when. Review activity in a searchable logbook inside the Control Panel, ideal for team accountability and compliance.
Install and publish:
composer require emran-alhaddad/statamic-logbook
php artisan vendor:publish --tag=logbook-config
php artisan vendor:publish --tag=logbook-migrations
php artisan migrate
Statamic auto-discovers the add-on; there is no manual provider registration in config/app.php.
Look here first, in this order:
config/logbook.php — the only real control surface (enabled channels, retention, guard/site capture, middleware toggle).database/migrations/* — tells you the exact table/column names you will query against.src/Listeners and src/Http/Middleware — tells you what is captured automatically, which is the single biggest question you'll have in week one.routes/cp.php — the CP routes and, importantly, the export endpoint you may want to reuse.First use case: turn on audit logging for content and auth events, then confirm in the Control Panel under the Logbook nav item that an entry edit, a login, and a failed login all appear with the acting user attached. If the audit stream is empty, the middleware or event subscribers are usually disabled in config — that is the first thing to check.
Treat the two streams as separate concerns. System logs (framework/PHP errors routed into the DB) and user audit logs (who did what) have different retention, different access rules, and different volume. Configure them independently rather than flipping one global switch.
Log domain events explicitly. Automatic capture covers Statamic CRUD and auth, but the valuable audit trail is usually business-level: order refunds, publish/unpublish of a landing page, role changes. Wrap those in a small service or a queued listener that writes to the logbook with a stable event key (content.published, user.role_changed), the actor, and a compact context payload. Keep the event key stable — your reports and CSV exports will filter on it.
Pair it with Statamic events rather than controllers. Registering listeners on EntrySaved, UserLoggedIn, BlueprintSaved, etc. keeps logging out of your application code and makes it easy to disable per-environment.
Use the Eloquent model for reporting, the CP UI for humans. The UI is fine for "what happened to this page yesterday". For dashboards, scheduled digests, or Slack alerts, query the underlying model directly with scopes on created_at, user_id, and event name — it is far faster than scraping the CP.
CSV export is an integration point. Either hit the CP export route with an authenticated request, or reimplement the export with a streamed response over the same query builder. The latter is worth it if you need exports on a schedule — wire it into an Artisan command and a Mailable so admins get a monthly audit pack without logging in.
Schedule pruning. Whatever retention setting exists, it is only enforced by a scheduled command. Add it to routes/console.php / the scheduler explicitly; unpruned audit tables are the most common way this package becomes a problem.
Test the trail, not the package. In feature tests, use RefreshDatabase, perform the action, and assert a log row exists with the expected event key and actor — this catches accidental removal of listeners during refactors.
vendor:publish --tag=logbook-migrations + migrate step to your deploy script and CI, not just your local setup.php artisan config:clear. A stale config cache silently produces empty logs.created_at, user_id, and the event column, and set retention aggressively for system logs and conservatively for audit logs.composer.json and read the changelog before upgrading Statamic; a 9-star add-on has a small compatibility matrix.dev-main as unstable.src/ directly and avoid depending on classes marked internal — be prepared to fork or copy the queries if the package stalls. Budget half a day to read the source before building reporting on top of it.How can I help you explore Laravel packages today?