superguardado: comando limpieza (limpia procesos atascados de la Pi) + limpiar.py
This commit is contained in:
82
vigilancia/limpiar.py
Normal file
82
vigilancia/limpiar.py
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Limpieza de procesos de la Pi: mata procesos zombie/atascados, reinicia servicios si es necesario."""
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import config
|
||||
|
||||
def sh(cmd):
|
||||
try:
|
||||
return subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=15).stdout.strip()
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
def limpiar():
|
||||
informe = []
|
||||
|
||||
# 1. Procesos Python atascados (CPU > 50% durante >60s)
|
||||
ps = sh("ps aux | grep python3 | grep -v grep")
|
||||
for linea in ps.splitlines():
|
||||
if not linea: continue
|
||||
parts = linea.split()
|
||||
try:
|
||||
cpu = float(parts[2])
|
||||
pid = parts[1]
|
||||
cmd = " ".join(parts[10:])
|
||||
if cpu > 50 and "minipc" in cmd:
|
||||
informe.append(f"Matando proceso atascado PID {pid} ({cpu}% CPU): {cmd[:50]}")
|
||||
sh(f"kill -9 {pid}")
|
||||
except (IndexError, ValueError):
|
||||
pass
|
||||
|
||||
# 2. Zombie processes
|
||||
zombies = sh("ps aux | awk '$8==\"Z\" {print $2}'")
|
||||
for z in zombies.splitlines():
|
||||
if z.strip():
|
||||
informe.append(f"Zombie PID {z.strip()} limpiado")
|
||||
sh(f"kill -9 {z.strip()}")
|
||||
|
||||
# 3. Procesos python viejos (>2h, sin ser servicios principales)
|
||||
ps2 = sh("ps aux | grep python3 | grep -v grep")
|
||||
for linea in ps2.splitlines():
|
||||
if not linea: continue
|
||||
parts = linea.split()
|
||||
try:
|
||||
pid = parts[1]
|
||||
starttime = parts[8]
|
||||
cmd = " ".join(parts[10:])
|
||||
if "tv_api" not in cmd and "pi_bot" not in cmd and "http.server" not in cmd:
|
||||
if "python" in cmd.lower() or "vigilancia" in cmd.lower():
|
||||
informe.append(f"Proceso residual PID {pid}: {cmd[:60]}")
|
||||
except (IndexError, ValueError):
|
||||
pass
|
||||
|
||||
# 4. Limpiar cache del sistema
|
||||
sh("echo 'raspberry' | sudo -S sync")
|
||||
sh("echo 'raspberry' | sudo -S sh -c 'echo 3 > /proc/sys/vm/drop_caches'")
|
||||
informe.append("Caché del sistema limpiado")
|
||||
|
||||
# 5. Verificar servicios
|
||||
for svc in ["tv-api", "pi-bot"]:
|
||||
st = sh(f"systemctl is-active {svc}")
|
||||
if st != "active":
|
||||
informe.append(f"⚠️ Servicio {svc} no activo: {st}")
|
||||
sh(f"echo 'raspberry' | sudo -S systemctl restart {svc}")
|
||||
|
||||
# 6. Estado final
|
||||
temp = sh("vcgencmd measure_temp")
|
||||
load = sh("cat /proc/loadavg | cut -d' ' -f1")
|
||||
mem = sh("free -h | awk 'NR==2{print $2\" total, \"$7\" libre\"}'")
|
||||
|
||||
if not informe:
|
||||
informe.append("✅ Todo limpio, sin procesos atascados")
|
||||
|
||||
informe.append(f"\nEstado: temp={temp} | load={load} | mem={mem}")
|
||||
return "\n".join(informe)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(limpiar())
|
||||
Reference in New Issue
Block a user