151 lines
5.3 KiB
PHP
151 lines
5.3 KiB
PHP
<?php
|
|
/**
|
|
* WEVIA FIABILITY ENGINE v1.0
|
|
* Uses sovereign LLMs to analyze infrastructure health
|
|
* Runs HTTP checks on ALL pages, feeds results to LLM for diagnosis
|
|
* Called by Director cron or manually
|
|
*
|
|
* GET ?run → Full fiability scan
|
|
* GET ?quick → Quick critical-only scan
|
|
* GET ?report → Last report
|
|
* GET ?urls=N → Scan N random pages
|
|
*/
|
|
header("Content-Type: application/json; charset=utf-8");
|
|
header("Access-Control-Allow-Origin: *");
|
|
|
|
require_once "/opt/wevia-brain/wevia-master-router.php";
|
|
|
|
define("FIA_REPORT_FILE", "/var/log/wevia-director/fiability-report.json");
|
|
define("FIA_LOG", "/var/log/wevia-director/fiability.log");
|
|
|
|
// ═══ ROUTING ═══
|
|
if (isset($_GET["report"])) {
|
|
echo @file_get_contents(FIA_REPORT_FILE) ?: json_encode(["status" => "no_report"]);
|
|
exit;
|
|
}
|
|
|
|
$mode = "quick";
|
|
if (isset($_GET["run"])) $mode = "full";
|
|
if (isset($_GET["quick"])) $mode = "quick";
|
|
$maxUrls = intval($_GET["urls"] ?? ($mode === "full" ? 50 : 15));
|
|
|
|
$t0 = microtime(true);
|
|
|
|
// ═══ LOAD REGISTRY ═══
|
|
$registry = json_decode(file_get_contents("/opt/wevia-brain/wevia-director-registry.json"), true);
|
|
$criticalUrls = $registry["health_checks"]["critical_urls"] ?? [];
|
|
$subdomains = $registry["health_checks"]["subdomain_checks"] ?? [];
|
|
|
|
// ═══ SCAN ALL CRITICAL URLS ═══
|
|
$results = [];
|
|
$failed = [];
|
|
$slow = [];
|
|
|
|
foreach (array_slice($criticalUrls, 0, $maxUrls) as $check) {
|
|
$url = $check["url"];
|
|
$start = microtime(true);
|
|
$ch = curl_init($url);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10,
|
|
CURLOPT_FOLLOWLOCATION => true, CURLOPT_SSL_VERIFYPEER => false,
|
|
CURLOPT_HEADER => true, CURLOPT_NOBODY => false,
|
|
]);
|
|
$resp = curl_exec($ch);
|
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
$time = round((microtime(true) - $start) * 1000);
|
|
$size = curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
|
|
|
|
// Check for JS errors in HTML
|
|
$hasJsError = false;
|
|
$hasEmptyBody = ($size < 20);
|
|
$hasSpaWrapper = (strpos($resp, "Enterprise Digital Transformation") !== false && strpos($resp, basename($url)) === false);
|
|
|
|
$status = "ok";
|
|
if ($code >= 400) $status = "error";
|
|
elseif ($hasEmptyBody) $status = "empty";
|
|
elseif ($hasSpaWrapper) $status = "spa_wrapped";
|
|
elseif ($time > 5000) $status = "slow";
|
|
|
|
$entry = [
|
|
"url" => basename(parse_url($url, PHP_URL_PATH)),
|
|
"full_url" => $url,
|
|
"code" => $code,
|
|
"time_ms" => $time,
|
|
"size" => $size,
|
|
"status" => $status,
|
|
];
|
|
$results[] = $entry;
|
|
|
|
if ($status !== "ok") $failed[] = $entry;
|
|
if ($time > 3000) $slow[] = $entry;
|
|
}
|
|
|
|
// ═══ SCAN SUBDOMAINS ═══
|
|
$subResults = [];
|
|
foreach ($subdomains as $sub) {
|
|
$start = microtime(true);
|
|
$ch = curl_init("https://$sub/");
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8,
|
|
CURLOPT_FOLLOWLOCATION => true, CURLOPT_SSL_VERIFYPEER => false,
|
|
CURLOPT_NOBODY => true,
|
|
]);
|
|
curl_exec($ch);
|
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
$time = round((microtime(true) - $start) * 1000);
|
|
$subResults[] = ["sub" => $sub, "code" => $code, "time_ms" => $time, "ok" => ($code >= 200 && $code < 400)];
|
|
}
|
|
|
|
// ═══ ASK SOVEREIGN LLM TO ANALYZE ═══
|
|
$summary = [
|
|
"total_urls" => count($results),
|
|
"ok" => count(array_filter($results, fn($r) => $r["status"] === "ok")),
|
|
"failed" => $failed,
|
|
"slow" => $slow,
|
|
"subdomains_ok" => count(array_filter($subResults, fn($r) => $r["ok"])),
|
|
"subdomains_total" => count($subResults),
|
|
"subdomains_failed" => array_values(array_filter($subResults, fn($r) => !$r["ok"])),
|
|
];
|
|
|
|
$llmAnalysis = "";
|
|
if (!empty($failed) || !empty($slow)) {
|
|
$prompt = "Tu es WEVIA Director, agent DevOps autonome. Analyse ce rapport de fiabilité et donne un diagnostic concis avec actions prioritaires:
|
|
|
|
"
|
|
. "URLs OK: {$summary["ok"]}/{$summary["total_urls"]}
|
|
"
|
|
. "Failed:
|
|
" . json_encode($failed, JSON_PRETTY_PRINT) . "
|
|
"
|
|
. "Slow (>3s):
|
|
" . json_encode($slow, JSON_PRETTY_PRINT) . "
|
|
"
|
|
. "Subdomains: {$summary["subdomains_ok"]}/{$summary["subdomains_total"]}
|
|
"
|
|
. "
|
|
Réponds en JSON: {\"diagnosis\": \"...\", \"priority_actions\": [...], \"risk_level\": \"ok|medium|high|critical\"}";
|
|
|
|
// DISABLED: $llmResult = mr_route($prompt, "Tu es un expert DevOps. Réponds UNIQUEMENT en JSON valide.");
|
|
// DISABLED: $llmAnalysis = $llmResult["content"] ?? "";
|
|
}
|
|
|
|
// ═══ BUILD REPORT ═══
|
|
$report = [
|
|
"timestamp" => date("c"),
|
|
"mode" => $mode,
|
|
"duration_ms" => round((microtime(true) - $t0) * 1000),
|
|
"summary" => $summary,
|
|
"llm_analysis" => $llmAnalysis,
|
|
"llm_provider" => $llmResult["provider"] ?? "none",
|
|
"results" => $results,
|
|
"subdomains" => $subResults,
|
|
"score" => round(($summary["ok"] / max($summary["total_urls"], 1)) * 100),
|
|
];
|
|
|
|
file_put_contents(FIA_REPORT_FILE, json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
|
$logLine = date("Y-m-d H:i:s") . " | score={$report["score"]}% | {$summary["ok"]}/{$summary["total_urls"]} OK | failed=" . count($failed) . " | " . round($report["duration_ms"]/1000,1) . "s
|
|
";
|
|
file_put_contents(FIA_LOG, $logLine, FILE_APPEND);
|
|
|
|
echo json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|