El comando crea un binario ejecutable personalizado en /usr/local/bin/server-status utilizando un heredoc que escribe el contenido delimitado por EOF dentro del fichero, garantizando que el script se genera exactamente como se define y evitando expansión de variables en el momento de creación gracias a las comillas simples en 'EOF'. Posteriormente se aplican permisos de ejecución con chmod +x y se registra un alias en .bashrc para invocarlo como si fuera un comando nativo.
El bloque inicial imprime un encabezado coloreado mediante secuencias ANSI del tipo \033[…], lo que mejora la legibilidad en terminal. La instrucción date +"%Y-%m-%d %H:%M:%S" inserta un timestamp en tiempo real que permite correlacionar métricas con eventos posteriores como despliegues o picos de tráfico.
La sección de carga y tiempo activo ejecuta uptime, que devuelve el tiempo de actividad del sistema y el load average en ventanas de 1, 5 y 15 minutos. El load average representa procesos en cola de ejecución o esperando CPU, y su comparación con el número de cores disponibles permite identificar saturación sostenida.
El bloque de memoria utiliza free -h para mostrar RAM total, usada y libre en formato legible, y extrae el consumo de swap con awk. El uso sostenido de swap indica presión de memoria o dimensionamiento inadecuado de PHP-FPM, situación que incrementa latencia en aplicaciones web.
La sección de disco ejecuta df -h / para revisar la partición raíz, habitual contenedor de logs, sesiones y temporales en entornos ecommerce. También consulta inodos con df -i, ya que el agotamiento de inodos puede bloquear escrituras incluso con espacio libre disponible, fenómeno frecuente en catálogos con millones de imágenes pequeñas.
El análisis de entrada/salida utiliza iostat -x 1 1, que captura estadísticas extendidas durante un segundo. El filtrado por dispositivos relevantes permite observar métricas como %util, await y svctm, determinantes para detectar cuellos de botella en almacenamiento.
La detección de procesos en estado D identifica tareas bloqueadas en espera de I/O no interrumpible. Se cuentan mediante ps aux | awk '$8 ~ /D/' y se listan hasta 15 para inspección. Un volumen elevado suele correlacionar con saturación de disco o inestabilidad en sistemas NFS.
Los procesos con mayor consumo se ordenan con ps aux --sort=-%cpu y ps aux --sort=-%mem, mostrando usuario, PID, porcentaje de uso y binario ejecutado. Esta vista permite detectar cron intensivos, importaciones masivas o workers descontrolados.
En la sección de servicios críticos se cuantifican procesos php-fpm y apache2. En arquitecturas ecommerce basadas en PHP, la saturación de workers genera colas de espera y timeouts, por lo que contar procesos totales y bloqueados anticipa degradaciones.
El bloque de red emplea ss -s para resumir sockets y extrae conexiones en estados ESTAB y TIME_WAIT. Un volumen elevado en TIME_WAIT puede reflejar problemas de keep-alive o parámetros del kernel mal ajustados.
La sección de mantenimiento revisa tareas find y scripts de limpieza, útil en catálogos masivos donde se ejecutan rutinas periódicas sobre imágenes y datos. También se consulta la última línea de un log si existe para conocer progreso reciente.
El análisis de errores recientes en Apache busca coincidencias temporales en error.log correspondientes a los últimos cinco minutos. Aunque el filtrado depende del formato del log y del locale del sistema, permite detectar incidencias inmediatamente posteriores a un despliegue.
El bloque final define alertas operativas calculando variables como load average, porcentaje de uso de disco y número de procesos bloqueados, evaluadas contra umbrales numéricos. Si se superan valores críticos se imprimen avisos en rojo; cuando las métricas permanecen dentro de rangos seguros se informa estado saludable, configurando un mecanismo básico de observabilidad reactiva.
El alias añadido en .bashrc integra el comando en el entorno de shell del usuario root, lo que permite ejecutar server-status como una utilidad nativa del sistema sin recordar rutas absolutas.
Desde una perspectiva de arquitectura operativa, el script consolida métricas de CPU, memoria, almacenamiento, red y procesos en una única vista coherente, reduciendo tiempo de diagnóstico ante incidencias y evitando la ejecución manual de múltiples comandos. Su valor reside en la agregación estructurada y en la priorización de señales con impacto directo en el rendimiento web.
cat > /usr/local/bin/server-status << 'EOF'
#!/bin/bash
echo -e "\033[1;33m╔══════════════════════════════════════════════════════════════╗\033[0m"
echo -e "\033[1;33m║ DIAGNÓSTICO COMPLETO DEL SERVIDOR - $(date +"%Y-%m-%d %H:%M:%S") ║\033[0m"
echo -e "\033[1;33m╚══════════════════════════════════════════════════════════════╝\033[0m"
echo -e "\n\033[1;36m=== CARGA Y UPTIME ===\033[0m"
uptime
echo -e "\n\033[1;36m=== MEMORIA ===\033[0m"
free -h
echo " Swap usado: $(free -h | grep Swap | awk '{print $3}')"
echo -e "\n\033[1;36m=== DISCO ===\033[0m"
df -h /
echo " Inodos: $(df -i / | tail -1 | awk '{print $5}' | tr -d '%')% usado"
echo -e "\n\033[1;36m=== I/O DISCO ===\033[0m"
iostat -x 1 1 | grep -E "Device|loop0|dm-0|sda|sdb"
echo -e "\n\033[1;36m=== PROCESOS BLOQUEADOS (estado D) ===\033[0m"
BLOCKED_COUNT=$(ps aux | awk '$8 ~ /D/' | wc -l)
if [ "$BLOCKED_COUNT" -gt 0 ]; then
ps aux | awk '$8 ~ /D/ {printf " PID: %-7s Estado: %-4s Proceso: %-30s Tiempo: %s\n", $2, $8, $11, $10}' | head -15
else
echo -e " \033[1;32m✓ Sin procesos bloqueados\033[0m"
fi
echo " Total bloqueados: $BLOCKED_COUNT procesos"
echo -e "\n\033[1;36m=== TOP 5 PROCESOS POR CPU ===\033[0m"
ps aux --sort=-%cpu | head -6 | tail -5 | awk '{printf " %-15s PID: %-7s CPU: %-6s MEM: %-6s %s\n", $1, $2, $3"%", $4"%", $11}'
echo -e "\n\033[1;36m=== TOP 5 PROCESOS POR MEMORIA ===\033[0m"
ps aux --sort=-%mem | head -6 | tail -5 | awk '{printf " %-15s PID: %-7s MEM: %-6s CPU: %-6s %s\n", $1, $2, $4"%", $3"%", $11}'
echo -e "\n\033[1;36m=== SERVICIOS CRÍTICOS ===\033[0m"
PHP_TOTAL=$(ps aux | grep php-fpm | grep -v grep | wc -l)
PHP_BLOCKED=$(ps aux | grep php-fpm | awk '$8 ~ /D/' | wc -l)
APACHE_TOTAL=$(ps aux | grep apache2 | grep -v grep | wc -l)
echo " PHP-FPM: Total: $PHP_TOTAL | Bloqueados: $PHP_BLOCKED"
echo " Apache: Total: $APACHE_TOTAL procesos"
echo -e "\n\033[1;36m=== CONEXIONES DE RED ===\033[0m"
ss -s
CONN_ESTABLISHED=$(ss -s | grep -oP 'estab \K[0-9]+' 2>/dev/null || echo "0")
CONN_TIMEWAIT=$(ss -s | grep -oP 'timewait \K[0-9]+' 2>/dev/null || echo "0")
echo " Establecidas: $CONN_ESTABLISHED | TimeWait: $CONN_TIMEWAIT"
echo -e "\n\033[1;36m=== PROCESOS DE LIMPIEZA ===\033[0m"
FIND_COUNT=$(ps aux | grep find | grep -v grep | wc -l)
CLEANUP_RUNNING=$(ps aux | grep cleanup | grep -v grep | wc -l)
if [ "$CLEANUP_RUNNING" -gt 0 ]; then
echo -e " Script limpieza: \033[1;32m✓ Ejecutándose\033[0m"
[ -f /root/cleanup_progress.log ] && echo " Última línea: $(tail -1 /root/cleanup_progress.log)"
else
echo -e " Script limpieza: \033[1;33m○ No ejecutándose\033[0m"
fi
echo " Procesos find activos: $FIND_COUNT"
echo -e "\n\033[1;36m=== ÚLTIMOS ERRORES APACHE (5 min) ===\033[0m"
RECENT_ERRORS=$(grep "$(date +'%a %b %d %H:%M' -d '5 minutes ago' 2>/dev/null)" /var/log/apache2/error.log 2>/dev/null | wc -l)
echo " Errores últimos 5 min: $RECENT_ERRORS"
if [ "$RECENT_ERRORS" -gt 0 ]; then
tail -3 /var/log/apache2/error.log 2>/dev/null | sed 's/^/ /'
else
echo -e " \033[1;32m✓ Sin errores recientes\033[0m"
fi
echo -e "\n\033[1;36m=== ALERTAS ===\033[0m"
LOAD_AVG=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | tr -d ',' | awk '{print int($1+0.5)}')
DISK_PERCENT=$(df / | tail -1 | awk '{print $5}' | tr -d '%')
[ "$LOAD_AVG" -gt 20 ] && echo -e " \033[1;31m⚠ CARGA CRÍTICA: $LOAD_AVG (>20)\033[0m"
[ "$DISK_PERCENT" -gt 85 ] && echo -e " \033[1;31m⚠ DISCO ALTO: $DISK_PERCENT% (>85%)\033[0m"
[ "$PHP_BLOCKED" -gt 3 ] && echo -e " \033[1;31m⚠ PHP-FPM BLOQUEADO: $PHP_BLOCKED procesos\033[0m"
[ "$BLOCKED_COUNT" -gt 10 ] && echo -e " \033[1;31m⚠ PROCESOS BLOQUEADOS: $BLOCKED_COUNT (>10)\033[0m"
[ "$LOAD_AVG" -lt 15 ] && [ "$DISK_PERCENT" -lt 95 ] && [ "$PHP_BLOCKED" -eq 0 ] && [ "$BLOCKED_COUNT" -lt 5 ] && echo -e " \033[1;32m✓ Servidor en buen estado\033[0m"
echo -e "\n\033[1;33m╚══════════════════════════════════════════════════════════════╝\033[0m"
EOF
chmod +x /usr/local/bin/server-status
echo "alias server-status='/usr/local/bin/server-status'" >> /root/.bashrc source /root/.bashrc