<?php namespace App\Sensor; use App\Sensor; use App\SensorConfig; use App\ServerInfo; use App\Report; use App\Status; use Illuminate\Database\Eloquent\Collection as DatabaseCollection; use Illuminate\Support\Collection; /** * Monitor disk usage * * @author tibo */ class Disks implements Sensor { public function config(): SensorConfig { return new SensorConfig("disks", "disks"); } const REGEXP = "/\\n([A-z\/0-9:\\-\\.]+)\s*([0-9]+)\s*([0-9]+)\s*([0-9]+)\s*([0-9]+)%\s*([A-z\/0-9]+)/"; public function analyze(DatabaseCollection $records, ServerInfo $serverinfo): Report { $report = (new Report())->setTitle("Partitions"); $record = $records->last(); $partitions = $this->parse($record->data); $report->setHTML(view("sensor.disks", ["partitions" => $partitions])); return $report->setStatus(Status::max($partitions)); } /** * * @param string $string * @return Collection<Partition> */ public function parse(string $string) : Collection { $values = array(); preg_match_all(self::REGEXP, $string, $values); $partitions = new Collection(); $count = count($values[1]); for ($i = 0; $i < $count; $i++) { $fs = $values[1][$i]; if ($this->shouldSkip($fs)) { continue; } $partition = new Partition(); $partition->filesystem = $fs; $partition->blocks = $values[2][$i]; $partition->used = $values[3][$i]; $partition->mounted = $values[6][$i]; $partitions->push($partition); } return $partitions; } public function fromRecord($record) : Collection { $partitions = $this->parse($record->data); $time = $record->time; foreach ($partitions as $partition) { $partition->time = $time; } return $partitions; } const SKIP_FS = ["none", "tmpfs", "shm", "udev", "overlay", '/dev/loop', "devfs"]; public function shouldSkip(string $fs) : bool { foreach (self::SKIP_FS as $should_skip) { if ($this->startsWith($should_skip, $fs)) { return true; } } return false; } public function startsWith(string $needle, string $haystack) : bool { return substr($haystack, 0, strlen($needle)) === $needle; } }