Files
SIAX-MONITOR/EJEMPLOS.md
pablinux b0489739cf feat: Implementación completa Fase 4 - Sistema de monitoreo con API REST y WebSocket
 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
2026-01-13 08:24:13 -05:00

11 KiB

Ejemplos Prácticos de Uso - SIAX Monitor

Tabla de Contenidos

  1. Instalación
  2. Gestión de Aplicaciones Node.js
  3. Gestión de Aplicaciones Python
  4. Monitoreo y Logs
  5. Casos de Uso Reales
  6. 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.