Files
homelab-docs/scripts/vps-metrics-api.py

95 lines
3.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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()