123 lines
4.1 KiB
Python
Executable File
123 lines
4.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import subprocess
|
|
import sys
|
|
import os
|
|
import signal
|
|
import time
|
|
from datetime import datetime
|
|
|
|
LOG_DIR = "/app/data/logs"
|
|
os.makedirs(LOG_DIR, exist_ok=True)
|
|
|
|
def get_timestamp():
|
|
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
log_file = open(f"{LOG_DIR}/bots.log", "a")
|
|
|
|
def log(msg):
|
|
timestamp = get_timestamp()
|
|
log_line = f"[{timestamp}] {msg}\n"
|
|
log_file.write(log_line)
|
|
log_file.flush()
|
|
print(msg)
|
|
|
|
print("🤖 Iniciando Bots de Traducción...")
|
|
print("=" * 40)
|
|
|
|
processes = []
|
|
restart_counts = {}
|
|
MAX_RESTARTS = 3
|
|
RESTART_COOLDOWN = 60
|
|
|
|
def start_process(cmd, name, delay_before=0):
|
|
if delay_before > 0:
|
|
log(f"⏳ Esperando {delay_before}s antes de iniciar {name}...")
|
|
time.sleep(delay_before)
|
|
|
|
log(f"✅ Iniciando {name}...")
|
|
|
|
log_path = f"{LOG_DIR}/{name.lower().replace(' ', '_')}.log"
|
|
log_fd = open(log_path, "a")
|
|
|
|
# stdout va al archivo Y a la consola del contenedor (Docker logs)
|
|
p = subprocess.Popen(
|
|
cmd,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.STDOUT,
|
|
preexec_fn=os.setsid
|
|
)
|
|
|
|
# Hilo que redirige la salida del proceso al archivo + consola
|
|
import threading
|
|
def tee_output(proc, fd, label):
|
|
for line in iter(proc.stdout.readline, b''):
|
|
decoded = line.decode("utf-8", errors="replace")
|
|
fd.write(decoded)
|
|
fd.flush()
|
|
print(f"[{label}] {decoded}", end="", flush=True)
|
|
fd.close()
|
|
|
|
t = threading.Thread(target=tee_output, args=(p, log_fd, name), daemon=True)
|
|
t.start()
|
|
|
|
processes.append((p, name))
|
|
return p
|
|
|
|
p1 = start_process(["python3", "-X", "faulthandler", "-X", "importsys", "botdiscord/bot.py"], "Discord Bot", delay_before=10)
|
|
p2 = start_process(["python3", "-X", "faulthandler", "-X", "importsys", "bottelegram/telegram_bot.py"], "Telegram Bot", delay_before=5)
|
|
p3 = start_process(["python3", "-X", "faulthandler", "-X", "importsys", "panel/main.py"], "Panel Web", delay_before=0)
|
|
|
|
print("=" * 40)
|
|
print("🎉 Todos los servicios funcionando!")
|
|
print(f" 📍 Panel: http://localhost:8000")
|
|
print(f" 📁 Logs: {LOG_DIR}")
|
|
print("=" * 40)
|
|
print("\nCtrl+C para detener")
|
|
|
|
def signal_handler(sig, frame):
|
|
log("🛑 Deteniendo...")
|
|
for p, name in processes:
|
|
try:
|
|
os.killpg(os.getpgid(p.pid), signal.SIGTERM)
|
|
log(f" ✅ {name} detenido")
|
|
except:
|
|
pass
|
|
log_file.close()
|
|
sys.exit(0)
|
|
|
|
signal.signal(signal.SIGINT, signal_handler)
|
|
signal.signal(signal.SIGTERM, signal_handler)
|
|
|
|
while True:
|
|
for p, name in processes:
|
|
if p.poll() is not None:
|
|
if name not in restart_counts:
|
|
restart_counts[name] = {"count": 0, "last_restart": 0}
|
|
|
|
current_time = time.time()
|
|
|
|
if current_time - restart_counts[name]["last_restart"] > RESTART_COOLDOWN:
|
|
restart_counts[name]["count"] = 0
|
|
|
|
restart_counts[name]["count"] += 1
|
|
restart_counts[name]["last_restart"] = current_time
|
|
|
|
if restart_counts[name]["count"] > MAX_RESTARTS:
|
|
log(f"⛔ {name} se detuvo {restart_counts[name]['count']} veces. Demasiados reinicios. Esperando {RESTART_COOLDOWN}s...")
|
|
time.sleep(RESTART_COOLDOWN)
|
|
restart_counts[name]["count"] = 0
|
|
continue
|
|
|
|
log(f"⚠️ {name} se detuvo (intento {restart_counts[name]['count']}/{MAX_RESTARTS}), reiniciando...")
|
|
|
|
delay = 5 if name != "Discord Bot" else 10
|
|
|
|
if name == "Discord Bot":
|
|
p1 = start_process(["python3", "-X", "faulthandler", "-X", "importsys", "botdiscord/bot.py"], "Discord Bot", delay_before=delay)
|
|
elif name == "Telegram Bot":
|
|
p2 = start_process(["python3", "-X", "faulthandler", "-X", "importsys", "bottelegram/telegram_bot.py"], "Telegram Bot", delay_before=delay)
|
|
elif name == "Panel Web":
|
|
p3 = start_process(["python3", "-X", "faulthandler", "-X", "importsys", "panel/main.py"], "Panel Web", delay_before=0)
|
|
|
|
time.sleep(5)
|