getset('metrics:mqtt:count', 0) ?? 0); } catch (\Throwable) { // counter unavailable — record 0 } Metric::create([ 'sampled_at' => now(), 'mqtt_messages' => $messages, 'cpu_load' => $this->cpuLoad(), 'mem_used_pct' => $this->memUsedPct(), ]); Metric::where('sampled_at', '<', now()->subDay())->delete(); return self::SUCCESS; } private function cpuLoad(): ?float { $raw = @file_get_contents('/proc/loadavg'); return $raw ? (float) explode(' ', $raw)[0] : null; } private function memUsedPct(): ?int { $raw = @file_get_contents('/proc/meminfo'); if (! $raw) { return null; } preg_match('/MemTotal:\s+(\d+)/', $raw, $total); preg_match('/MemAvailable:\s+(\d+)/', $raw, $available); if (empty($total[1]) || ! isset($available[1])) { return null; } return (int) round((((int) $total[1] - (int) $available[1]) / (int) $total[1]) * 100); } }