abra-nl/backup-monitor
Lightweight Laravel package for monitoring application backups: it checks backup status and surfaces problems early so you know your data is protected. Early-stage project with little adoption, so review the source and test carefully before relying on it in production.
Install the package with Composer, then publish its config and compiled CP assets:
composer require <vendor>/backup-monitor
php artisan vendor:publish --tag=backup-monitor --force
Open config/backup-monitor.php first. The monitor_backups array is the single source of truth: it lists which disks (by name, as defined in config/filesystems.php) should have their backups tracked.
Visit the CP page to confirm each disk is listed and shows a latest-backup timestamp. As of v1.1.0, any disk showing "Not monitored" now states the reason inline — empty monitor_backups, disk absent from the array, or a case-mismatched disk name — so this page is the first place to debug a missing disk.
First real use case: point the package at your backup disk, run your backup command once, then confirm the CP page picks up the new archive. From there, wire up alerting (see below) so a silently failing backup job doesn't go unnoticed.
Registering disks. Add the exact disk key from config/filesystems.php to monitor_backups. Keep this list in sync whenever you add a new backup target (e.g. a second S3 bucket for off-site copies).
Staleness alerting via spatie/laravel-health. The README's recommended pattern is a MaximumAgeInDays check backed by the package's backup:monitor command, scheduled alongside your backup job:
// in a service provider / health check registration
MaximumAgeInDays::make()
->days(2)
->name('Backup freshness');
Schedule backup:monitor in routes/console.php or the scheduler so the health check has fresh data to evaluate.
Hours-based SLA. Where daily granularity is too coarse, the docs now include a custom health check example that compares the newest backup's timestamp against an hours threshold — useful for high-churn apps with hourly dumps.
Layered scheduling. Run backup:run then backup:monitor in sequence (->then(...) or chained commands) so monitoring always reflects the run that just completed rather than yesterday's state.
Environment scoping. In local/CI, either leave monitor_backups empty or gate the health check behind app()->isProduction() to avoid noisy failures on machines with no backup disk.
Testing. Use Storage::fake() for the configured disk and assert the monitor command's output/exit code, so a broken monitor_backups entry fails in CI rather than in the CP page.
Backups vs backups mismatch used to fail silently; v1.1.0 surfaces it explicitly in the CP page's "Not monitored" reason. Always read that message before digging into the filesystem config.monitor_backups array is valid but invisible. Nothing errors, nothing is watched. If the CP page is blank, that's the first thing to check.php artisan vendor:publish --tag=backup-monitor --force after pulling v1.1.0 or you'll keep seeing the old UI without the new "Not monitored" explanations. Note --force will overwrite any published view/config customisations — diff your config first if you've edited it.monitor_backups, run php artisan config:clear (or config:cache in deploy) — otherwise the old array persists and the CP page keeps reporting stale results.monitor_backups contents → config/filesystems.php key → run php artisan backup:monitor manually and inspect output → check the backup disk actually contains files with the expected naming pattern.Result classes rather than forking the monitor command. Published views can be overridden for custom CP presentation if the stock "Not monitored" copy doesn't fit your team's vocabulary.How can I help you explore Laravel packages today?