spatie/laravel-disk-monitor
Monitor Laravel filesystem disks by recording daily metrics (currently: file count per disk). Includes migrations, config for disk names, and a scheduled command to capture usage over time for reporting and alerts.
Installation:
composer require spatie/laravel-disk-monitor
Publish the config file:
php artisan vendor:publish --provider="Spatie\DiskMonitor\DiskMonitorServiceProvider"
Configuration:
Edit config/disk-monitor.php to specify which disks to monitor (e.g., local, s3). Defaults to monitoring all configured disks in config/filesystems.php.
First Use Case: Run the monitor command to fetch disk metrics:
php artisan disk:monitor
Outputs a JSON array with disk names and their file counts (e.g., {"local": 1234, "s3": 5678}).
Viewing Results:
Metrics are stored in storage/disk-monitor.json by default. Access via:
$metrics = Spatie\DiskMonitor\Facades\DiskMonitor::getMetrics();
Scheduled Monitoring:
Add a cron job to app/Console/Kernel.php:
protected function schedule(Schedule $schedule)
{
$schedule->command('disk:monitor')->hourly();
}
Logs metrics to storage/disk-monitor.json automatically.
Custom Metrics:
Extend the Spatie\DiskMonitor\DiskMonitor class to track additional metrics (e.g., disk space):
use Spatie\DiskMonitor\DiskMonitor as BaseMonitor;
class CustomDiskMonitor extends BaseMonitor
{
public function getMetrics()
{
$metrics = parent::getMetrics();
foreach ($metrics as $disk => $files) {
$metrics[$disk]['free_space'] = Storage::disk($disk)->freeSpace();
}
return $metrics;
}
}
Bind the custom class in AppServiceProvider:
$this->app->bind('disk-monitor', function () {
return new CustomDiskMonitor();
});
Integration with Monitoring Tools:
Push metrics to external services (e.g., Datadog, Prometheus) by hooking into the disk.monitored event:
// In AppServiceProvider
DiskMonitor::monitored(function ($metrics) {
// Send to external service
});
Conditional Monitoring: Dynamically enable/disable monitoring for specific disks:
DiskMonitor::monitor(['local', 's3']); // Only monitor these disks
$metrics = DiskMonitor::getMetrics(); // Returns array of disk names => file counts
DiskMonitor::clearMetrics(); // Deletes storage/disk-monitor.json
Performance on Large Disks:
->withoutVisibility() to exclude hidden files or filter by extension:
DiskMonitor::monitor(['local'], function ($disk) {
return $disk->files()->where(function ($file) {
return str_ends_with($file->path(), '.log');
});
});
Concurrency Issues:
disk:monitor concurrently in production (e.g., via multiple cron jobs). Use a lock (e.g., laravel-shift/lock) if needed.Filesystem Permissions:
storage/) is writable for the web server user. Errors may occur if storage/disk-monitor.json can’t be written.Outdated Metrics:
monitored event to push updates dynamically.Log Errors:
Enable debug mode in config/disk-monitor.php to log issues:
'debug' => env('DISK_MONITOR_DEBUG', false),
Check storage/logs/laravel.log for errors during monitoring.
Verify Disk Configuration:
Ensure disks in config/filesystems.php are correctly configured. Test connectivity manually:
Storage::disk('s3')->exists('test.txt'); // Should return false (file doesn’t exist, but tests connection)
Exclude Directories:
Skip monitoring specific directories (e.g., node_modules):
DiskMonitor::monitor(['local'], function ($disk) {
return $disk->files()->reject(function ($file) {
return str_contains($file->path(), 'node_modules');
});
});
Human-Readable Output: Format metrics for CLI output:
$metrics = DiskMonitor::getMetrics();
foreach ($metrics as $disk => $count) {
echo "Disk {$disk}: {$count} files\n";
}
Testing: Mock the monitor in tests:
$monitor = Mockery::mock(Spatie\DiskMonitor\DiskMonitor::class);
$monitor->shouldReceive('getMetrics')->andReturn(['local' => 100]);
$this->app->instance(Spatie\DiskMonitor\DiskMonitor::class, $monitor);
Custom Storage Path:
Change the storage path in config/disk-monitor.php:
'storage_path' => storage_path('app/disk-metrics.json'),
Laravel 8+ Optimization:
Use Laravel’s FilesystemManager directly for better performance if extending:
$filesystem = app(\Illuminate\Contracts\Filesystem\Filesystem::class);
$count = $filesystem->disk('local')->count();
How can I help you explore Laravel packages today?