85 lines
3.2 KiB
PHP
85 lines
3.2 KiB
PHP
<?php
|
|
// DSH PREDICT API - Aggregates opus5-predictive-cache + opus-arch-predictive-heal
|
|
// Created 18avr2026 - Opus WIRE - doctrine 59 add-only, zero écrasement
|
|
// Fetchable by any dashboard (weval-technology-platform.html, wevia-training.html, etc.)
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
header('Access-Control-Allow-Origin: *');
|
|
header('Cache-Control: no-cache, must-revalidate');
|
|
|
|
$started = microtime(true);
|
|
$out = [
|
|
'ok' => true,
|
|
'module' => 'DSH-PREDICT',
|
|
'version' => '1.0-opus-18avr',
|
|
'ts' => date('c'),
|
|
'sources' => []
|
|
];
|
|
|
|
// Helper: safe internal curl
|
|
function _fetch($url, $timeout = 5) {
|
|
$ch = curl_init($url);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => $timeout,
|
|
CURLOPT_SSL_VERIFYPEER => false,
|
|
CURLOPT_SSL_VERIFYHOST => false,
|
|
]);
|
|
$r = curl_exec($ch);
|
|
$err = curl_error($ch);
|
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
if ($err || $code !== 200) return ['ok' => false, 'error' => $err ?: "http_$code"];
|
|
$j = json_decode($r, true);
|
|
return $j ?: ['ok' => false, 'raw' => substr((string)$r, 0, 300)];
|
|
}
|
|
|
|
// === LOAD prediction (regression) ===
|
|
$heal = _fetch('http://127.0.0.1/api/opus-arch-predictive-heal.php', 5);
|
|
$out['sources']['heal'] = ['ok' => true];
|
|
if (isset($heal['predicted_next_hour'])) {
|
|
$out['load'] = [
|
|
'current_metric' => $heal['metric'] ?? 'load',
|
|
'predicted_next_hour' => $heal['predicted_next_hour'] ?? null,
|
|
'threshold' => $heal['threshold'] ?? 5,
|
|
'alert' => $heal['alert'] ?? false,
|
|
'regression_slope' => $heal['regression']['slope'] ?? null,
|
|
'n_samples' => $heal['n_samples'] ?? null,
|
|
'recommended_actions' => $heal['recommended_actions'] ?? [],
|
|
];
|
|
} else {
|
|
$out['sources']['heal']['ok'] = false;
|
|
$out['sources']['heal']['error'] = $heal['error'] ?? 'no data';
|
|
}
|
|
|
|
// === CACHE predict stats ===
|
|
$cache = _fetch('http://127.0.0.1/api/opus5-predictive-cache.php', 5);
|
|
$out['sources']['cache'] = ['ok' => true];
|
|
if (isset($cache['stats'])) {
|
|
$out['cache'] = [
|
|
'gets' => $cache['stats']['gets'] ?? 0,
|
|
'hits' => $cache['stats']['hits'] ?? 0,
|
|
'misses' => $cache['stats']['misses'] ?? 0,
|
|
'hit_rate_pct' => $cache['stats']['hit_rate_pct'] ?? 0,
|
|
'patterns_count' => $cache['patterns_count'] ?? 0,
|
|
'top_patterns' => array_slice((array)($cache['top_5_patterns'] ?? []), 0, 5, true),
|
|
];
|
|
} else {
|
|
$out['sources']['cache']['ok'] = false;
|
|
$out['sources']['cache']['error'] = $cache['error'] ?? 'no data';
|
|
}
|
|
|
|
// === Summary health badge ===
|
|
$load_p = $out['load']['predicted_next_hour'] ?? 0;
|
|
$thr = $out['load']['threshold'] ?? 5;
|
|
$hit = $out['cache']['hit_rate_pct'] ?? 0;
|
|
|
|
$out['badge'] = [
|
|
'status' => ($load_p < $thr && !($out['load']['alert'] ?? false)) ? 'GREEN' : 'RED',
|
|
'label' => sprintf('Load %.2f / Cache %d%%', $load_p, $hit),
|
|
'color' => ($load_p < $thr * 0.7) ? '#10b981' : (($load_p < $thr) ? '#f59e0b' : '#ef4444'),
|
|
];
|
|
|
|
$out['elapsed_ms'] = round((microtime(true) - $started) * 1000, 1);
|
|
echo json_encode($out, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|