✨ Nuevas funcionalidades: - API REST unificada en puerto 8080 (eliminado CORS) - WebSocket para logs en tiempo real desde journalctl - Integración completa con systemd para gestión de servicios - Escaneo automático de procesos Node.js y Python - Rate limiting (1 operación/segundo por app) - Interface web moderna con Tailwind CSS (tema oscuro) - Documentación API estilo Swagger completamente en español 🎨 Interface Web (todas las páginas en español): - Dashboard con estadísticas en tiempo real - Visor de escaneo de procesos con filtros - Formulario de registro de aplicaciones con variables de entorno - Visor de logs en tiempo real con WebSocket y sidebar - Página de selección de apps detectadas - Documentación completa de API REST 🏗️ Arquitectura: - Módulo models: ServiceConfig, ManagedApp, AppStatus - Módulo systemd: wrapper de systemctl, generador de .service, parser - Módulo orchestrator: AppManager, LifecycleManager con validaciones - Módulo api: handlers REST, WebSocket manager, DTOs - Servidor unificado en puerto 8080 (Web + API + WS) 🔧 Mejoras técnicas: - Eliminación de CORS mediante servidor unificado - Separación clara frontend/backend con carga dinámica - Thread-safe con Arc<DashMap> para estado compartido - Reconciliación de estados: sysinfo vs systemd - Validaciones de paths, usuarios y configuraciones - Manejo robusto de errores con thiserror 📝 Documentación: - README.md actualizado con arquitectura completa - EJEMPLOS.md con casos de uso detallados - ESTADO_PROYECTO.md con progreso de Fase 4 - API docs interactiva en /api-docs - Script de despliegue mejorado con health checks 🚀 Producción: - Deployment script con validaciones - Health checks y rollback capability - Configuración de sudoers para systemctl - Hardening de seguridad en servicios systemd
11 KiB
11 KiB
Ejemplos Prácticos de Uso - SIAX Monitor
Tabla de Contenidos
- Instalación
- Gestión de Aplicaciones Node.js
- Gestión de Aplicaciones Python
- Monitoreo y Logs
- Casos de Uso Reales
- Troubleshooting
Instalación
Instalación Completa
# Clonar el proyecto
git clone <repo-url>
cd siax_monitor
# Ejecutar script de deployment
sudo ./desplegar_agent.sh
# Verificar instalación
sudo systemctl status siax-agent
Verificar que todo funciona
# Verificar servicio
curl http://localhost:8081/api/apps
# Debe responder:
# {"success":true,"data":{"apps":[],"total":0}}
Gestión de Aplicaciones Node.js
Ejemplo 1: API Express Básica
# Registrar aplicación
curl -X POST http://localhost:8081/api/apps \
-H "Content-Type: application/json" \
-d '{
"app_name": "api-express",
"script_path": "/home/nodejs/api-express/server.js",
"working_directory": "/home/nodejs/api-express",
"user": "nodejs",
"environment": {
"PORT": "3000",
"NODE_ENV": "production"
},
"restart_policy": "always",
"app_type": "nodejs",
"description": "API REST con Express"
}'
# Iniciar aplicación
curl -X POST http://localhost:8081/api/apps/api-express/start
# Ver estado
curl http://localhost:8081/api/apps/api-express/status | jq
Ejemplo 2: Aplicación Next.js
curl -X POST http://localhost:8081/api/apps \
-H "Content-Type: application/json" \
-d '{
"app_name": "frontend-nextjs",
"script_path": "/var/www/frontend/.next/standalone/server.js",
"working_directory": "/var/www/frontend",
"user": "www-data",
"environment": {
"PORT": "3000",
"NODE_ENV": "production",
"HOSTNAME": "0.0.0.0"
},
"restart_policy": "always",
"app_type": "nodejs"
}'
curl -X POST http://localhost:8081/api/apps/frontend-nextjs/start
Ejemplo 3: Worker de Background (Bull Queue)
curl -X POST http://localhost:8081/api/apps \
-H "Content-Type: application/json" \
-d '{
"app_name": "queue-worker",
"script_path": "/opt/workers/queue-worker/index.js",
"working_directory": "/opt/workers/queue-worker",
"user": "workers",
"environment": {
"REDIS_URL": "redis://localhost:6379",
"CONCURRENCY": "5"
},
"restart_policy": "on-failure",
"app_type": "nodejs",
"description": "Worker de procesamiento de colas"
}'
Gestión de Aplicaciones Python
Ejemplo 1: API FastAPI
curl -X POST http://localhost:8081/api/apps \
-H "Content-Type: application/json" \
-d '{
"app_name": "ml-api",
"script_path": "/home/python/ml-api/main.py",
"working_directory": "/home/python/ml-api",
"user": "python",
"environment": {
"PORT": "8000",
"WORKERS": "4",
"PYTHONUNBUFFERED": "1"
},
"restart_policy": "always",
"app_type": "python",
"description": "API de Machine Learning"
}'
curl -X POST http://localhost:8081/api/apps/ml-api/start
Nota: Asegúrate de que tu main.py tiene un servidor ASGI:
# main.py
from fastapi import FastAPI
import uvicorn
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
if __name__ == "__main__":
import os
port = int(os.getenv("PORT", 8000))
workers = int(os.getenv("WORKERS", 4))
uvicorn.run("main:app", host="0.0.0.0", port=port, workers=workers)
Ejemplo 2: Script de Data Processing
curl -X POST http://localhost:8081/api/apps \
-H "Content-Type: application/json" \
-d '{
"app_name": "data-processor",
"script_path": "/opt/scripts/data-processor/processor.py",
"working_directory": "/opt/scripts/data-processor",
"user": "dataops",
"environment": {
"DB_HOST": "localhost",
"DB_PORT": "5432",
"LOG_LEVEL": "INFO"
},
"restart_policy": "on-failure",
"app_type": "python"
}'
Monitoreo y Logs
Ver logs en tiempo real con WebSocket
Opción 1: JavaScript (Browser)
// Conectar a logs
const ws = new WebSocket('ws://localhost:8081/ws/logs/api-express');
ws.onopen = () => {
console.log('Conectado a logs de api-express');
};
ws.onmessage = (event) => {
console.log('LOG:', event.data);
// Mostrar en UI
document.getElementById('logs').innerHTML += event.data + '<br>';
};
ws.onerror = (error) => {
console.error('Error:', error);
};
ws.onclose = () => {
console.log('Desconectado');
};
Opción 2: wscat (CLI)
# Instalar wscat
npm install -g wscat
# Conectar a logs
wscat -c ws://localhost:8081/ws/logs/api-express
Opción 3: Python
import websocket
import json
def on_message(ws, message):
try:
data = json.loads(message)
print(f"[{data.get('timestamp', 'N/A')}] {data.get('MESSAGE', message)}")
except:
print(message)
def on_error(ws, error):
print(f"Error: {error}")
def on_close(ws, close_status_code, close_msg):
print("Conexión cerrada")
def on_open(ws):
print("Conectado a logs")
ws = websocket.WebSocketApp(
"ws://localhost:8081/ws/logs/api-express",
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close
)
ws.run_forever()
Verificar estado de múltiples apps
#!/bin/bash
# check-all-apps.sh
echo "Estado de todas las aplicaciones:"
echo "=================================="
# Obtener lista de apps
apps=$(curl -s http://localhost:8081/api/apps | jq -r '.data.apps[]')
for app in $apps; do
status=$(curl -s http://localhost:8081/api/apps/$app/status | jq -r '.data.status')
pid=$(curl -s http://localhost:8081/api/apps/$app/status | jq -r '.data.pid')
cpu=$(curl -s http://localhost:8081/api/apps/$app/status | jq -r '.data.cpu_usage')
mem=$(curl -s http://localhost:8081/api/apps/$app/status | jq -r '.data.memory_usage')
printf "%-20s [%s] PID: %-6s CPU: %-6s RAM: %s\n" "$app" "$status" "$pid" "$cpu" "$mem"
done
Casos de Uso Reales
Caso 1: Microservicios
# Registrar todos los microservicios
# Auth Service
curl -X POST http://localhost:8081/api/apps -H "Content-Type: application/json" -d '{
"app_name": "auth-service",
"script_path": "/services/auth/index.js",
"working_directory": "/services/auth",
"user": "services",
"environment": {"PORT": "3001", "NODE_ENV": "production"},
"restart_policy": "always",
"app_type": "nodejs"
}'
# Users Service
curl -X POST http://localhost:8081/api/apps -H "Content-Type: application/json" -d '{
"app_name": "users-service",
"script_path": "/services/users/index.js",
"working_directory": "/services/users",
"user": "services",
"environment": {"PORT": "3002", "NODE_ENV": "production"},
"restart_policy": "always",
"app_type": "nodejs"
}'
# Orders Service
curl -X POST http://localhost:8081/api/apps -H "Content-Type: application/json" -d '{
"app_name": "orders-service",
"script_path": "/services/orders/index.js",
"working_directory": "/services/orders",
"user": "services",
"environment": {"PORT": "3003", "NODE_ENV": "production"},
"restart_policy": "always",
"app_type": "nodejs"
}'
# Iniciar todos
for service in auth-service users-service orders-service; do
curl -X POST http://localhost:8081/api/apps/$service/start
echo "Iniciado: $service"
done
Caso 2: Deployment con Script
#!/bin/bash
# deploy-app.sh
APP_NAME=$1
APP_PATH=$2
PORT=$3
if [ -z "$APP_NAME" ] || [ -z "$APP_PATH" ] || [ -z "$PORT" ]; then
echo "Uso: ./deploy-app.sh <nombre> <path> <puerto>"
exit 1
fi
echo "Desplegando $APP_NAME..."
# Registrar app
curl -X POST http://localhost:8081/api/apps \
-H "Content-Type: application/json" \
-d "{
\"app_name\": \"$APP_NAME\",
\"script_path\": \"$APP_PATH/index.js\",
\"working_directory\": \"$APP_PATH\",
\"user\": \"nodejs\",
\"environment\": {\"PORT\": \"$PORT\", \"NODE_ENV\": \"production\"},
\"restart_policy\": \"always\",
\"app_type\": \"nodejs\"
}"
echo ""
echo "Iniciando $APP_NAME..."
curl -X POST http://localhost:8081/api/apps/$APP_NAME/start
echo ""
echo "Estado de $APP_NAME:"
curl http://localhost:8081/api/apps/$APP_NAME/status | jq
Uso:
./deploy-app.sh mi-nueva-app /opt/apps/mi-nueva-app 3004
Caso 3: Rolling Restart
#!/bin/bash
# rolling-restart.sh - Reinicia servicios uno por uno
APPS=("auth-service" "users-service" "orders-service")
for app in "${APPS[@]}"; do
echo "Reiniciando $app..."
curl -X POST http://localhost:8081/api/apps/$app/restart
# Esperar que esté activo
sleep 5
status=$(curl -s http://localhost:8081/api/apps/$app/status | jq -r '.data.status')
if [ "$status" = "running" ]; then
echo "✅ $app reiniciado correctamente"
else
echo "❌ ERROR: $app no está corriendo"
exit 1
fi
# Delay entre reinici os
sleep 10
done
echo "✅ Rolling restart completado"
Troubleshooting
Problema: App no inicia
# 1. Ver estado en systemd
sudo systemctl status mi-app.service
# 2. Ver logs de systemd
sudo journalctl -u mi-app.service -n 100
# 3. Ver logs en tiempo real
wscat -c ws://localhost:8081/ws/logs/mi-app
# 4. Verificar permisos del archivo
ls -la /path/to/script.js
# 5. Probar ejecución manual
sudo -u nodejs node /path/to/script.js
Problema: Rate limit excedido
# Error: "Rate limit excedido para: mi-app"
# Solución: Esperar 1 segundo entre operaciones
curl -X POST http://localhost:8081/api/apps/mi-app/restart
sleep 2 # Esperar antes de la siguiente operación
curl -X POST http://localhost:8081/api/apps/otra-app/restart
Problema: WebSocket no conecta
# Verificar que el puerto está abierto
sudo netstat -tlnp | grep 8081
# Verificar que hay menos de 5 conexiones activas
# (límite por app)
# Probar con curl primero
curl http://localhost:8081/api/apps
Problema: Permisos sudo
# Verificar configuración
sudo cat /etc/sudoers.d/siax-agent
# Probar manualmente
sudo -u siax-agent sudo systemctl status siax-agent
# Si falla, re-ejecutar deployment
sudo ./desplegar_agent.sh
Scripts Útiles
Monitor Dashboard (Bash)
#!/bin/bash
# dashboard.sh - Dashboard simple en terminal
watch -n 2 '
echo "=== SIAX Monitor Dashboard ==="
echo ""
curl -s http://localhost:8081/api/apps | jq -r ".data.apps[]" | while read app; do
status=$(curl -s http://localhost:8081/api/apps/$app/status)
echo "$status" | jq -r "\"[\(.data.status)] \(.data.name) - PID: \(.data.pid) CPU: \(.data.cpu_usage) RAM: \(.data.memory_usage)\""
done
'
Auto-Restart on Crash
#!/bin/bash
# auto-restart.sh - Reinicia apps crasheadas automáticamente
while true; do
apps=$(curl -s http://localhost:8081/api/apps | jq -r '.data.apps[]')
for app in $apps; do
status=$(curl -s http://localhost:8081/api/apps/$app/status | jq -r '.data.status')
if [ "$status" = "crashed" ] || [ "$status" = "failed" ]; then
echo "[$(date)] Detectado $app en estado $status, reiniciando..."
curl -X POST http://localhost:8081/api/apps/$app/restart
sleep 2
fi
done
sleep 30
done
¡Estos ejemplos cubren los casos de uso más comunes! Para más información, consulta el README.md.