Files
html/api/wevia-services-live.php
opus 2ba81195f3
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
AUTO-BACKUP 20260420-1320
2026-04-20 13:20:02 +02:00

125 lines
5.0 KiB
PHP

<?php
/**
* WEVAL Services Live Status API V96.20
*
* User WTP admin-v2: Loki affiché ROUGE 18021ms mais alert dit LIVE 3 days
* Root cause: admin-v2.html SERVICES hardcoded line 102 avec s:'up' statique
* Many services afficherait `---` sans vraie donnée
*
* This API returns TRUE live status for 23 services by probing each one.
*/
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
function probe_port($host, $port, $timeout = 2) {
$start = microtime(true);
$conn = @fsockopen($host, $port, $errno, $errstr, $timeout);
$ms = round((microtime(true) - $start) * 1000);
if ($conn) { fclose($conn); return ['up' => true, 'ms' => $ms]; }
return ['up' => false, 'ms' => $ms, 'err' => $errstr];
}
function probe_http($url, $timeout = 3) {
$start = microtime(true);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $timeout,
CURLOPT_NOBODY => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
]);
curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$ms = round((microtime(true) - $start) * 1000);
curl_close($ch);
return ['up' => ($code >= 200 && $code < 500), 'ms' => $ms, 'code' => $code];
}
function probe_systemd($unit) {
exec("systemctl is-active $unit 2>&1", $o);
$status = trim($o[0] ?? '');
return ['up' => ($status === 'active'), 'status' => $status];
}
function probe_docker($name) {
exec("docker ps --filter name=$name --format '{{.Status}}' 2>&1", $o);
$status = trim(implode(' ', $o));
$up = (strpos($status, 'Up') !== false);
return ['up' => $up, 'status' => $status ?: 'not found'];
}
// 23 services from admin-v2 — verify each
$services = [
// systemd / nginx / FPM
['n' => 'Nginx', 'p' => ':80/:443', 't' => 'system', 'probe' => 'http://localhost'],
['n' => 'Apache', 'p' => ':5890/:8443', 't' => 'system', 'probe' => 'http://localhost:5890'],
['n' => 'PHP-FPM 8.5', 'p' => ':socket', 't' => 'systemd', 'systemd' => 'php8.5-fpm'],
// LLM + APIs
['n' => 'Sovereign API', 'p' => ':4000', 't' => 'systemd', 'probe' => 'http://localhost:4000/v1/models'],
['n' => 'Ollama', 'p' => ':11434', 't' => 'systemd', 'probe' => 'http://localhost:11434/api/tags'],
['n' => 'Paperclip', 'p' => ':3100', 't' => 'systemd', 'probe' => 'http://localhost:3100'],
['n' => 'DeerFlow', 'p' => ':3002/:3003', 't' => 'systemd', 'probe' => 'http://localhost:3002'],
// Docker containers
['n' => 'Loki', 'p' => ':3100 (container)', 't' => 'docker', 'docker' => 'loki'],
['n' => 'Gitea', 'p' => ':3300', 't' => 'docker', 'docker' => 'gitea'],
['n' => 'Qdrant', 'p' => ':6333', 't' => 'docker', 'docker' => 'qdrant'],
['n' => 'Mattermost', 'p' => ':8065', 't' => 'docker', 'docker' => 'mattermost'],
['n' => 'Twenty CRM', 'p' => ':3000', 't' => 'docker', 'docker' => 'twenty'],
['n' => 'Langfuse', 'p' => ':3333', 't' => 'docker', 'docker' => 'langfuse'],
['n' => 'Prometheus', 'p' => ':9090', 't' => 'docker', 'docker' => 'prometheus'],
['n' => 'Uptime-Kuma', 'p' => ':3001', 't' => 'docker', 'docker' => 'uptime-kuma'],
['n' => 'Vaultwarden', 'p' => ':8222', 't' => 'docker', 'docker' => 'vaultwarden'],
['n' => 'Redis-Weval', 'p' => ':6379', 't' => 'docker', 'docker' => 'redis-weval'],
['n' => 'SearXNG', 'p' => ':8080', 't' => 'docker', 'docker' => 'searxng'],
['n' => 'Plausible', 'p' => ':8000', 't' => 'docker', 'docker' => 'plausible'],
['n' => 'n8n', 'p' => ':5678', 't' => 'docker', 'docker' => 'n8n'],
['n' => 'Listmonk', 'p' => ':9000', 't' => 'docker', 'docker' => 'listmonk'],
// PG + Email infra
['n' => 'PostgreSQL', 'p' => ':5432', 't' => 'systemd', 'systemd' => 'postgresql'],
// Security
['n' => 'Fail2Ban', 'p' => 'daemon', 't' => 'systemd', 'systemd' => 'fail2ban'],
];
$results = [];
$up_count = 0;
$total_ms = 0;
foreach ($services as $s) {
$r = null;
if (!empty($s['probe'])) {
$r = probe_http($s['probe']);
} elseif (!empty($s['docker'])) {
$r = probe_docker($s['docker']);
} elseif (!empty($s['systemd'])) {
$r = probe_systemd($s['systemd']);
}
$entry = [
'n' => $s['n'],
'p' => $s['p'],
't' => $s['t'],
's' => ($r && !empty($r['up'])) ? 'up' : 'down',
];
if (isset($r['ms'])) { $entry['ms'] = $r['ms']; $total_ms += $r['ms']; }
if (isset($r['status'])) $entry['detail'] = $r['status'];
if (isset($r['code'])) $entry['code'] = $r['code'];
if ($entry['s'] === 'up') $up_count++;
$results[] = $entry;
}
$total = count($results);
$uptime_pct = $total > 0 ? round(($up_count / $total) * 100, 1) : 0;
echo json_encode([
'v' => 'V96.20-services-live-opus',
'ts' => date('c'),
'total' => $total,
'up' => $up_count,
'down' => $total - $up_count,
'uptime_pct' => $uptime_pct,
'avg_latency_ms' => $total > 0 ? round($total_ms / $total) : 0,
'services' => $results,
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);