@disk_total_space('/') ?: null, 'root_free_bytes' => @disk_free_space('/') ?: null, ]; $disk['root_used_bytes'] = ($disk['root_total_bytes'] && $disk['root_free_bytes']) ? ($disk['root_total_bytes'] - $disk['root_free_bytes']) : null; $disk['root_used_pct'] = $disk['root_total_bytes'] ? round($disk['root_used_bytes'] / $disk['root_total_bytes'] * 100, 2) : null; $services = [ 'nginx' => serviceStatus(['nginx']), 'apache' => serviceStatus(['apache2', 'httpd']), 'mysql' => serviceStatus(['mariadb', 'mysqld', 'mysql']), 'php-fpm' => serviceStatus(['php-fpm', 'php8.3-fpm', 'php8.2-fpm', 'php8.1-fpm', 'plesk-php80-fpm']), 'postfix' => serviceStatus(['postfix']), 'dovecot' => serviceStatus(['dovecot']), 'named' => serviceStatus(['named', 'bind9']), ]; $mem = parseMemInfo(); $cpus = cpuCount(); $upt = uptimeSeconds(); // Output $out = [ 'host' => [ 'hostname' => gethostname(), 'os' => php_uname(), 'php' => PHP_VERSION, 'sapi' => php_sapi_name(), ], 'uptime_seconds' => $upt, 'load_avg' => $load ? [ '1min' => $load[0], '5min' => $load[1], '15min' => $load[2], 'per_cpu_1min' => ($cpus && $load) ? round($load[0] / $cpus, 2) : null, ] : null, 'cpu' => [ 'cores' => $cpus, ], 'memory' => $mem, 'disk' => [ 'root_total_bytes' => $disk['root_total_bytes'], 'root_used_bytes' => $disk['root_used_bytes'], 'root_free_bytes' => $disk['root_free_bytes'], 'root_used_pct' => $disk['root_used_pct'], 'root_total_h' => $disk['root_total_bytes'] ? bytesFmt($disk['root_total_bytes']) : null, 'root_used_h' => $disk['root_used_bytes'] ? bytesFmt($disk['root_used_bytes']) : null, 'root_free_h' => $disk['root_free_bytes'] ? bytesFmt($disk['root_free_bytes']) : null, ], 'services' => $services ]; header('Content-Type: application/json; charset=utf-8'); echo json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL; } else { header('Location: http://www.informer.eu/'); } function sh($cmd) { // Run shell command safely; return trimmed string or null $out = @shell_exec($cmd . ' 2>/dev/null'); return $out !== null ? trim($out) : null; } function parseMemInfo() { $meminfo = @file_get_contents('/proc/meminfo'); if (!$meminfo) return null; $data = []; foreach (explode("\n", $meminfo) as $line) { if (preg_match('/^(\w+):\s+(\d+)\s+kB$/', trim($line), $m)) { $data[$m[1]] = (int)$m[2] * 1024; // bytes } } if (!$data) return null; // Prefer MemAvailable if present $total = $data['MemTotal'] ?? 0; $free = $data['MemFree'] ?? 0; $buff = $data['Buffers'] ?? 0; $cached= $data['Cached'] ?? 0; $avail = $data['MemAvailable'] ?? ($free + $buff + $cached); $used = max(0, $total - $avail); return [ 'total_bytes' => $total, 'used_bytes' => $used, 'available_bytes' => $avail, 'free_bytes' => $free, 'buffers_bytes' => $buff, 'cached_bytes' => $cached, 'used_pct' => $total > 0 ? round($used / $total * 100, 2) : null, ]; } function cpuCount() { $n = (int)sh('nproc'); if ($n > 0) return $n; $cpuinfo = @file_get_contents('/proc/cpuinfo'); if ($cpuinfo && preg_match_all('/^processor\s+:\s+\d+/m', $cpuinfo, $m)) return count($m[0]); return null; } function uptimeSeconds() { $s = @file_get_contents('/proc/uptime'); if ($s && preg_match('/^([\d\.]+)/', $s, $m)) return (int)floatval($m[1]); // fallback $u = sh('cut -d. -f1 /proc/uptime'); // still /proc but simpler return $u !== null ? (int)$u : null; } function serviceStatus($nameCandidates) { // Try systemctl, else service foreach ((array)$nameCandidates as $name) { $out = sh("systemctl is-active $name"); if ($out) return $out; // active|inactive|failed|unknown $out = sh("service $name status"); if ($out) { if (stripos($out, 'running') !== false) return 'active'; if (stripos($out, 'dead') !== false || stripos($out, 'stopped') !== false) return 'inactive'; return 'unknown'; } } return 'unknown'; } function bytesFmt($b) { $units = ['B','KB','MB','GB','TB','PB']; $i = 0; $v = max(0, (float)$b); while ($v >= 1024 && $i < count($units)-1) { $v /= 1024; $i++; } return round($v, 2) . ' ' . $units[$i]; }