$ts, 'generator' => 'infra-live.php v1.0']; // 1. Load average / CPU / disk $load = @file_get_contents('/proc/loadavg'); list($l1, $l5, $l15) = array_pad(explode(' ', $load), 3, 0); $mem_info = @file_get_contents('/proc/meminfo'); preg_match('/MemTotal:\s+(\d+)/', $mem_info, $mt); preg_match('/MemAvailable:\s+(\d+)/', $mem_info, $ma); $mem_total = (int)($mt[1] ?? 0); $mem_avail = (int)($ma[1] ?? 0); $mem_used = $mem_total - $mem_avail; $mem_pct = $mem_total ? round(100 * $mem_used / $mem_total, 1) : 0; $disk = @shell_exec("df / | tail -1 | awk '{print $3,$4,$5}'"); list($du, $df, $dp) = array_pad(explode(' ', trim($disk)), 3, '?'); // 2. FPM processes $fpm = trim(@shell_exec("pgrep -c '^php-fpm'") ?? '0'); // 3. Docker containers $docker = @shell_exec("docker ps --format '{{.Names}}|{{.Status}}|{{.Ports}}' 2>&1"); $containers = []; foreach (array_filter(explode("\n", trim($docker))) as $line) { $parts = explode('|', $line, 3); if (count($parts) >= 2) $containers[] = ['name' => $parts[0], 'status' => $parts[1], 'ports' => $parts[2] ?? '']; } // 4. Systemd services critical $services = ['nginx','php8.4-fpm','postgresql','redis-server','ollama','paperclip','deerflow','deerflow-web','deepseek-web','sovereign-api','wevia-llm-worker','wevia-webchat','wevia-async-worker','wevads-relay']; $svc_status = []; foreach ($services as $s) { $st = trim(@shell_exec("systemctl is-active $s 2>&1")); $svc_status[$s] = $st; } // 5. Key ports $ports = [80,443,5432,6333,11434,5678,8080,8443,4000,5890,3100]; $port_status = []; foreach ($ports as $p) { $listen = (int)trim(@shell_exec("ss -tln 2>/dev/null | grep -c ':$p ' ")); $port_status[(string)$p] = $listen > 0; } // 6. Cloudflare status $cf_zone = trim(@shell_exec("curl -sk --max-time 3 http://127.0.0.1/cf-origin-check.php 2>&1 | head -c 100")); // 7. Network I/O $net = @file_get_contents('/proc/net/dev'); $rx_bytes = 0; $tx_bytes = 0; foreach (explode("\n", $net) as $line) { if (preg_match('/^\s*(eth|ens|en)\w+:\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+(\d+)/', $line, $m)) { $rx_bytes += (int)$m[2]; $tx_bytes += (int)$m[3]; } } // 8. Nginx reqs (last min via access.log tail) $nginx_reqs = (int)trim(@shell_exec("tail -1000 /var/log/nginx/access.log 2>&1 | awk '{print $4}' | sort -u | wc -l")); $out['system'] = [ 'load1' => (float)$l1, 'load5' => (float)$l5, 'load15' => (float)$l15, 'mem_used_kb' => $mem_used, 'mem_total_kb' => $mem_total, 'mem_pct' => $mem_pct, 'disk_used' => $du, 'disk_free' => $df, 'disk_pct' => $dp, 'fpm_processes' => (int)$fpm, 'uptime_s' => (int)trim(@shell_exec("awk '{print int(\$1)}' /proc/uptime")), ]; $out['docker'] = [ 'count' => count($containers), 'containers' => $containers, ]; $out['services'] = $svc_status; $out['ports'] = $port_status; $out['network'] = [ 'rx_bytes' => $rx_bytes, 'tx_bytes' => $tx_bytes, ]; $out['nginx'] = ['unique_ips_last_1k' => $nginx_reqs]; echo json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);