Statamic Logbook
Latest Release License Open Issues Last Commit
A production-ready logging and audit trail addon for Statamic.
Statamic Logbook provides a centralized place to review:
- System logs (Laravel / Monolog)
- User audit logs (who changed what, and when)
All inside the Statamic Control Panel, with filtering, analytics, and CSV export.
Features
System logs
- Captures Laravel log events automatically (no manual
logging.phpwiring required) - Stores structured records in Logbook DB tables
- Captures request context (URL, method, IP, user, request id)
- Supports noise filtering by channel/message fragment
Audit logs
- Captures high-signal Statamic mutation events by default
- Stores action, subject metadata, and entry-level before/after diffs
- Supports field-level ignore rules and value truncation
- Supports optional broader event discovery mode
Control Panel
- Native Statamic CP styling/components
- Dashboard widgets (overview, trends, live pulse)
- Utility views with filtering and CSV export
- Widget set includes:
- Logbook Overview (24h health cards)
- Logbook Trends (daily stacked volume)
- Logbook Pulse (live mixed feed + quick filters)
Widget preview
Overview cards
Logbook Overview Cards
Trends
Logbook Trends Volume
Live pulse
Logbook Live Pulse
Widget slugs (handles)
Use these widget handles when configuring dashboard widgets:
logbook_stats(Overview cards)logbook_trends(Volume by day)logbook_pulse(Live feed)
Compatibility
| Component | Supported |
|---|---|
| Statamic | v4, v5, v6 |
| Laravel | 10, 11 |
| PHP | 8.1+ |
Installation
composer require emran-alhaddad/statamic-logbookphp artisan vendor:publish --tag=logbook-config
Setup (Required)
1) Configure Logbook database credentials in .env
These are required for Logbook to work:
LOGBOOK_DB_CONNECTION=mysqlLOGBOOK_DB_HOST=127.0.0.1LOGBOOK_DB_PORT=3306LOGBOOK_DB_DATABASE=logbook_databaseLOGBOOK_DB_USERNAME=logbook_userLOGBOOK_DB_PASSWORD=secret
Then clear config cache:
php artisan config:clear
2) Install database tables
php artisan logbook:install
Environment Variables
All variables used by the addon:
# Required DB connectionLOGBOOK_DB_CONNECTION=mysqlLOGBOOK_DB_HOST=127.0.0.1LOGBOOK_DB_PORT=3306LOGBOOK_DB_DATABASE=logbook_databaseLOGBOOK_DB_USERNAME=logbook_userLOGBOOK_DB_PASSWORD=secret # Optional DB tuningLOGBOOK_DB_SOCKET=LOGBOOK_DB_CHARSET=utf8mb4LOGBOOK_DB_COLLATION=utf8mb4_unicode_ci # System loggingLOGBOOK_SYSTEM_LOGS_ENABLED=trueLOGBOOK_SYSTEM_LOGS_LEVEL=debugLOGBOOK_SYSTEM_LOGS_BUBBLE=trueLOGBOOK_SYSTEM_LOGS_IGNORE_CHANNELS=deprecationsLOGBOOK_SYSTEM_LOGS_IGNORE_MESSAGES=Since symfony/http-foundation,Unable to create configured logger. Using emergency logger. # Audit loggingLOGBOOK_AUDIT_DISCOVER_EVENTS=falseLOGBOOK_AUDIT_EXCLUDE_EVENTS=LOGBOOK_AUDIT_IGNORE_FIELDS=updated_at,created_at,date,uri,slugLOGBOOK_AUDIT_MAX_VALUE_LENGTH=2000 # RetentionLOGBOOK_RETENTION_DAYS=365 # Ingestion modeLOGBOOK_INGEST_MODE=syncLOGBOOK_SPOOL_PATH=storage/app/logbook/spoolLOGBOOK_SPOOL_MAX_MB=256LOGBOOK_SPOOL_BACKPRESSURE=drop_oldest # Addon scheduler (flush spool)LOGBOOK_SCHEDULER_FLUSH_SPOOL_ENABLED=trueLOGBOOK_SCHEDULER_FLUSH_SPOOL_EVERY_MINUTES=60LOGBOOK_SCHEDULER_FLUSH_SPOOL_WITHOUT_OVERLAPPING=true
Short .env example (minimal working setup)
LOGBOOK_DB_CONNECTION=mysqlLOGBOOK_DB_HOST=127.0.0.1LOGBOOK_DB_PORT=3306LOGBOOK_DB_DATABASE=logbook_databaseLOGBOOK_DB_USERNAME=logbook_userLOGBOOK_DB_PASSWORD=secret LOGBOOK_INGEST_MODE=spoolLOGBOOK_SPOOL_PATH=storage/app/logbook/spool
Required variables
LOGBOOK_DB_CONNECTIONLOGBOOK_DB_HOSTLOGBOOK_DB_PORTLOGBOOK_DB_DATABASELOGBOOK_DB_USERNAMELOGBOOK_DB_PASSWORD
Optional variables and behavior
LOGBOOK_DB_SOCKET: unix socket path.LOGBOOK_DB_CHARSET: DB charset (defaultutf8mb4).LOGBOOK_DB_COLLATION: DB collation (defaultutf8mb4_unicode_ci).LOGBOOK_SYSTEM_LOGS_ENABLED: enable/disable system log capture (defaulttrue).LOGBOOK_SYSTEM_LOGS_LEVEL: minimum system level (defaultdebug).LOGBOOK_SYSTEM_LOGS_BUBBLE: Monolog bubble behavior (defaulttrue).LOGBOOK_SYSTEM_LOGS_IGNORE_CHANNELS: comma-separated ignored channels.LOGBOOK_SYSTEM_LOGS_IGNORE_MESSAGES: comma-separated ignored message fragments.LOGBOOK_AUDIT_DISCOVER_EVENTS: whentrue, merges discovered Statamic events with curated defaults.LOGBOOK_AUDIT_EXCLUDE_EVENTS: comma-separated audit event classes to exclude.LOGBOOK_AUDIT_IGNORE_FIELDS: comma-separated fields ignored in diffs.LOGBOOK_AUDIT_MAX_VALUE_LENGTH: max stored value length before truncation.LOGBOOK_RETENTION_DAYS: retention period for prune command.LOGBOOK_INGEST_MODE:sync(direct DB) orspool(local file spool + background flush).LOGBOOK_SPOOL_PATH: spool directory path.LOGBOOK_SPOOL_MAX_MB: max spool size before backpressure policy applies.LOGBOOK_SPOOL_BACKPRESSURE: currently supportsdrop_oldest.LOGBOOK_SCHEDULER_FLUSH_SPOOL_ENABLED: enable/disable addon-level scheduler for flush command (defaulttrue).LOGBOOK_SCHEDULER_FLUSH_SPOOL_EVERY_MINUTES: interval (minutes) for addon-level flush scheduling (default60).LOGBOOK_SCHEDULER_FLUSH_SPOOL_WITHOUT_OVERLAPPING: apply overlap protection for scheduled flush runs (defaulttrue).
Ingestion Modes
sync mode
- Writes system/audit rows directly to DB in request lifecycle.
spool mode
- Writes NDJSON records to local spool files in request lifecycle.
- Flushes spool files to DB in background via command/scheduler.
- If enqueue fails, Logbook falls back to direct DB insert (prevents silent drops).
Spool Flush and Background Scheduling
Flush command:
php artisan logbook:flush-spool
Common usage:
php artisan logbook:flush-spool --type=all --limit=1000php artisan logbook:flush-spool --type=system --dry-run
Command output includes:
- queued files (before/after)
- queued bytes (before/after)
- failed files (before/after)
- failure reason and failed-file destination when flush fails
Built-in addon scheduler (spool mode)
When LOGBOOK_INGEST_MODE=spool, the addon auto-registers logbook:flush-spool in Laravel Scheduler.
Default behavior:
- Runs every 60 minutes
- Uses
withoutOverlapping()by default - Can be tuned via:
LOGBOOK_SCHEDULER_FLUSH_SPOOL_ENABLEDLOGBOOK_SCHEDULER_FLUSH_SPOOL_EVERY_MINUTESLOGBOOK_SCHEDULER_FLUSH_SPOOL_WITHOUT_OVERLAPPING
Important:
- This scheduler is only active in
spoolmode. logbook:pruneis not auto-scheduled by the addon.
Application-level scheduler entry (optional override)
Add to your app scheduler (routes/console.php or Console\Kernel):
use Illuminate\Support\Facades\Schedule; Schedule::command('logbook:flush-spool --type=all --limit=1000') ->everyFiveMinutes() ->withoutOverlapping();
Short scheduler example:
Schedule::command('logbook:flush-spool')->everyFiveMinutes();
OS cron (host level, required)
* * * * * cd /absolute/path/to/your-laravel-app && php artisan schedule:run >> /dev/null 2>&1
Short cron example:
* * * * * php /absolute/path/to/your-laravel-app/artisan schedule:run >> /dev/null 2>&1
Operational Commands
- Install tables:
php artisan logbook:install - Prune old rows:
php artisan logbook:prune - Flush spool:
php artisan logbook:flush-spool
Run maintenance from Control Panel
From Utilities -> Logbook, use the header action buttons:
Prune Logs: executesphp artisan logbook:pruneFlush Spool: executesphp artisan logbook:flush-spool
Each action shows a CP toast status lifecycle:
in-progresswhen starteddoneon successfailedon command/transport error
Implementation note: CP action requests are submitted as form-encoded POST with _token to satisfy Laravel/Statamic CSRF validation.
Quick Verification
- Set required DB env vars.
- Run
php artisan config:clear. - Run
php artisan logbook:install. - Trigger a test log:
\Log::error('logbook smoke test', ['source' => 'manual-check']);
- If in spool mode, run
php artisan logbook:flush-spool --type=all. - Confirm rows appear in CP (System Logs / Audit Logs).
Test Coverage
This repository includes a lightweight PHPUnit suite focused on regression checks for critical behavior:
- Audit action normalization mapping
- Curated audit default mode (
discover_events=false) - Pulse widget filter listener singleton guard
Run tests:
./vendor/bin/phpunit --configuration phpunit.xml
What To Do / What Not To Do
Do
- Use a dedicated DB/schema for Logbook where possible.
- Keep scheduler and cron configured if using
spoolmode. - Keep
LOGBOOK_AUDIT_DISCOVER_EVENTS=falseunless you need wider coverage. - Monitor failed spool files under
storage/app/logbook/spool/failed/.
Do not
- Do not commit real credentials.
- Do not disable scheduler while using
spoolmode. - Do not point Logbook to an uncontrolled DB.
- Do not treat audit logs as editable content.
Troubleshooting
- If spool files are not created:
- run
php artisan config:clear - verify
LOGBOOK_INGEST_MODE=spool - verify spool directory write permissions for PHP-FPM user
- run
- If flush fails:
- read printed
Flush error:message - inspect
storage/app/logbook/spool/failed/... - fix root cause, requeue failed file, and run flush again
- read printed
Release and History
Known tags:
v1.5.1(current)v1.5.0v1.4.0v1.3.1v1.3.0v1.2.0v1.1.0v1.0.0
Recent changes after v1.2.0 are documented under CHANGELOG.md -> Unreleased.
Current release
- Current release:
v1.5.1 - Focus: addon-level spool flush scheduler with env-controlled interval/defaults and spool-mode activation guard.
License
MIT License. See LICENSE.
Author
Built and maintained by Emran Alhaddad
GitHub: https://github.com/emran-alhaddad
Changelog
See CHANGELOG.md for release history.