first commit
This commit is contained in:
Executable
+89
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Cache-Control: no-cache, must-revalidate');
|
||||
header('Expires: 0');
|
||||
|
||||
ini_set('display_errors', 0);
|
||||
error_reporting(0);
|
||||
|
||||
define('CRAFTY_URL', 'https://craft.ipv6.nix.roulaise.net');
|
||||
define('CRAFTY_TOKEN', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJpYXQiOjE3NzczMDIwNjIsInRva2VuX2lkIjoxfQ.DXFKO4aim-nJ_Wyn-o3qMaVyv6AP3aCoAYukR-uQels');
|
||||
|
||||
// Ports connus → clé logique
|
||||
const PORT_MAP = [9191 => 'mc1', 9292 => 'mc2'];
|
||||
|
||||
function craftyGet(string $path): ?array {
|
||||
$ch = curl_init(CRAFTY_URL . $path);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => 5,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . CRAFTY_TOKEN],
|
||||
]);
|
||||
$body = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $body ? json_decode($body, true) : null;
|
||||
}
|
||||
|
||||
// Extraire -Xmx depuis la commande d'exécution → retourne en Mio
|
||||
function extractXmx(string $cmd): ?int {
|
||||
if (preg_match('/-Xmx(\d+)([GgMm])/i', $cmd, $m)) {
|
||||
return strtolower($m[2]) === 'g'
|
||||
? (int)$m[1] * 1024
|
||||
: (int)$m[1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 1. Lister les serveurs
|
||||
$list = craftyGet('/api/v2/servers');
|
||||
if (!$list || ($list['status'] ?? '') !== 'ok') {
|
||||
echo json_encode(['success' => false, 'error' => 'Crafty unreachable']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($list['data'] as $srv) {
|
||||
$uuid = $srv['server_id'];
|
||||
|
||||
// Stats de ce serveur
|
||||
$stats = craftyGet("/api/v2/servers/{$uuid}/stats");
|
||||
if (!$stats || ($stats['status'] ?? '') !== 'ok') continue;
|
||||
$d = $stats['data'];
|
||||
|
||||
// Identifier la clé logique par port
|
||||
$port = (int)($d['server_port'] ?? $srv['server_port'] ?? 0);
|
||||
$key = PORT_MAP[$port] ?? null;
|
||||
|
||||
// Fallback par nom si port inconnu
|
||||
if (!$key) {
|
||||
$name = strtolower($d['server_name'] ?? $srv['server_name'] ?? '');
|
||||
if (str_contains($name, '#1') || str_contains($name, 'mc1') || str_contains($name, 'forge')) $key = 'mc1';
|
||||
elseif (str_contains($name, '#2') || str_contains($name, 'mc2') || str_contains($name, 'fabric')) $key = 'mc2';
|
||||
else $key = $uuid;
|
||||
}
|
||||
|
||||
// RAM utilisée : Crafty retourne en octets
|
||||
$ramUsed = isset($d['mem']) ? (int)round($d['mem'] / 1024 / 1024) : null;
|
||||
|
||||
// RAM allouée : extraire -Xmx depuis execution_command
|
||||
$cmd = $d['execution_command'] ?? $srv['execution_command'] ?? '';
|
||||
$ramAlloc = extractXmx($cmd);
|
||||
|
||||
$result[$key] = [
|
||||
'uuid' => $uuid,
|
||||
'name' => $d['server_name'] ?? $srv['server_name'] ?? $uuid,
|
||||
'port' => $port,
|
||||
'running' => (bool)($d['running'] ?? false),
|
||||
'players' => (int)($d['online'] ?? 0),
|
||||
'max_players' => (int)($d['max'] ?? 0),
|
||||
'ram_used' => $ramUsed,
|
||||
'ram_alloc' => $ramAlloc,
|
||||
'cpu' => isset($d['cpu']) ? round((float)$d['cpu'], 1) : null,
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'servers' => $result], JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE);
|
||||
?>
|
||||
Executable
+115
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Cache-Control: no-cache, must-revalidate');
|
||||
|
||||
ini_set('display_errors', 0);
|
||||
error_reporting(0);
|
||||
|
||||
$result = [];
|
||||
|
||||
// ===== EVENTS (logs parsés par mc-log-watcher) =====
|
||||
$logsFile = '/var/cache/mc-logs.json';
|
||||
if (file_exists($logsFile)) {
|
||||
$raw = @file_get_contents($logsFile);
|
||||
$decoded = $raw ? @json_decode($raw, true) : null;
|
||||
$result['events'] = $decoded['events'] ?? [];
|
||||
// Renvoyer les N derniers triés du plus récent au plus ancien
|
||||
$result['events'] = array_reverse(array_slice($result['events'], -100));
|
||||
} else {
|
||||
$result['events'] = [];
|
||||
}
|
||||
|
||||
// ===== WHITELIST =====
|
||||
$whitelists = [
|
||||
'mc1' => '/srv/Minecraft/whitelist.json',
|
||||
'mc2' => '/srv/Fabric-1.21.8/whitelist.json',
|
||||
];
|
||||
$result['whitelist'] = [];
|
||||
foreach ($whitelists as $key => $path) {
|
||||
if (file_exists($path)) {
|
||||
$raw = @file_get_contents($path);
|
||||
$players = $raw ? @json_decode($raw, true) : [];
|
||||
$result['whitelist'][$key] = is_array($players) ? $players : [];
|
||||
} else {
|
||||
$result['whitelist'][$key] = null; // null = whitelist désactivée / fichier absent
|
||||
}
|
||||
}
|
||||
|
||||
// ===== BANNISSEMENTS =====
|
||||
$banlists = [
|
||||
'mc1' => '/srv/Minecraft/banned-players.json',
|
||||
'mc2' => '/srv/Fabric-1.21.8/banned-players.json',
|
||||
];
|
||||
$result['banned'] = [];
|
||||
foreach ($banlists as $key => $path) {
|
||||
if (file_exists($path)) {
|
||||
$raw = @file_get_contents($path);
|
||||
$players = $raw ? @json_decode($raw, true) : [];
|
||||
$result['banned'][$key] = is_array($players) ? $players : [];
|
||||
} else {
|
||||
$result['banned'][$key] = [];
|
||||
}
|
||||
}
|
||||
|
||||
// ===== MODS (Fabric uniquement - dossier mods/) =====
|
||||
$modsDir = '/srv/Fabric-1.21.8/mods';
|
||||
$result['mods'] = [];
|
||||
if (is_dir($modsDir)) {
|
||||
$files = @scandir($modsDir);
|
||||
if ($files) {
|
||||
foreach ($files as $file) {
|
||||
if (pathinfo($file, PATHINFO_EXTENSION) === 'jar') {
|
||||
// Tenter de lire fabric.mod.json à l'intérieur du jar (zip)
|
||||
$jarPath = $modsDir . '/' . $file;
|
||||
$modInfo = ['filename' => $file, 'name' => null, 'version' => null, 'description' => null];
|
||||
|
||||
// Lire le fabric.mod.json depuis le jar (zip)
|
||||
if (class_exists('ZipArchive')) {
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($jarPath) === true) {
|
||||
$idx = $zip->locateName('fabric.mod.json');
|
||||
if ($idx !== false) {
|
||||
$json = @json_decode($zip->getFromIndex($idx), true);
|
||||
if ($json) {
|
||||
$modInfo['name'] = $json['name'] ?? $json['id'] ?? null;
|
||||
$modInfo['version'] = $json['version'] ?? null;
|
||||
$modInfo['description'] = $json['description'] ?? null;
|
||||
$modInfo['id'] = $json['id'] ?? null;
|
||||
}
|
||||
}
|
||||
$zip->close();
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: nom depuis le fichier
|
||||
if (!$modInfo['name']) {
|
||||
$modInfo['name'] = preg_replace('/[-_][\d.]+.*\.jar$/', '', $file);
|
||||
}
|
||||
|
||||
$result['mods'][] = $modInfo;
|
||||
}
|
||||
}
|
||||
// Trier par nom
|
||||
usort($result['mods'], fn($a, $b) => strcasecmp($a['name'] ?? '', $b['name'] ?? ''));
|
||||
}
|
||||
}
|
||||
|
||||
// ===== SERVER PROPERTIES (whitelist activée ?) =====
|
||||
$propsFiles = [
|
||||
'mc1' => '/srv/Minecraft/server.properties',
|
||||
'mc2' => '/srv/Fabric-1.21.8/server.properties',
|
||||
];
|
||||
$result['whitelist_enabled'] = [];
|
||||
foreach ($propsFiles as $key => $path) {
|
||||
$result['whitelist_enabled'][$key] = false;
|
||||
if (file_exists($path)) {
|
||||
$content = @file_get_contents($path);
|
||||
if ($content && preg_match('/^white-list\s*=\s*true/m', $content)) {
|
||||
$result['whitelist_enabled'][$key] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'data' => $result], JSON_UNESCAPED_UNICODE);
|
||||
?>
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
header('Cache-Control: no-store');
|
||||
|
||||
$content = @file_get_contents('/proc/mdstat');
|
||||
if (!$content) { echo json_encode(['error' => 'unreadable']); exit; }
|
||||
|
||||
$arrays = [];
|
||||
$current = null;
|
||||
|
||||
foreach (explode("\n", $content) as $line) {
|
||||
if (preg_match('/^(md\d+)\s*:\s*(\w+)\s+(\w+)\s+(.+)$/', $line, $m)) {
|
||||
$current = $m[1];
|
||||
$arrays[$current] = ['name' => $m[1], 'level' => $m[3], 'health' => 'ok', 'bitmap' => '', 'detail' => ''];
|
||||
}
|
||||
if ($current && preg_match('/\[(\d+)\/(\d+)\]\s*\[([U_]+)\]/', $line, $m)) {
|
||||
$arrays[$current]['bitmap'] = $m[3];
|
||||
$arrays[$current]['active'] = (int)$m[2];
|
||||
$arrays[$current]['total'] = (int)$m[1];
|
||||
if ((int)$m[2] < (int)$m[1] || str_contains($m[3], '_'))
|
||||
$arrays[$current]['health'] = 'degraded';
|
||||
}
|
||||
if ($current && preg_match('/(resync|recovery)\s*=\s*([\d.]+%)/i', $line, $m)) {
|
||||
$arrays[$current]['health'] = 'recovering';
|
||||
$arrays[$current]['detail'] = "{$m[1]} {$m[2]}";
|
||||
}
|
||||
}
|
||||
|
||||
$list = array_values($arrays);
|
||||
$healthy = !array_filter($list, fn($a) => $a['health'] !== 'ok');
|
||||
|
||||
echo json_encode(['healthy' => $healthy, 'arrays' => $list]);
|
||||
Executable
+178
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Cache-Control: no-cache, must-revalidate');
|
||||
header('Expires: 0');
|
||||
|
||||
ini_set('display_errors', 0);
|
||||
error_reporting(0);
|
||||
|
||||
/**
|
||||
* Minecraft Server List Ping (protocole 1.7+)
|
||||
* Ref: https://wiki.vg/Server_List_Ping
|
||||
*/
|
||||
function pingMinecraftServer(string $host, int $port = 25565, int $timeout = 4): array {
|
||||
$result = [
|
||||
'online' => false,
|
||||
'players' => 0,
|
||||
'max_players' => 0,
|
||||
'version' => '',
|
||||
'motd' => '',
|
||||
'latency' => null,
|
||||
];
|
||||
|
||||
$start = microtime(true);
|
||||
|
||||
$socket = @fsockopen($host, $port, $errno, $errstr, $timeout);
|
||||
if (!$socket) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
stream_set_timeout($socket, $timeout);
|
||||
|
||||
// ---- Handshake packet (0x00) ----
|
||||
$hostBytes = $host;
|
||||
$hostLen = strlen($hostBytes);
|
||||
|
||||
$handshakeData = "\x00"; // Packet ID 0x00
|
||||
$handshakeData .= varInt(47); // Protocol version (47 = 1.8, -1 non-spécifique)
|
||||
$handshakeData .= varInt($hostLen) . $hostBytes; // Server address
|
||||
$handshakeData .= pack('n', $port); // Port (unsigned short big-endian)
|
||||
$handshakeData .= varInt(1); // Next state: 1 = status
|
||||
|
||||
fwrite($socket, varInt(strlen($handshakeData)) . $handshakeData);
|
||||
|
||||
// ---- Status Request (0x00, longueur 1) ----
|
||||
fwrite($socket, "\x01\x00");
|
||||
|
||||
// ---- Lire la réponse ----
|
||||
$packetLen = readVarInt($socket);
|
||||
if ($packetLen <= 0) {
|
||||
fclose($socket);
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Lire l'ID du paquet (doit être 0x00)
|
||||
readVarInt($socket);
|
||||
|
||||
// Lire la longueur de la chaîne JSON
|
||||
$strLen = readVarInt($socket);
|
||||
if ($strLen <= 0) {
|
||||
fclose($socket);
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Lire le JSON
|
||||
$json = '';
|
||||
$remaining = $strLen;
|
||||
while ($remaining > 0 && !feof($socket)) {
|
||||
$chunk = fread($socket, min($remaining, 4096));
|
||||
if ($chunk === false || $chunk === '') break;
|
||||
$json .= $chunk;
|
||||
$remaining -= strlen($chunk);
|
||||
}
|
||||
|
||||
fclose($socket);
|
||||
|
||||
$latency = (int) round((microtime(true) - $start) * 1000);
|
||||
$data = @json_decode($json, true);
|
||||
|
||||
if (!$data) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// ---- Extraire le MOTD ----
|
||||
$motd = '';
|
||||
if (isset($data['description'])) {
|
||||
if (is_string($data['description'])) {
|
||||
$motd = $data['description'];
|
||||
} elseif (is_array($data['description'])) {
|
||||
$motd = $data['description']['text'] ?? '';
|
||||
// Concatener les extras
|
||||
if (!empty($data['description']['extra']) && is_array($data['description']['extra'])) {
|
||||
foreach ($data['description']['extra'] as $extra) {
|
||||
$motd .= $extra['text'] ?? '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Supprimer les codes couleur §X
|
||||
$motd = preg_replace('/§[0-9a-fk-orA-FK-OR]/u', '', $motd);
|
||||
$motd = trim(preg_replace('/\s+/', ' ', $motd));
|
||||
|
||||
$result['online'] = true;
|
||||
$result['players'] = (int) ($data['players']['online'] ?? 0);
|
||||
$result['max_players'] = (int) ($data['players']['max'] ?? 0);
|
||||
$result['version'] = $data['version']['name'] ?? '';
|
||||
$result['motd'] = $motd;
|
||||
$result['latency'] = $latency;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode un entier en VarInt Minecraft
|
||||
*/
|
||||
function varInt(int $value): string {
|
||||
$out = '';
|
||||
do {
|
||||
$byte = $value & 0x7F;
|
||||
$value = ($value >> 7) & PHP_INT_MAX; // shift sans signe
|
||||
if ($value !== 0) $byte |= 0x80;
|
||||
$out .= chr($byte);
|
||||
} while ($value !== 0);
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lit un VarInt depuis un socket
|
||||
*/
|
||||
function readVarInt($socket): int {
|
||||
$value = 0;
|
||||
$shift = 0;
|
||||
do {
|
||||
$raw = fgetc($socket);
|
||||
if ($raw === false) return 0;
|
||||
$byte = ord($raw);
|
||||
$value |= ($byte & 0x7F) << $shift;
|
||||
$shift += 7;
|
||||
if ($shift > 35) break; // sécurité anti-boucle infinie
|
||||
} while ($byte & 0x80);
|
||||
return $value;
|
||||
}
|
||||
|
||||
// ======================================================
|
||||
// Configuration des serveurs à pinger
|
||||
// ======================================================
|
||||
$servers = [
|
||||
[
|
||||
'name' => 'Serveur MC #1',
|
||||
'host' => 'nix.roulaise.net',
|
||||
'port' => 9191,
|
||||
],
|
||||
[
|
||||
'name' => 'Serveur MC #2',
|
||||
'host' => 'nix.roulaise.net',
|
||||
'port' => 9292,
|
||||
],
|
||||
];
|
||||
|
||||
// ======================================================
|
||||
// Ping tous les serveurs et retourner le résultat JSON
|
||||
// ======================================================
|
||||
$results = [];
|
||||
foreach ($servers as $srv) {
|
||||
$ping = pingMinecraftServer($srv['host'], $srv['port']);
|
||||
$results[] = array_merge([
|
||||
'name' => $srv['name'],
|
||||
'host' => $srv['host'],
|
||||
'port' => $srv['port'],
|
||||
], $ping);
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'servers' => $results,
|
||||
'timestamp' => time(),
|
||||
], JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
|
||||
?>
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
// --- Configuration des serveurs ---
|
||||
$servers = [
|
||||
'Fabric 1.19.2' => '/srv/fabric-1.19.2',
|
||||
'Forge 1.19.2' => '/srv/forge-1.19.2',
|
||||
];
|
||||
// ----------------------------------
|
||||
|
||||
header('Content-Type: application/json');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
|
||||
function mod_name(string $filename): string {
|
||||
$name = preg_replace('/\.jar$/i', '', $filename);
|
||||
$name = preg_replace('/[-_](?:v?\d+[\.\d]*[\+\-\w]*).*$/i', '', $name);
|
||||
$name = str_replace(['-', '_'], ' ', $name);
|
||||
return ucwords(strtolower(trim($name)));
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach ($servers as $label => $root) {
|
||||
$mods_dir = $root . '/mods';
|
||||
$entry = ['label' => $label, 'mods' => [], 'error' => null];
|
||||
|
||||
if (!is_dir($mods_dir)) {
|
||||
$entry['error'] = 'Dossier introuvable : ' . $mods_dir;
|
||||
} else {
|
||||
$files = glob($mods_dir . '/*.jar');
|
||||
sort($files);
|
||||
foreach ($files as $f) {
|
||||
$filename = basename($f);
|
||||
$entry['mods'][] = [
|
||||
'file' => $filename,
|
||||
'name' => mod_name($filename),
|
||||
];
|
||||
}
|
||||
}
|
||||
$result[] = $entry;
|
||||
}
|
||||
|
||||
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
Executable
+133
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Cache-Control: no-cache, must-revalidate');
|
||||
header('Expires: 0');
|
||||
|
||||
ini_set('display_errors', 0);
|
||||
error_reporting(0);
|
||||
|
||||
function getSystemStats() {
|
||||
$stats = [];
|
||||
|
||||
// ========== UPTIME ==========
|
||||
if (file_exists('/proc/uptime')) {
|
||||
$uptime = @file_get_contents('/proc/uptime');
|
||||
if ($uptime !== false) {
|
||||
$uptimeSeconds = floatval(explode(' ', $uptime)[0]);
|
||||
$days = floor($uptimeSeconds / 86400);
|
||||
$hours = floor(($uptimeSeconds % 86400) / 3600);
|
||||
$minutes = floor(($uptimeSeconds % 3600) / 60);
|
||||
$stats['uptime'] = sprintf('%dd %dh %dm', $days, $hours, $minutes);
|
||||
} else {
|
||||
$stats['uptime'] = 'N/A';
|
||||
}
|
||||
} else {
|
||||
$stats['uptime'] = 'N/A';
|
||||
}
|
||||
|
||||
// ========== CPU USAGE ==========
|
||||
if (file_exists('/proc/stat')) {
|
||||
$stat1 = @file('/proc/stat');
|
||||
if ($stat1 !== false && count($stat1) > 0) {
|
||||
usleep(100000);
|
||||
$stat2 = @file('/proc/stat');
|
||||
if ($stat2 !== false && count($stat2) > 0) {
|
||||
$info1 = explode(' ', preg_replace('!cpu +!', '', $stat1[0]));
|
||||
$info2 = explode(' ', preg_replace('!cpu +!', '', $stat2[0]));
|
||||
$dif = [
|
||||
'user' => floatval($info2[0]) - floatval($info1[0]),
|
||||
'nice' => floatval($info2[1]) - floatval($info1[1]),
|
||||
'sys' => floatval($info2[2]) - floatval($info1[2]),
|
||||
'idle' => floatval($info2[3]) - floatval($info1[3])
|
||||
];
|
||||
$total = array_sum($dif);
|
||||
$stats['cpu_usage'] = $total > 0 ? round(100 - ($dif['idle'] / $total * 100), 1) : 0;
|
||||
} else {
|
||||
$load = sys_getloadavg();
|
||||
$stats['cpu_usage'] = round(min($load[0] * 25, 100), 1);
|
||||
}
|
||||
} else {
|
||||
$load = sys_getloadavg();
|
||||
$stats['cpu_usage'] = round(min($load[0] * 25, 100), 1);
|
||||
}
|
||||
} else {
|
||||
$stats['cpu_usage'] = 0;
|
||||
}
|
||||
|
||||
// ========== MEMORY ==========
|
||||
if (file_exists('/proc/meminfo')) {
|
||||
$meminfo = @file_get_contents('/proc/meminfo');
|
||||
if ($meminfo !== false) {
|
||||
preg_match_all('/^(\w+):\s+(\d+)/m', $meminfo, $matches);
|
||||
$mem = array_combine($matches[1], $matches[2]);
|
||||
$memTotal = floatval($mem['MemTotal']) / 1024 / 1024;
|
||||
$memAvailable = isset($mem['MemAvailable'])
|
||||
? floatval($mem['MemAvailable'])
|
||||
: (floatval($mem['MemFree']) + floatval($mem['Buffers']) + floatval($mem['Cached']));
|
||||
$memFree = $memAvailable / 1024 / 1024;
|
||||
$memUsed = $memTotal - $memFree;
|
||||
$stats['ram_total'] = round($memTotal, 1);
|
||||
$stats['ram_used'] = round($memUsed, 1);
|
||||
$stats['ram_free'] = round($memFree, 1);
|
||||
$stats['ram_percent'] = round(($memUsed / $memTotal) * 100, 1);
|
||||
} else {
|
||||
$stats['ram_total'] = $stats['ram_used'] = $stats['ram_percent'] = 0;
|
||||
}
|
||||
} else {
|
||||
$stats['ram_total'] = $stats['ram_used'] = $stats['ram_percent'] = 0;
|
||||
}
|
||||
|
||||
// ========== DISK ==========
|
||||
$partitions = ['/', '/var', '/srv'];
|
||||
foreach ($partitions as $partition) {
|
||||
$key = str_replace('/', '', $partition);
|
||||
if ($key === '') $key = 'root';
|
||||
$diskTotal = @disk_total_space($partition);
|
||||
$diskFree = @disk_free_space($partition);
|
||||
if ($diskTotal !== false && $diskFree !== false) {
|
||||
$diskUsed = $diskTotal - $diskFree;
|
||||
$stats['disk_' . $key . '_total'] = round($diskTotal / 1024 / 1024 / 1024, 1);
|
||||
$stats['disk_' . $key . '_used'] = round($diskUsed / 1024 / 1024 / 1024, 1);
|
||||
$stats['disk_' . $key . '_free'] = round($diskFree / 1024 / 1024 / 1024, 1);
|
||||
$stats['disk_' . $key . '_percent'] = round(($diskUsed / $diskTotal) * 100, 1);
|
||||
} else {
|
||||
$stats['disk_' . $key . '_total'] = 0;
|
||||
$stats['disk_' . $key . '_free'] = 0;
|
||||
$stats['disk_' . $key . '_percent'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ========== LOAD AVERAGE ==========
|
||||
$loadavg = sys_getloadavg();
|
||||
$stats['load_1'] = round($loadavg[0], 2);
|
||||
$stats['load_5'] = round($loadavg[1], 2);
|
||||
$stats['load_15'] = round($loadavg[2], 2);
|
||||
|
||||
// ========== PROCESSES ==========
|
||||
if (function_exists('shell_exec')) {
|
||||
$processes = @shell_exec('ps aux 2>/dev/null | wc -l');
|
||||
$stats['processes'] = $processes !== null ? max(intval(trim($processes)) - 1, 0) : 0;
|
||||
} else {
|
||||
$stats['processes'] = 0;
|
||||
}
|
||||
|
||||
$stats['hostname'] = @gethostname() ?: 'Unknown';
|
||||
$stats['timestamp'] = time();
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
try {
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'data' => getSystemStats()
|
||||
], JSON_NUMERIC_CHECK);
|
||||
} catch (Exception $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user