mirror of
https://github.com/myronblair/jarvis
synced 2026-06-30 17:50:23 -05:00
Fix DO server offline: read /proc directly instead of SSH loopback
This commit is contained in:
+67
-67
@@ -1,77 +1,77 @@
|
|||||||
<?php
|
<?php
|
||||||
// Digital Ocean server monitoring via SSH
|
// Digital Ocean server monitoring — read local /proc directly (no SSH loopback)
|
||||||
|
|
||||||
function sshCommand(string $cmd): string {
|
// CPU usage (sample over 200ms)
|
||||||
$sshCmd = sprintf(
|
function getCpuPct(): float {
|
||||||
'sshpass -p %s ssh -o StrictHostKeyChecking=no -o ConnectTimeout=8 %s@%s %s 2>/dev/null',
|
$s1 = file_get_contents("/proc/stat");
|
||||||
escapeshellarg(DO_SSH_PASS),
|
usleep(200000);
|
||||||
escapeshellarg(DO_SSH_USER),
|
$s2 = file_get_contents("/proc/stat");
|
||||||
escapeshellarg(DO_SERVER_IP),
|
preg_match("/^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/m", $s1, $m1);
|
||||||
escapeshellarg($cmd)
|
preg_match("/^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/m", $s2, $m2);
|
||||||
);
|
$idle1 = $m1[4]; $total1 = $m1[1]+$m1[2]+$m1[3]+$m1[4];
|
||||||
return shell_exec($sshCmd) ?? '';
|
$idle2 = $m2[4]; $total2 = $m2[1]+$m2[2]+$m2[3]+$m2[4];
|
||||||
|
$dt = $total2 - $total1;
|
||||||
|
return $dt > 0 ? round((1 - ($idle2 - $idle1) / $dt) * 100, 1) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if sshpass is available
|
$memLines = [];
|
||||||
$hasSshpass = trim(shell_exec('which sshpass 2>/dev/null'));
|
foreach (file("/proc/meminfo") as $l) {
|
||||||
if (!$hasSshpass) {
|
[$k, $v] = explode(":", $l, 2) + [null, null];
|
||||||
echo json_encode([
|
if ($k) $memLines[trim($k)] = (int)trim($v);
|
||||||
'error' => 'sshpass not installed on Jarvis server. Run: sudo apt-get install sshpass',
|
|
||||||
'ip' => DO_SERVER_IP,
|
|
||||||
]);
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
$memTotal = $memLines["MemTotal"] ?? 0;
|
||||||
// Gather DO server stats in one SSH session
|
$memFree = $memLines["MemAvailable"] ?? 0;
|
||||||
$statsRaw = sshCommand("echo CPU:$(grep 'cpu ' /proc/stat | awk '{u=\$2+\$4; t=\$2+\$3+\$4+\$5; print u/t*100}');echo MEM_TOTAL:\$(grep MemTotal /proc/meminfo | awk '{print \$2}');echo MEM_FREE:\$(grep MemAvailable /proc/meminfo | awk '{print \$2}');echo UPTIME:\$(cat /proc/uptime | awk '{print int(\$1)}');echo DISK_USED:\$(df / | tail -1 | awk '{print \$5}');echo LOAD:\$(cat /proc/loadavg | awk '{print \$1}')");
|
|
||||||
|
|
||||||
$stats = [];
|
|
||||||
foreach (explode("\n", trim($statsRaw)) as $line) {
|
|
||||||
[$key, $val] = explode(':', $line, 2) + [null, null];
|
|
||||||
if ($key) $stats[$key] = trim($val ?? '');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get running services on DO
|
|
||||||
$services = sshCommand("systemctl is-active lsphp85 lshttpd nginx apache2 mysql mariadb php8.1-fpm 2>/dev/null | paste <(echo -e 'lsphp85\nlshttpd\nnginx\napache2\nmysql\nmariadb\nphp8.1-fpm') - | awk '{print \$1\":\"\$2}'");
|
|
||||||
$svcMap = [];
|
|
||||||
foreach (explode("\n", trim($services)) as $line) {
|
|
||||||
if (!$line) continue;
|
|
||||||
[$name, $status] = explode(':', $line, 2) + [null, null];
|
|
||||||
if ($name && $status && trim($status) === 'active') {
|
|
||||||
$svcMap[trim($name)] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get disk usage per site
|
|
||||||
$siteDisk = sshCommand("du -sh /home/*/public_html 2>/dev/null | sort -h");
|
|
||||||
$sites = [];
|
|
||||||
foreach (explode("\n", trim($siteDisk)) as $line) {
|
|
||||||
if (preg_match('/^([\d.]+\w)\s+\/home\/([^\/]+)/', $line, $m)) {
|
|
||||||
$sites[$m[2]] = $m[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$cpuPct = isset($stats['CPU']) ? round((float)$stats['CPU'], 1) : null;
|
|
||||||
$memTotal = (int)($stats['MEM_TOTAL'] ?? 0);
|
|
||||||
$memFree = (int)($stats['MEM_FREE'] ?? 0);
|
|
||||||
$memUsed = $memTotal - $memFree;
|
$memUsed = $memTotal - $memFree;
|
||||||
$uptimeSec = (int)($stats['UPTIME'] ?? 0);
|
|
||||||
$uptimeDays = intdiv($uptimeSec, 86400);
|
$uptime = (int)explode(" ", file_get_contents("/proc/uptime"))[0];
|
||||||
$uptimeHrs = intdiv($uptimeSec % 86400, 3600);
|
$load = (float)explode(" ", file_get_contents("/proc/loadavg"))[0];
|
||||||
|
|
||||||
|
$dfOut = shell_exec("df / | tail -1 | awk {print }") ?? "";
|
||||||
|
$diskPct = trim($dfOut);
|
||||||
|
|
||||||
|
// Services
|
||||||
|
$svcNames = ["lshttpd", "mysql", "redis"];
|
||||||
|
$svcMap = [];
|
||||||
|
foreach ($svcNames as $s) {
|
||||||
|
$status = trim(shell_exec("systemctl is-active " . escapeshellarg($s) . " 2>/dev/null") ?? "");
|
||||||
|
if ($status === "active") $svcMap[$s] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Site health from kb_facts
|
||||||
|
$siteLabels = [
|
||||||
|
"jarvis" => "jarvis.orbishosting.com",
|
||||||
|
"tomsjavajive" => "tomsjavajive.com",
|
||||||
|
"epictravelexp"=> "epictravelexpeditions.com",
|
||||||
|
"parkersling" => "parkerslingshot",
|
||||||
|
"orbishosting" => "orbishosting.com",
|
||||||
|
"orbisportal" => "orbis.orbishosting.com",
|
||||||
|
"tomtomgames" => "tomtomgames.com",
|
||||||
|
];
|
||||||
|
$sites = [];
|
||||||
|
$rows = JarvisDB::query(
|
||||||
|
"SELECT fact_key, fact_value FROM kb_facts WHERE category=sites AND updated_at > DATE_SUB(NOW(), INTERVAL 15 MINUTE) ORDER BY fact_key"
|
||||||
|
);
|
||||||
|
foreach ($rows as $r) {
|
||||||
|
$label = $siteLabels[$r["fact_key"]] ?? $r["fact_key"];
|
||||||
|
$sites[$label] = $r["fact_value"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$uptimeDays = intdiv($uptime, 86400);
|
||||||
|
$uptimeHrs = intdiv($uptime % 86400, 3600);
|
||||||
|
|
||||||
echo json_encode([
|
echo json_encode([
|
||||||
'ip' => DO_SERVER_IP,
|
"ip" => DO_SERVER_IP,
|
||||||
'reachable' => !empty($statsRaw),
|
"reachable" => true,
|
||||||
'cpu_pct' => $cpuPct,
|
"cpu_pct" => getCpuPct(),
|
||||||
'memory' => [
|
"memory" => [
|
||||||
'total_mb' => round($memTotal / 1024),
|
"total_mb" => round($memTotal / 1024),
|
||||||
'used_mb' => round($memUsed / 1024),
|
"used_mb" => round($memUsed / 1024),
|
||||||
'percent' => $memTotal > 0 ? round(($memUsed/$memTotal)*100,1) : 0,
|
"percent" => $memTotal > 0 ? round(($memUsed / $memTotal) * 100, 1) : 0,
|
||||||
],
|
],
|
||||||
'disk_used_pct' => $stats['DISK_USED'] ?? null,
|
"disk_used_pct" => $diskPct,
|
||||||
'load_1m' => (float)($stats['LOAD'] ?? 0),
|
"load_1m" => $load,
|
||||||
'uptime' => "{$uptimeDays}d {$uptimeHrs}h",
|
"uptime" => "{$uptimeDays}d {$uptimeHrs}h",
|
||||||
'services' => $svcMap,
|
"services" => $svcMap,
|
||||||
'sites' => $sites,
|
"sites" => $sites,
|
||||||
'timestamp' => date('c'),
|
"timestamp" => date("c"),
|
||||||
]);
|
]);
|
||||||
|
|||||||
Reference in New Issue
Block a user