diff --git a/platform/modules/backups.py b/platform/modules/backups.py index 2f4ab89..6b38b91 100644 --- a/platform/modules/backups.py +++ b/platform/modules/backups.py @@ -592,63 +592,59 @@ def get_all_stats(): # ──────────────────────────────────────────────────────────────── def get_system_info(): - """ - Collect all system metrics in a SINGLE SSH call instead of 8 separate ones. - Emits a pipe-delimited line: cpu|mem|mem_pct|disk|disk_pct|load|uptime|docker_v|hostname - """ - batch_cmd = ( - "printf '%s|%s|%s|%s|%s|%s|%s|%s|%s\\n' " - "\"$(top -bn1 | grep 'Cpu(s)' | awk '{print $2+$4}')\" " - "\"$(free -m | awk 'NR==2{printf \"%s/%sMB\", $3, $2}')\" " - "\"$(free | awk 'NR==2{printf \"%.0f\", $3/$2*100}')\" " - "\"$(df -h / | awk 'NR==2{printf \"%s/%s\", $3, $2}')\" " - "\"$(df / | awk 'NR==2{print $5}' | tr -d '%')\" " - "\"$(cat /proc/loadavg | awk '{print $1, $2, $3}')\" " - "\"$(uptime -p)\" " - "\"$(docker --version 2>/dev/null | cut -d' ' -f3 | tr -d ',')\" " - "\"$(hostname -f 2>/dev/null || hostname)\"" - ) + if RUNNING_ON_MAIN_SERVER: + # Read directly from /proc (works in container with host /proc) + try: + # CPU + with open('/proc/stat') as f: + cpu = f.readline().split() + idle = int(cpu[4]) + total = sum(int(x) for x in cpu[1:]) + cpu_pct = round(100 * (1 - idle/total), 1) if total else 0 - stdout, stderr = _ssh_main(batch_cmd, timeout=20) + # Memory + mem = {} + with open('/proc/meminfo') as f: + for line in f: + k, v = line.split(':') + mem[k.strip()] = int(v.strip().split()[0]) + mem_total_mb = mem['MemTotal'] // 1024 + mem_used_mb = (mem['MemTotal'] - mem['MemAvailable']) // 1024 + mem_pct = round(100 * mem_used_mb / mem_total_mb) if mem_total_mb else 0 - # Parse the pipe-delimited result - if stdout and '|' in stdout: - # Use the last line in case there's extra output - for line in reversed(stdout.splitlines()): - line = line.strip() - if '|' in line: - parts = line.split('|') - if len(parts) >= 9: - return { - 'cpu_pct': parts[0] or '0', - 'memory': parts[1] or 'N/A', - 'mem_pct': parts[2] or '0', - 'disk': parts[3] or 'N/A', - 'disk_pct': parts[4] or '0', - 'load': parts[5] or 'N/A', - 'uptime': parts[6] or 'N/A', - 'docker_v': parts[7] or 'N/A', - 'hostname': parts[8] or 'main server', - } + # Disk + import shutil + disk = shutil.disk_usage('/') + disk_used_gb = round(disk.used / 1024**3, 1) + disk_total_gb = round(disk.total / 1024**3, 1) + disk_pct = round(100 * disk.used / disk.total) - # Fallback: individual calls if batch failed - cpu_out, _ = _ssh_main("top -bn1 | grep 'Cpu(s)' | awk '{print $2+$4}'") - mem_out, _ = _ssh_main("free -m | awk 'NR==2{printf \"%s/%sMB\", $3, $2}'") - mem_pct, _ = _ssh_main("free | awk 'NR==2{printf \"%.0f\", $3/$2*100}'") - disk_out, _ = _ssh_main("df -h / | awk 'NR==2{printf \"%s/%s\", $3, $2}'") - disk_pct, _ = _ssh_main("df / | awk 'NR==2{print $5}' | tr -d '%'") - load_out, _ = _ssh_main("cat /proc/loadavg | awk '{print $1, $2, $3}'") - uptime, _ = _ssh_main("uptime -p") - docker_v, _ = _ssh_main("docker --version | cut -d' ' -f3 | tr -d ','") - hostname, _ = _run("hostname -f 2>/dev/null || hostname") - return { - 'cpu_pct': cpu_out or '0', - 'memory': mem_out or 'N/A', - 'mem_pct': mem_pct or '0', - 'disk': disk_out or 'N/A', - 'disk_pct': disk_pct or '0', - 'load': load_out or 'N/A', - 'uptime': uptime or 'N/A', - 'docker_v': docker_v or 'N/A', - 'hostname': hostname or 'main server', - } \ No newline at end of file + # Load + with open('/proc/loadavg') as f: + load = f.read().split()[:3] + + # Uptime + with open('/proc/uptime') as f: + secs = int(float(f.read().split()[0])) + days = secs // 86400 + hrs = (secs % 86400) // 3600 + mins = (secs % 3600) // 60 + uptime = f"up {days}d {hrs}h {mins}m" if days else f"up {hrs}h {mins}m" + + # Docker version + docker_v, _ = _run("docker --version 2>/dev/null | cut -d' ' -f3 | tr -d ','") + hostname, _ = _run("cat /proc/sys/kernel/hostname 2>/dev/null || hostname") + + return { + 'cpu_pct': str(cpu_pct), + 'memory': f"{mem_used_mb}/{mem_total_mb}MB", + 'mem_pct': str(mem_pct), + 'disk': f"{disk_used_gb}G/{disk_total_gb}G", + 'disk_pct': str(disk_pct), + 'load': ' '.join(load), + 'uptime': uptime, + 'docker_v': docker_v or 'N/A', + 'hostname': hostname.strip() or 'main server', + } + except Exception as e: + pass # fall through to SSH method \ No newline at end of file