#!/usr/bin/env python3 """ Скрипт метрик для VPS: CPU, RAM, диск. Запуск: python3 vps-metrics-api.py [--port 3497] Установи на каждый VPS и открой порт в файрволе (3497/tcp). Systemd (опционально): sudo cp vps-metrics-api.py /usr/local/bin/ sudo chmod +x /usr/local/bin/vps-metrics-api.py Создай юнит /etc/systemd/system/vps-metrics.service с ExecStart=/usr/bin/python3 /usr/local/bin/vps-metrics-api.py sudo systemctl enable --now vps-metrics """ import json import subprocess import sys from http.server import HTTPServer, BaseHTTPRequestHandler PORT = 3497 def get_metrics(): """Собирает метрики из /proc и df. Только stdlib.""" out = {} try: # Load average (1 min) with open("/proc/loadavg") as f: parts = f.read().strip().split() out["load_1"] = round(float(parts[0]), 2) # Memory: MemTotal, MemAvailable mem = {} with open("/proc/meminfo") as f: for line in f: if ":" in line: k, v = line.strip().split(":", 1) mem[k.strip()] = int(v.strip().split()[0]) # kB total_kb = mem.get("MemTotal", 0) avail_kb = mem.get("MemAvailable", mem.get("MemFree", 0)) used_kb = total_kb - avail_kb out["memory_total_gb"] = round(total_kb / 1024 / 1024, 2) out["memory_used_gb"] = round(used_kb / 1024 / 1024, 2) out["memory_percent"] = round(100 * used_kb / total_kb, 1) if total_kb else 0 out["memory.status"] = f"{out['memory_used_gb']:.1f} / {out['memory_total_gb']:.1f} GB" # Disk: root / result = subprocess.run( ["df", "-k", "/"], capture_output=True, text=True, timeout=5, ) if result.returncode == 0 and result.stdout: lines = result.stdout.strip().split("\n") if len(lines) >= 2: parts = lines[1].split() if len(parts) >= 4: total_kb = int(parts[1]) used_kb = int(parts[2]) avail_kb = int(parts[3]) total_gb = total_kb / 1024 / 1024 used_gb = used_kb / 1024 / 1024 avail_gb = avail_kb / 1024 / 1024 out["disk_total_gb"] = round(total_gb, 1) out["disk_used_gb"] = round(used_gb, 1) out["disk_free_gb"] = round(avail_gb, 1) out["disk_percent"] = round(100 * used_kb / total_kb, 1) if total_kb else 0 out["disk.status"] = f"{out['disk_free_gb']:.1f} / {out['disk_total_gb']:.1f} GB свободно" # Uptime with open("/proc/uptime") as f: out["uptime_seconds"] = int(float(f.read().split()[0])) except Exception as e: out["error"] = str(e) return out class Handler(BaseHTTPRequestHandler): def do_GET(self): self.send_response(200) self.send_header("Content-Type", "application/json") self.end_headers() self.wfile.write(json.dumps(get_metrics(), ensure_ascii=False).encode()) def log_message(self, *args): pass def main(): port = PORT if len(sys.argv) > 1 and sys.argv[1] == "--port" and len(sys.argv) > 2: port = int(sys.argv[2]) print(f"VPS metrics API: http://0.0.0.0:{port}", file=sys.stderr) HTTPServer(("0.0.0.0", port), Handler).serve_forever() if __name__ == "__main__": main()