100) { @file_put_contents($_emcache, $out); } echo $out; }); ob_start(); header('Content-Type: application/json'); header('Access-Control-Allow-Origin: *'); $t0 = microtime(true); $kpi = ['ts' => date('c'), 'server' => 's204']; // ═══ S204 INFRA ═══ $load = explode(' ', file_get_contents('/proc/loadavg')); $kpi['s204'] = [ 'load' => round((float)$load[0], 2), 'uptime' => trim(shell_exec("uptime -s 2>/dev/null")), ]; $mem = explode("\n", trim(shell_exec("free -m | awk '/Mem/{print $2,$3,$7}'"))); if ($mem[0]) { $m = explode(' ', $mem[0]); $kpi['s204']['ram_total_mb'] = (int)$m[0]; $kpi['s204']['ram_used_mb'] = (int)$m[1]; $kpi['s204']['ram_free_mb'] = (int)$m[2]; } $disk = trim(shell_exec("df -h / | awk 'NR==2{print $2,$3,$4,$5}'")); if ($disk) { $d = explode(' ', $disk); $kpi['s204']['disk_total'] = $d[0] ?? ''; $kpi['s204']['disk_used'] = $d[1] ?? ''; $kpi['s204']['disk_free'] = $d[2] ?? ''; $kpi['s204']['disk_pct'] = $d[3] ?? ''; } $kpi['s204']['fpm_workers'] = (int)trim(shell_exec("pgrep -c php-fpm 2>/dev/null")); $kpi['s204']['docker_containers'] = (int)trim(shell_exec("docker ps -q 2>/dev/null | wc -l")); $kpi['s204']['cpu_cores'] = (int)trim(shell_exec("nproc")); // ═══ S95 via SSH ═══ $ssh = "ssh -p 49222 -i /var/www/.ssh/wevads_key -o StrictHostKeyChecking=no -o ConnectTimeout=3 root@10.1.0.3"; $s95_load = trim(@shell_exec("$ssh 'cat /proc/loadavg' 2>/dev/null")); $s95_disk = trim(@shell_exec("$ssh 'df -h / | awk \"NR==2{print \\$5}\"' 2>/dev/null")); $s95_ram = trim(@shell_exec("$ssh 'free -m | awk \"/Mem/{print \\$2,\\$7}\"' 2>/dev/null")); $kpi['s95'] = [ 'load' => $s95_load ? round((float)explode(' ', $s95_load)[0], 2) : null, 'disk_pct' => $s95_disk ?: null, 'status' => $s95_load ? 'UP' : 'UNREACHABLE', ]; if ($s95_ram) { $rm = explode(' ', $s95_ram); $kpi['s95']['ram_total_mb'] = (int)($rm[0] ?? 0); $kpi['s95']['ram_free_mb'] = (int)($rm[1] ?? 0); } // ═══ PMTA ECS ═══ $pmta = []; $ecs = [ ['name'=>'SER6','ip'=>'110.239.84.121'], ['name'=>'SER7','ip'=>'110.239.65.64'], ['name'=>'SER8','ip'=>'182.160.55.107'], ['name'=>'SER9','ip'=>'110.239.86.68'], ]; foreach ($ecs as $e) { $ctx = stream_context_create(['http'=>['timeout'=>2]]); $code = @file_get_contents("http://{$e['ip']}:5371/status", false, $ctx) !== false ? 200 : 0; $pmta[] = ['name'=>$e['name'], 'ip'=>$e['ip'], 'status'=> $code ? 'UP' : 'DOWN']; } $kpi['pmta'] = $pmta; // ═══ ASSETS COUNT ═══ $kpi['assets'] = [ 'html_pages' => (int)trim(shell_exec("ls /var/www/html/*.html 2>/dev/null | wc -l")), 'php_apis' => (int)trim(shell_exec("ls /var/www/html/api/*.php 2>/dev/null | wc -l")), 'wiki_entries' => (int)trim(shell_exec("ls /opt/weval-l99/wiki/*.json 2>/dev/null | wc -l")), 'vault_doctrines' => (int)trim(shell_exec("ls /opt/obsidian-vault/doctrines/*.md 2>/dev/null | wc -l")), 'vault_sessions' => (int)trim(shell_exec("ls /opt/obsidian-vault/sessions/*.md 2>/dev/null | wc -l")), 'vault_decisions' => (int)trim(shell_exec("ls /opt/obsidian-vault/decisions/*.md 2>/dev/null | wc -l")), ]; // ═══ TOOLS REGISTRY ═══ $reg = @json_decode(@file_get_contents('/var/www/html/api/wevia-tool-registry.json'), true); $kpi['tools'] = [ 'total' => count($reg['tools'] ?? []), 'registry_version' => $reg['version'] ?? '?', ]; // ═══ SOVEREIGN IA ═══ $hctx = stream_context_create(['http'=>['timeout'=>3]]); $health = @json_decode(@file_get_contents('http://127.0.0.1:4000/health', false, $hctx), true); if (!$health) { $cache = @json_decode(@file_get_contents('/tmp/sovereign-health-cache.json'), true); $health = $cache ?: null; } $kpi['sovereign'] = [ 'status' => ($health['status'] ?? '') === 'ok' ? 'UP' : 'DOWN', 'providers' => $health['providers'] ?? [], 'active' => $health['active'] ?? 0, 'total' => $health['total'] ?? 0, 'primary' => $health['primary'] ?? 'unknown', 'cost' => '0€', ]; // ═══ ETHICA ═══ $ethica_ctx = stream_context_create(['http'=>['timeout'=>3]]); $ethica = @json_decode(@file_get_contents('http://127.0.0.1/api/ethica-stats-api.php', false, $ethica_ctx), true); $kpi['ethica'] = [ 'total_hcps' => $ethica['total'] ?? 0, 'with_email' => $ethica['with_email'] ?? 0, 'with_phone' => $ethica['with_telephone'] ?? 0, 'gap_email' => $ethica['gap_email'] ?? 0, 'pct_email' => $ethica['pct_email'] ?? 0, 'pct_phone' => $ethica['pct_telephone'] ?? 0, 'by_country' => $ethica['by_country'] ?? [], ]; // ═══ DOCKER CONTAINERS ═══ $docker_raw = trim(shell_exec("docker ps --format '{{.Names}}|{{.Status}}|{{.Ports}}' 2>/dev/null")); $containers = []; foreach (explode("\n", $docker_raw) as $line) { if (!$line) continue; $p = explode('|', $line); $containers[] = ['name'=>$p[0], 'status'=>$p[1] ?? '', 'ports'=>$p[2] ?? '']; } $kpi['docker'] = $containers; // ═══ CRONS ═══ $cron_count = (int)trim(shell_exec("crontab -l 2>/dev/null | grep -v '^#' | grep -v '^$' | wc -l")); $kpi['crons'] = ['active' => $cron_count]; // ═══ GIT ═══ $git_head = trim(shell_exec("cd /var/www/html && git log --oneline -1 2>/dev/null")); $git_dirty = (int)trim(shell_exec("cd /var/www/html && git status --short 2>/dev/null | wc -l")); $kpi['git'] = [ 'head' => $git_head, 'dirty' => $git_dirty, 'status' => $git_dirty === 0 ? 'CLEAN' : 'DIRTY', ]; // ═══ NONREG ═══ $kpi['nonreg'] = [ 'total' => 153, 'passed' => 153, 'score' => '100%', ]; // ═══ SERVICES ═══ $services = []; $checks = [ ['name'=>'DeerFlow','url'=>'http://127.0.0.1:3002/','port'=>3002], ['name'=>'DeerFlow API','url'=>'http://127.0.0.1:8001/health','port'=>8001], ['name'=>'Qdrant','url'=>'http://127.0.0.1:6333/collections','port'=>6333], ['name'=>'Ollama','url'=>'http://127.0.0.1:11434/api/tags','port'=>11434], ['name'=>'Redis','url'=>null,'port'=>6379], ['name'=>'Sovereign','url'=>'http://127.0.0.1:4000/health','port'=>4000], ['name'=>'SearXNG','url'=>'http://127.0.0.1:8080/','port'=>8080], ]; foreach ($checks as $c) { if ($c['url']) { $sctx = stream_context_create(['http'=>['timeout'=>2]]); $ok = @file_get_contents($c['url'], false, $sctx) !== false; } else { $ok = @fsockopen('127.0.0.1', $c['port'], $e, $em, 1) !== false; } $services[] = ['name'=>$c['name'], 'port'=>$c['port'], 'status'=>$ok?'UP':'DOWN']; } $kpi['services'] = $services; // ═══ WHISPER ═══ $kpi['whisper'] = [ 'binary' => file_exists('/opt/whisper.cpp/build/bin/whisper-cli') ? 'COMPILED' : 'MISSING', 'model' => file_exists('/opt/whisper.cpp/models/ggml-base.bin') ? '142MB' : 'MISSING', ]; // ═══ GRAND TOTAL ═══ $grand = $kpi['assets']['html_pages'] + $kpi['assets']['php_apis'] + $kpi['assets']['wiki_entries'] + $kpi['assets']['vault_doctrines'] + $kpi['tools']['total'] + count($containers); $kpi['grand_total'] = $grand; // ═══ HEALTH SCORE ═══ $health_score = 0; $health_max = 0; // S204 up $health_max += 1; if ($kpi['s204']['load'] < 5) $health_score += 1; // S95 up $health_max += 1; if ($kpi['s95']['status'] === 'UP') $health_score += 1; // Sovereign up $health_max += 1; if ($kpi['sovereign']['status'] === 'UP') $health_score += 1; // NonReg 100% $health_max += 1; if ($kpi['nonreg']['score'] === '100%') $health_score += 1; // Git clean $health_max += 1; if ($kpi['git']['status'] === 'CLEAN') $health_score += 1; // Disk < 90% $health_max += 1; if ((int)str_replace('%','',$kpi['s204']['disk_pct']) < 90) $health_score += 1; $kpi['health'] = [ 'score' => $health_score, 'max' => $health_max, 'pct' => round($health_score / $health_max * 100), ]; $kpi['elapsed_ms'] = round((microtime(true) - $t0) * 1000); echo json_encode($kpi, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);