SNMP-spezifische Konfiguration (Host, Community, Timeout, OIDs, etc.) */ private array $config; /** * Erwartet den Teilbereich "snmp" aus der allgemeinen Konfiguration (config.php). * * @param array $snmpConfig Konfiguration für die SNMP-Abfragen */ public function __construct(array $snmpConfig) { // SNMP-Konfiguration in der Instanz speichern. $this->config = $snmpConfig; } /** * Liefert den aktuellen Serverstatus zurück. * * @return array Assoziatives Array mit Statuswerten (Hostname, CPU%, RAM%, etc.) * * @throws RuntimeException wenn die SNMP-Konfiguration unvollständig ist oder Abfragen fehlschlagen */ public function getServerStatus(): array { // --- 1. Konfiguration auslesen --- $host = (string)($this->config['host'] ?? 'itfa-proj-srv.itfa-proj-dom.local'); $community = (string)($this->config['community'] ?? ''); $oids = $this->config['oids'] ?? []; $timeout = (int)($this->config['timeout'] ?? 1) * 1_000_000; // in Mikrosekunden $retries = (int)($this->config['retries'] ?? 1); // --- Prüfungen für essentielle Konfig-Werte --- if ($host === '') { throw new RuntimeException('SNMP-Konfiguration ist unvollständig (host fehlt).'); } if ($community === '') { throw new RuntimeException('SNMP-Konfiguration ist unvollständig (community fehlt).'); } if (empty($oids)) { throw new RuntimeException('SNMP-Konfiguration ist unvollständig (oids fehlen).'); } // Helper-Funktion zum Bereinigen von SNMP-Antworten (z.B. "INTEGER: 123" -> 123) $cleanSnmpValue = fn($v) => (int)filter_var($v, FILTER_SANITIZE_NUMBER_INT); // --- 2. Uptime abfragen (war vorher nicht implementiert) --- $uptimeResult = snmpget($host, $community, $oids['uptime'], $timeout, $retries); if ($uptimeResult === false) { throw new RuntimeException("SNMP Uptime GET fehlgeschlagen."); } // Uptime (timeticks) in ein lesbares Format umwandeln (optional, hier als String) // Format ist oft "Timeticks: (12345678) 1 day, 10:17:36.78" // Wir extrahieren den Teil in Klammern (Hundertstelsekunden) preg_match('/\((.*?)\)/', $uptimeResult, $matches); $uptimeTicks = (int)($matches[1] ?? 0); $uptimeSeconds = $uptimeTicks / 100; $uptimeFormatted = sprintf( '%d Tage, %02d:%02d:%02d', floor($uptimeSeconds / 86400), floor(($uptimeSeconds % 86400) / 3600), floor(($uptimeSeconds % 3600) / 60), $uptimeSeconds % 60 ); // --- 3. CPU --- $cpuValues = snmpwalk($host, $community, $oids['cpu_table'], $timeout, $retries); if (!is_array($cpuValues) || empty($cpuValues)) { throw new RuntimeException("SNMP CPU WALK fehlgeschlagen."); } $cpuValues = array_map($cleanSnmpValue, $cpuValues); $cpuAvg = array_sum($cpuValues) / count($cpuValues); // --- 4. Memory --- $memTotalResult = snmpget($host, $community, $oids['mem_size'], $timeout, $retries); if($memTotalResult === false) { throw new RuntimeException("SNMP MemTotal GET fehlgeschlagen."); } // memTotal in Bytes berechnen (korrigierte Reihenfolge von filter/cast) $memTotal = $cleanSnmpValue($memTotalResult) * 1024; // KB -> Bytes // Storage-Tabelle (RAM + Disks) $descr = snmpwalk($host, $community, $oids['storage_descr'], $timeout, $retries); $units = snmpwalk($host, $community, $oids['storage_units'], $timeout, $retries); $size = snmpwalk($host, $community, $oids['storage_size'], $timeout, $retries); $used = snmpwalk($host, $community, $oids['storage_used'], $timeout, $retries); if ($descr === false || $units === false || $size === false || $used === false) { throw new RuntimeException("SNMP Storage WALK fehlgeschlagen."); } // Werte bereinigen // Die SNMP-Antwort enthält "STRING: " und Anführungszeichen, die wir entfernen müssen. $descr = array_map(fn($v) => trim(str_ireplace('STRING:', '', $v), ' "'), $descr); $units = array_map($cleanSnmpValue, $units); // Ints $size = array_map($cleanSnmpValue, $size); // Ints $used = array_map($cleanSnmpValue, $used); // Ints // RAM $ramIndex = array_search("Physical Memory", $descr); if ($ramIndex === false) { throw new RuntimeException("Konnte 'Physical Memory' in der SNMP Storage-Tabelle nicht finden."); } $ramUsedBytes = $units[$ramIndex] * $used[$ramIndex]; $ramPercent = ($memTotal > 0) ? ($ramUsedBytes / $memTotal) * 100 : 0; // --- 5. Disk C: --- $cIndex = false; foreach ($descr as $index => $description) { // str_starts_with prüft, ob der String mit C:\ beginnt if (str_starts_with($description, 'C:\\')) { $cIndex = $index; break; } } if ($cIndex === false) { throw new RuntimeException("Konnte Laufwerk 'C:\' in der SNMP Storage-Tabelle nicht finden."); } $cUsed = $units[$cIndex] * $used[$cIndex]; $cTotal = $units[$cIndex] * $size[$cIndex]; $diskCPercent = ($cTotal > 0) ? ($cUsed / $cTotal) * 100 : 0; // --- 6. Status-Array zusammenbauen --- $status = [ 'hostname' => $host, 'os' => 'Windows Server 2025 Datacenter', // TODO: OS dynamisch abfragen 'uptime' => $uptimeFormatted, // Fehlende Variable hinzugefügt 'cpu_usage' => round($cpuAvg), 'memory_usage' => round($ramPercent), 'disk_usage_c' => round($diskCPercent), 'last_update' => date('d.m.Y H:i:s'), ]; return $status; } }