| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- <?php
- declare(strict_types=1);
- namespace App\Services;
- use Illuminate\Support\Facades\Cache;
- use Throwable;
- class DiskSpaceMonitor
- {
- private const CACHE_KEY = 'disk_space_monitor.status';
- /**
- * @return array{warning: bool, free_bytes: int|null, threshold_bytes: int, path: string, checked_at: string|null}
- */
- public function status(): array
- {
- try {
- return Cache::remember(
- self::CACHE_KEY,
- now()->addSeconds($this->cacheSeconds()),
- fn (): array => $this->freshStatus()
- );
- } catch (Throwable) {
- return $this->freshStatus();
- }
- }
- public function formatBytes(?int $bytes): string
- {
- if ($bytes === null) {
- return 'неизвестно';
- }
- $units = ['Б', 'КБ', 'МБ', 'ГБ', 'ТБ'];
- $value = (float) $bytes;
- $unitIndex = 0;
- while ($value >= 1024 && $unitIndex < count($units) - 1) {
- $value /= 1024;
- $unitIndex++;
- }
- return sprintf('%s %s', round($value, $unitIndex === 0 ? 0 : 2), $units[$unitIndex]);
- }
- /**
- * @return array{warning: bool, free_bytes: int|null, threshold_bytes: int, path: string, checked_at: string|null}
- */
- private function freshStatus(): array
- {
- $path = $this->path();
- $thresholdBytes = $this->thresholdBytes();
- $freeBytes = @disk_free_space($path);
- $freeBytes = $freeBytes === false ? null : (int) $freeBytes;
- return [
- 'warning' => $freeBytes !== null && $freeBytes < $thresholdBytes,
- 'free_bytes' => $freeBytes,
- 'threshold_bytes' => $thresholdBytes,
- 'path' => $path,
- 'checked_at' => now()->toDateTimeString(),
- ];
- }
- private function path(): string
- {
- return (string) config('app.disk_space_warning.path', storage_path());
- }
- private function thresholdBytes(): int
- {
- return max(0, (int) config('app.disk_space_warning.threshold_bytes', 1024 * 1024 * 1024));
- }
- private function cacheSeconds(): int
- {
- return max(1, (int) config('app.disk_space_warning.cache_seconds', 300));
- }
- }
|