Files
html/api/paperclip-status.php
2026-04-23 21:35:02 +02:00

65 lines
3.3 KiB
PHP

<?php
// WEVIA Intent Helper : paperclip-status
// Live health check paperclip (systemd + pnpm dev + endpoints + DB + run-logs)
// Zero side-effects, read-only
header('Content-Type: application/json');
$TS = date('c');
$out = ['tool'=>'paperclip-status', 'ts'=>$TS];
// 1) Systemd unit status
$sv = @shell_exec('systemctl is-active paperclip.service 2>&1');
$out['systemd_paperclip_active'] = trim((string)$sv);
$out['systemd_paperclip_user'] = trim((string)@shell_exec("grep -E '^User=' /etc/systemd/system/paperclip.service 2>/dev/null | head -1"));
// 2) Endpoints health
$ep = [];
foreach ([['port'=>3002,'src'=>'pnpm dev next'],['port'=>3201,'src'=>'systemd'],['url'=>'https://paperclip.weval-consulting.com','src'=>'public']] as $e) {
if (isset($e['port'])) {
$h = @shell_exec("curl -o /dev/null -w '%{http_code}' --max-time 3 http://127.0.0.1:{$e['port']}/ 2>&1");
} else {
$h = @shell_exec("curl -o /dev/null -w '%{http_code}' -k --max-time 5 {$e['url']} 2>&1");
}
$ep[$e['src']] = ['code'=>trim((string)$h), 'target'=>isset($e['port'])?"127.0.0.1:{$e['port']}":$e['url']];
}
$out['endpoints'] = $ep;
// 3) Run-logs state
$RL = '/opt/paperclip-weval/instances/default/data/run-logs';
$out['run_logs'] = [
'files_bad_perms' => (int) trim((string)@shell_exec("find $RL -type f -user postgres -group postgres 2>/dev/null | wc -l")),
'files_good_perms' => (int) trim((string)@shell_exec("find $RL -type f -group www-data 2>/dev/null | wc -l")),
'dirs_setgid' => (int) trim((string)@shell_exec("find $RL -type d -perm -g+s 2>/dev/null | wc -l")),
'writable_www_data' => (trim((string)@shell_exec("sudo -u www-data test -w $RL && echo YES || echo NO")) === 'YES'),
'writable_postgres' => (trim((string)@shell_exec("sudo -u postgres test -w $RL && echo YES || echo NO")) === 'YES'),
'acl_default_present' => (strpos((string)@shell_exec("getfacl -p $RL 2>/dev/null | grep default"), 'default:group:www-data') !== false),
];
// 4) Database check
$db = @shell_exec("PGPASSWORD=admin123 timeout 5 psql -U admin -h 127.0.0.1 -d paperclip -t -c 'SELECT count(*) FROM information_schema.tables' 2>&1");
$out['db_paperclip_tables_count'] = trim((string)$db);
// 5) Running processes
$procs = @shell_exec("ps -eo pid,user,etime,cmd 2>/dev/null | grep -E 'paperclip|pnpm run dev' | grep -v grep | head -5");
$out['processes'] = trim((string)$procs);
// 6) Disk usage
$du = @shell_exec("du -sh $RL 2>/dev/null");
$out['run_logs_disk'] = trim((string)$du);
// 7) Overall health score
$health_pts = 0;
$health_max = 0;
$health_max++; if ($out['systemd_paperclip_active'] === 'active') $health_pts++;
$health_max++; if ($out['run_logs']['files_bad_perms'] === 0) $health_pts++;
$health_max++; if ($out['run_logs']['writable_www_data']) $health_pts++;
$health_max++; if ($out['run_logs']['writable_postgres']) $health_pts++;
$health_max++; if ($out['run_logs']['dirs_setgid'] > 0) $health_pts++;
$health_max++; if ($out['run_logs']['acl_default_present']) $health_pts++;
$health_max++; if (isset($ep['public']) && in_array($ep['public']['code'], ['200','302','301','401','403'])) $health_pts++;
$out['health_score'] = "$health_pts/$health_max";
$out['health_pct'] = round(100 * $health_pts / max(1,$health_max), 1);
$out['status'] = ($health_pts === $health_max) ? 'ALL_GREEN' : (($health_pts >= 5) ? 'MOSTLY_OK' : 'DEGRADED');
echo json_encode($out, JSON_PRETTY_PRINT);