Implementa sistemas de monitoreo proactivo para optimizar el rendimiento del servidor
El monitoreo de recursos es fundamental para mantener sistemas estables y eficientes. Con Bash podemos crear herramientas de monitoreo personalizadas que se adapten a nuestras necesidades específicas y proporcionen alertas tempranas ante problemas potenciales.
Recurso | Comando | Descripción | Umbral Típico |
---|---|---|---|
CPU | top, vmstat, mpstat |
Uso de procesador | < 80% sostenido |
Memoria | free, /proc/meminfo |
Uso de RAM | < 85% |
Disco | df, du, iostat |
Espacio y I/O de disco | < 90% espacio |
Red | ss, netstat, iftop |
Conexiones y tráfico | Depende del uso |
Load Average | uptime, /proc/loadavg |
Carga del sistema | < número de CPUs |
Procesos | ps, pstree |
Procesos activos | Depende del sistema |
#!/bin/bash
# Monitor básico del sistema
# Recopila métricas fundamentales del sistema
# Configuración
HOSTNAME=$(hostname)
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
# Función para obtener uso de CPU
get_cpu_usage() {
# Método 1: usando vmstat
local cpu_idle=$(vmstat 1 2 | tail -1 | awk '{print $15}')
local cpu_usage=$((100 - cpu_idle))
echo "$cpu_usage"
}
# Función para obtener uso de memoria
get_memory_usage() {
local mem_total=$(free -m | awk '/^Mem:/ {print $2}')
local mem_used=$(free -m | awk '/^Mem:/ {print $3}')
local mem_percent=$((mem_used * 100 / mem_total))
echo "$mem_percent|$mem_used|$mem_total"
}
# Función para obtener uso de disco
get_disk_usage() {
local disk_info=$(df -h / | tail -1)
local disk_percent=$(echo "$disk_info" | awk '{print $5}' | sed 's/%//')
local disk_used=$(echo "$disk_info" | awk '{print $3}')
local disk_total=$(echo "$disk_info" | awk '{print $2}')
echo "$disk_percent|$disk_used|$disk_total"
}
# Función para obtener load average
get_load_average() {
local load=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//')
echo "$load"
}
# Función para obtener número de procesos
get_process_count() {
local total_processes=$(ps aux | wc -l)
local running_processes=$(ps aux | awk '$8 ~ /^R/ {count++} END {print count+0}')
local zombie_processes=$(ps aux | awk '$8 ~ /^Z/ {count++} END {print count+0}')
echo "$total_processes|$running_processes|$zombie_processes"
}
# Función para obtener información de red
get_network_info() {
local connections=$(ss -tun | wc -l)
local established=$(ss -tun | grep ESTAB | wc -l)
echo "$connections|$established"
}
# Función para obtener uptime
get_uptime() {
local uptime_seconds=$(awk '{print int($1)}' /proc/uptime)
local days=$((uptime_seconds / 86400))
local hours=$(( (uptime_seconds % 86400) / 3600 ))
local minutes=$(( (uptime_seconds % 3600) / 60 ))
echo "${days}d ${hours}h ${minutes}m"
}
# Función para obtener temperatura (si está disponible)
get_temperature() {
if [ -f /sys/class/thermal/thermal_zone0/temp ]; then
local temp_millic=$(cat /sys/class/thermal/thermal_zone0/temp)
local temp_c=$((temp_millic / 1000))
echo "$temp_c°C"
else
echo "N/A"
fi
}
# Función principal para mostrar todas las métricas
show_system_metrics() {
clear
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║ MONITOR DEL SISTEMA ║"
echo "╠══════════════════════════════════════════════════════════════╣"
echo "║ Servidor: $HOSTNAME"
echo "║ Fecha: $TIMESTAMP"
echo "╠══════════════════════════════════════════════════════════════╣"
# CPU
local cpu_usage
cpu_usage=$(get_cpu_usage)
printf "║ CPU: %3d%% " "$cpu_usage"
if [ "$cpu_usage" -gt 80 ]; then
echo "🔴 ALTO"
elif [ "$cpu_usage" -gt 60 ]; then
echo "🟡 MEDIO"
else
echo "🟢 NORMAL"
fi
# Memoria
IFS='|' read -ra MEM_DATA <<< "$(get_memory_usage)"
local mem_percent="${MEM_DATA[0]}"
local mem_used="${MEM_DATA[1]}"
local mem_total="${MEM_DATA[2]}"
printf "║ Memoria: %3d%% (%s/%s MB) " "$mem_percent" "$mem_used" "$mem_total"
if [ "$mem_percent" -gt 85 ]; then
echo "🔴 ALTO"
elif [ "$mem_percent" -gt 70 ]; then
echo "🟡 MEDIO"
else
echo "🟢 NORMAL"
fi
# Disco
IFS='|' read -ra DISK_DATA <<< "$(get_disk_usage)"
local disk_percent="${DISK_DATA[0]}"
local disk_used="${DISK_DATA[1]}"
local disk_total="${DISK_DATA[2]}"
printf "║ Disco: %3d%% (%s/%s) " "$disk_percent" "$disk_used" "$disk_total"
if [ "$disk_percent" -gt 90 ]; then
echo "🔴 CRÍTICO"
elif [ "$disk_percent" -gt 75 ]; then
echo "🟡 ADVERTENCIA"
else
echo "🟢 NORMAL"
fi
# Load Average
local load_avg
load_avg=$(get_load_average)
echo "║ Load Avg: $load_avg"
# Procesos
IFS='|' read -ra PROC_DATA <<< "$(get_process_count)"
local total_procs="${PROC_DATA[0]}"
local running_procs="${PROC_DATA[1]}"
local zombie_procs="${PROC_DATA[2]}"
echo "║ Procesos: $total_procs total, $running_procs ejecutando, $zombie_procs zombie"
# Red
IFS='|' read -ra NET_DATA <<< "$(get_network_info)"
local connections="${NET_DATA[0]}"
local established="${NET_DATA[1]}"
echo "║ Red: $connections conexiones ($established establecidas)"
# Uptime
local uptime_str
uptime_str=$(get_uptime)
echo "║ Uptime: $uptime_str"
# Temperatura
local temp
temp=$(get_temperature)
echo "║ Temp: $temp"
echo "╚══════════════════════════════════════════════════════════════╝"
}
# Función para modo continuo
continuous_monitoring() {
local interval="${1:-5}"
echo "Iniciando monitoreo continuo (intervalo: ${interval}s)"
echo "Presione Ctrl+C para detener"
while true; do
show_system_metrics
sleep "$interval"
done
}
# Función para generar reporte JSON
generate_json_report() {
local cpu_usage
cpu_usage=$(get_cpu_usage)
IFS='|' read -ra MEM_DATA <<< "$(get_memory_usage)"
IFS='|' read -ra DISK_DATA <<< "$(get_disk_usage)"
IFS='|' read -ra PROC_DATA <<< "$(get_process_count)"
IFS='|' read -ra NET_DATA <<< "$(get_network_info)"
local load_avg
load_avg=$(get_load_average)
local uptime_str
uptime_str=$(get_uptime)
local temp
temp=$(get_temperature)
cat << EOF
{
"hostname": "$HOSTNAME",
"timestamp": "$TIMESTAMP",
"cpu": {
"usage_percent": $cpu_usage
},
"memory": {
"usage_percent": ${MEM_DATA[0]},
"used_mb": ${MEM_DATA[1]},
"total_mb": ${MEM_DATA[2]}
},
"disk": {
"usage_percent": ${DISK_DATA[0]},
"used": "${DISK_DATA[1]}",
"total": "${DISK_DATA[2]}"
},
"load_average": "$load_avg",
"processes": {
"total": ${PROC_DATA[0]},
"running": ${PROC_DATA[1]},
"zombie": ${PROC_DATA[2]}
},
"network": {
"connections": ${NET_DATA[0]},
"established": ${NET_DATA[1]}
},
"uptime": "$uptime_str",
"temperature": "$temp"
}
EOF
}
# Función principal
main() {
case "${1:-show}" in
show)
show_system_metrics
;;
watch|continuous)
continuous_monitoring "${2:-5}"
;;
json)
generate_json_report
;;
help)
echo "Uso: $0 [show|watch|continuous|json|help] [intervalo]"
echo ""
echo "Comandos:"
echo " show - Mostrar métricas una vez (por defecto)"
echo " watch - Monitoreo continuo"
echo " continuous - Alias para watch"
echo " json - Generar reporte en formato JSON"
echo " help - Mostrar esta ayuda"
echo ""
echo "Ejemplos:"
echo " $0 # Mostrar métricas una vez"
echo " $0 watch 10 # Monitoreo cada 10 segundos"
echo " $0 json > report.json # Exportar a JSON"
;;
*)
echo "Comando no válido: $1"
echo "Use '$0 help' para ver opciones disponibles"
exit 1
;;
esac
}
# Ejecutar función principal
main "$@"
./system_monitor.sh
./system_monitor.sh watch 5
./system_monitor.sh json > system_metrics.json
#!/bin/bash
# Monitor avanzado del sistema con alertas y logging
# Versión: 2.0
set -euo pipefail
# Configuración
declare -g CONFIG_FILE="/etc/system_monitor.conf"
declare -g LOG_FILE="/var/log/system_monitor.log"
declare -g ALERT_LOG="/var/log/system_alerts.log"
declare -g PID_FILE="/var/run/system_monitor.pid"
declare -g DATA_DIR="/var/lib/system_monitor"
declare -g ALERTS_ENABLED=true
# Umbrales por defecto
declare -g CPU_WARNING=70
declare -g CPU_CRITICAL=90
declare -g MEM_WARNING=75
declare -g MEM_CRITICAL=90
declare -g DISK_WARNING=80
declare -g DISK_CRITICAL=95
declare -g LOAD_MULTIPLIER=2
# Email/Notificaciones
declare -g ALERT_EMAIL=""
declare -g SLACK_WEBHOOK=""
declare -g ALERT_COOLDOWN=300 # 5 minutos
# Crear directorios necesarios
mkdir -p "$DATA_DIR"
# Función de logging avanzado
log() {
local level="$1"
shift
local message="$*"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
local log_entry="[$timestamp] [$level] $message"
echo "$log_entry" >> "$LOG_FILE"
# También mostrar en stdout si no es daemon
if [ "${DAEMON_MODE:-false}" != "true" ]; then
echo "$log_entry" >&2
fi
}
log_info() { log "INFO" "$@"; }
log_warn() { log "WARN" "$@"; }
log_error() { log "ERROR" "$@"; }
log_alert() {
log "ALERT" "$@"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ALERT: $*" >> "$ALERT_LOG"
}
# Cargar configuración
load_config() {
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
log_info "Configuración cargada desde $CONFIG_FILE"
else
log_warn "Archivo de configuración no encontrado, usando valores por defecto"
fi
}
# Función para enviar alertas por email
send_email_alert() {
local subject="$1"
local message="$2"
if [ -n "$ALERT_EMAIL" ] && command -v mail >/dev/null 2>&1; then
echo "$message" | mail -s "$subject" "$ALERT_EMAIL"
log_info "Alerta enviada por email: $subject"
fi
}
# Función para enviar alertas a Slack
send_slack_alert() {
local message="$1"
local color="$2"
if [ -n "$SLACK_WEBHOOK" ] && command -v curl >/dev/null 2>&1; then
local payload=$(cat << EOF
{
"attachments": [
{
"color": "$color",
"title": "Alerta del Sistema - $(hostname)",
"text": "$message",
"ts": $(date +%s)
}
]
}
EOF
)
curl -s -X POST -H 'Content-type: application/json' \
--data "$payload" "$SLACK_WEBHOOK" >/dev/null
log_info "Alerta enviada a Slack"
fi
}
# Sistema de cooldown para alertas
check_alert_cooldown() {
local alert_type="$1"
local cooldown_file="$DATA_DIR/cooldown_$alert_type"
local current_time=$(date +%s)
if [ -f "$cooldown_file" ]; then
local last_alert=$(cat "$cooldown_file")
local time_diff=$((current_time - last_alert))
if [ "$time_diff" -lt "$ALERT_COOLDOWN" ]; then
return 1 # Todavía en cooldown
fi
fi
echo "$current_time" > "$cooldown_file"
return 0 # OK para enviar alerta
}
# Monitor de CPU
monitor_cpu() {
local cpu_usage
# Obtener promedio de CPU en los últimos 5 segundos
cpu_usage=$(sar -u 1 5 | tail -1 | awk '{print 100 - $8}' | cut -d. -f1)
if [ "$cpu_usage" -ge "$CPU_CRITICAL" ]; then
if check_alert_cooldown "cpu_critical"; then
local alert_msg="CPU CRÍTICA: ${cpu_usage}% de uso"
log_alert "$alert_msg"
send_email_alert "CRÍTICO: Alta carga de CPU en $(hostname)" "$alert_msg"
send_slack_alert "$alert_msg" "danger"
fi
echo "CRITICAL|$cpu_usage"
elif [ "$cpu_usage" -ge "$CPU_WARNING" ]; then
if check_alert_cooldown "cpu_warning"; then
local alert_msg="CPU ALTA: ${cpu_usage}% de uso"
log_alert "$alert_msg"
send_slack_alert "$alert_msg" "warning"
fi
echo "WARNING|$cpu_usage"
else
echo "OK|$cpu_usage"
fi
}
# Monitor de memoria
monitor_memory() {
local mem_percent
mem_percent=$(free | awk '/^Mem:/ {printf("%.0f", $3/$2*100)}')
if [ "$mem_percent" -ge "$MEM_CRITICAL" ]; then
if check_alert_cooldown "mem_critical"; then
local alert_msg="MEMORIA CRÍTICA: ${mem_percent}% de uso"
log_alert "$alert_msg"
send_email_alert "CRÍTICO: Alta uso de memoria en $(hostname)" "$alert_msg"
send_slack_alert "$alert_msg" "danger"
fi
echo "CRITICAL|$mem_percent"
elif [ "$mem_percent" -ge "$MEM_WARNING" ]; then
if check_alert_cooldown "mem_warning"; then
local alert_msg="MEMORIA ALTA: ${mem_percent}% de uso"
log_alert "$alert_msg"
send_slack_alert "$alert_msg" "warning"
fi
echo "WARNING|$mem_percent"
else
echo "OK|$mem_percent"
fi
}
# Monitor de disco
monitor_disk() {
local disk_usage
disk_usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
if [ "$disk_usage" -ge "$DISK_CRITICAL" ]; then
if check_alert_cooldown "disk_critical"; then
local alert_msg="DISCO CRÍTICO: ${disk_usage}% de uso en /"
log_alert "$alert_msg"
send_email_alert "CRÍTICO: Poco espacio en disco en $(hostname)" "$alert_msg"
send_slack_alert "$alert_msg" "danger"
fi
echo "CRITICAL|$disk_usage"
elif [ "$disk_usage" -ge "$DISK_WARNING" ]; then
if check_alert_cooldown "disk_warning"; then
local alert_msg="DISCO ALTO: ${disk_usage}% de uso en /"
log_alert "$alert_msg"
send_slack_alert "$alert_msg" "warning"
fi
echo "WARNING|$disk_usage"
else
echo "OK|$disk_usage"
fi
}
# Monitor de load average
monitor_load() {
local cpu_count
cpu_count=$(nproc)
local load_avg
load_avg=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//')
local load_threshold=$(echo "$cpu_count * $LOAD_MULTIPLIER" | bc -l)
if (( $(echo "$load_avg > $load_threshold" | bc -l) )); then
if check_alert_cooldown "load_high"; then
local alert_msg="CARGA ALTA: Load average $load_avg (umbral: $load_threshold)"
log_alert "$alert_msg"
send_slack_alert "$alert_msg" "warning"
fi
echo "WARNING|$load_avg"
else
echo "OK|$load_avg"
fi
}
# Monitor de servicios críticos
monitor_services() {
local services=("ssh" "nginx" "apache2" "mysql" "postgresql" "docker")
local failed_services=()
for service in "${services[@]}"; do
if systemctl is-enabled "$service" >/dev/null 2>&1; then
if ! systemctl is-active "$service" >/dev/null 2>&1; then
failed_services+=("$service")
fi
fi
done
if [ ${#failed_services[@]} -gt 0 ]; then
if check_alert_cooldown "services_down"; then
local alert_msg="SERVICIOS CAÍDOS: ${failed_services[*]}"
log_alert "$alert_msg"
send_email_alert "CRÍTICO: Servicios caídos en $(hostname)" "$alert_msg"
send_slack_alert "$alert_msg" "danger"
fi
echo "CRITICAL|${#failed_services[@]} servicios caídos"
else
echo "OK|Todos los servicios activos"
fi
}
# Almacenar métricas históricas
store_metrics() {
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
local cpu_result
cpu_result=$(monitor_cpu)
local mem_result
mem_result=$(monitor_memory)
local disk_result
disk_result=$(monitor_disk)
local load_result
load_result=$(monitor_load)
# Extraer valores numéricos
local cpu_value=$(echo "$cpu_result" | cut -d'|' -f2)
local mem_value=$(echo "$mem_result" | cut -d'|' -f2)
local disk_value=$(echo "$disk_result" | cut -d'|' -f2)
local load_value=$(echo "$load_result" | cut -d'|' -f2)
# Guardar en CSV para análisis posterior
echo "$timestamp,$cpu_value,$mem_value,$disk_value,$load_value" >> "$DATA_DIR/metrics.csv"
# Mantener solo los últimos 7 días de datos
if [ -f "$DATA_DIR/metrics.csv" ]; then
tail -n 10080 "$DATA_DIR/metrics.csv" > "$DATA_DIR/metrics.csv.tmp"
mv "$DATA_DIR/metrics.csv.tmp" "$DATA_DIR/metrics.csv"
fi
}
# Generar reporte detallado
generate_report() {
local report_file="${1:-/tmp/system_report_$(date +%Y%m%d_%H%M%S).html}"
log_info "Generando reporte detallado: $report_file"
cat > "$report_file" << 'EOF'
Reporte del Sistema
EOF
echo "Reporte del Sistema - $(hostname)
" >> "$report_file"
echo "Generado el: $(date)
" >> "$report_file"
echo "Estado Actual
" >> "$report_file"
# CPU
local cpu_result
cpu_result=$(monitor_cpu)
local cpu_status=$(echo "$cpu_result" | cut -d'|' -f1)
local cpu_value=$(echo "$cpu_result" | cut -d'|' -f2)
echo "" >> "$report_file"
echo "CPU: ${cpu_value}% - $cpu_status" >> "$report_file"
echo "" >> "$report_file"
# Memoria
local mem_result
mem_result=$(monitor_memory)
local mem_status=$(echo "$mem_result" | cut -d'|' -f1)
local mem_value=$(echo "$mem_result" | cut -d'|' -f2)
echo "" >> "$report_file"
echo "Memoria: ${mem_value}% - $mem_status" >> "$report_file"
echo "" >> "$report_file"
# Historial reciente si existe
if [ -f "$DATA_DIR/metrics.csv" ]; then
echo "Historial Reciente (últimas 24 horas)
" >> "$report_file"
echo "" >> "$report_file"
echo "Timestamp CPU % Memoria % Disco % Load " >> "$report_file"
tail -n 288 "$DATA_DIR/metrics.csv" | while IFS=, read -r timestamp cpu mem disk load; do
echo "$timestamp $cpu $mem $disk $load " >> "$report_file"
done
echo "
" >> "$report_file"
fi
echo "" >> "$report_file"
log_info "Reporte generado: $report_file"
echo "$report_file"
}
# Modo daemon
daemon_mode() {
local interval="${1:-60}"
log_info "Iniciando modo daemon (intervalo: ${interval}s)"
# Crear archivo PID
echo $$ > "$PID_FILE"
# Configurar traps para limpieza
trap 'rm -f "$PID_FILE"; exit 0' EXIT INT TERM
export DAEMON_MODE=true
while true; do
store_metrics
sleep "$interval"
done
}
# Función de ayuda
show_help() {
cat << EOF
Monitor Avanzado del Sistema v2.0
USO:
$0 [COMANDO] [OPCIONES]
COMANDOS:
monitor Ejecutar monitoreo una vez
daemon [SECS] Ejecutar como daemon (default: 60s)
report [FILE] Generar reporte HTML
status Mostrar estado actual
stop Detener daemon
config Mostrar configuración actual
EJEMPLOS:
$0 monitor # Monitoreo único
$0 daemon 30 # Daemon cada 30 segundos
$0 report /tmp/report.html # Generar reporte
$0 stop # Detener daemon
ARCHIVOS:
Config: $CONFIG_FILE
Log: $LOG_FILE
Datos: $DATA_DIR/
CONFIGURACIÓN (en $CONFIG_FILE):
CPU_WARNING=70
CPU_CRITICAL=90
MEM_WARNING=75
MEM_CRITICAL=90
DISK_WARNING=80
DISK_CRITICAL=95
ALERT_EMAIL="[email protected]"
SLACK_WEBHOOK="https://hooks.slack.com/..."
EOF
}
# Función principal
main() {
load_config
case "${1:-monitor}" in
monitor)
log_info "Ejecutando monitoreo único"
store_metrics
echo "Monitoreo completado. Ver logs en $LOG_FILE"
;;
daemon)
daemon_mode "${2:-60}"
;;
report)
generate_report "${2:-}"
;;
status)
echo "=== ESTADO DEL SISTEMA ==="
echo "CPU: $(monitor_cpu)"
echo "Memoria: $(monitor_memory)"
echo "Disco: $(monitor_disk)"
echo "Load: $(monitor_load)"
echo "Servicios: $(monitor_services)"
;;
stop)
if [ -f "$PID_FILE" ]; then
local pid=$(cat "$PID_FILE")
kill "$pid" 2>/dev/null && echo "Daemon detenido" || echo "No se pudo detener el daemon"
rm -f "$PID_FILE"
else
echo "Daemon no está ejecutándose"
fi
;;
config)
echo "=== CONFIGURACIÓN ACTUAL ==="
echo "CPU Warning: $CPU_WARNING%"
echo "CPU Critical: $CPU_CRITICAL%"
echo "Memory Warning: $MEM_WARNING%"
echo "Memory Critical: $MEM_CRITICAL%"
echo "Disk Warning: $DISK_WARNING%"
echo "Disk Critical: $DISK_CRITICAL%"
echo "Alert Email: ${ALERT_EMAIL:-'No configurado'}"
echo "Slack Webhook: ${SLACK_WEBHOOK:+'Configurado'}"
;;
help|--help|-h)
show_help
;;
*)
echo "Comando no válido: $1"
show_help
exit 1
;;
esac
}
# Verificar dependencias
check_dependencies() {
local deps=("sar" "bc" "nproc")
local missing=()
for dep in "${deps[@]}"; do
if ! command -v "$dep" >/dev/null 2>&1; then
missing+=("$dep")
fi
done
if [ ${#missing[@]} -gt 0 ]; then
echo "Error: Dependencias faltantes: ${missing[*]}" >&2
echo "Instale: apt install sysstat bc coreutils" >&2
exit 1
fi
}
# Verificar dependencias y ejecutar
check_dependencies
main "$@"
#!/bin/bash
# Generador de dashboard web para monitoreo del sistema
# Crea un dashboard HTML que se actualiza automáticamente
set -euo pipefail
# Configuración
DASHBOARD_DIR="/var/www/html/monitor"
DASHBOARD_FILE="$DASHBOARD_DIR/index.html"
DATA_FILE="$DASHBOARD_DIR/data.json"
UPDATE_INTERVAL=30
# Crear directorio si no existe
mkdir -p "$DASHBOARD_DIR"
# Función para obtener métricas del sistema
collect_metrics() {
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# CPU
local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//')
# Memoria
local mem_info=$(free -m)
local mem_total=$(echo "$mem_info" | awk '/^Mem:/ {print $2}')
local mem_used=$(echo "$mem_info" | awk '/^Mem:/ {print $3}')
local mem_percent=$((mem_used * 100 / mem_total))
# Disco
local disk_info=$(df -h / | tail -1)
local disk_percent=$(echo "$disk_info" | awk '{print $5}' | sed 's/%//')
local disk_used=$(echo "$disk_info" | awk '{print $3}')
local disk_total=$(echo "$disk_info" | awk '{print $2}')
# Load average
local load_avg=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//')
# Procesos
local processes=$(ps aux | wc -l)
# Red (conexiones establecidas)
local connections=$(ss -tun | grep ESTAB | wc -l)
# Uptime
local uptime_seconds=$(awk '{print int($1)}' /proc/uptime)
local uptime_formatted=$(printf '%dd %dh %dm' $((uptime_seconds/86400)) $((uptime_seconds%86400/3600)) $((uptime_seconds%3600/60)))
# Servicios (verificar algunos servicios comunes)
local services_status=""
local services=("ssh" "nginx" "apache2" "mysql" "postgresql")
for service in "${services[@]}"; do
if systemctl is-enabled "$service" >/dev/null 2>&1; then
if systemctl is-active "$service" >/dev/null 2>&1; then
services_status+="\"$service\": \"active\","
else
services_status+="\"$service\": \"inactive\","
fi
fi
done
services_status=${services_status%,} # Remover última coma
# Generar JSON
cat > "$DATA_FILE" << EOF
{
"timestamp": "$timestamp",
"hostname": "$(hostname)",
"cpu": {
"usage": ${cpu_usage:-0}
},
"memory": {
"total": $mem_total,
"used": $mem_used,
"percent": $mem_percent
},
"disk": {
"percent": $disk_percent,
"used": "$disk_used",
"total": "$disk_total"
},
"load_average": "$load_avg",
"processes": $processes,
"network": {
"connections": $connections
},
"uptime": "$uptime_formatted",
"services": {
$services_status
}
}
EOF
}
# Generar dashboard HTML
generate_dashboard() {
cat > "$DASHBOARD_FILE" << 'EOF'
Monitor del Sistema
🖥️ Monitor del Sistema
Cargando...
Procesador (CPU)
--
Cargando...
Memoria RAM
--
Cargando...
Almacenamiento
--
Cargando...
Carga del Sistema
--
Load Average
Procesos
--
Procesos activos
Conexiones de Red
--
Conexiones establecidas
Tiempo Activo
--
Uptime del sistema
Estado de Servicios
Cargando...
EOF
}
# Función principal para iniciar el dashboard
start_dashboard() {
echo "Generando dashboard web en $DASHBOARD_DIR"
# Generar dashboard HTML
generate_dashboard
# Generar datos iniciales
collect_metrics
echo "Dashboard generado exitosamente!"
echo "Archivo HTML: $DASHBOARD_FILE"
echo "Datos JSON: $DATA_FILE"
echo ""
echo "Para servir el dashboard:"
echo "1. Con Python: cd $DASHBOARD_DIR && python3 -m http.server 8080"
echo "2. Con Node.js: cd $DASHBOARD_DIR && npx http-server -p 8080"
echo "3. Con nginx: configure el directorio raíz a $DASHBOARD_DIR"
echo ""
echo "Luego accede a http://localhost:8080"
}
# Función para actualizar datos en bucle
update_loop() {
echo "Iniciando bucle de actualización de datos (cada ${UPDATE_INTERVAL}s)"
echo "Presiona Ctrl+C para detener"
while true; do
collect_metrics
echo "Datos actualizados: $(date)"
sleep "$UPDATE_INTERVAL"
done
}
# Función principal
main() {
case "${1:-start}" in
start|generate)
start_dashboard
;;
update)
collect_metrics
echo "Datos actualizados"
;;
loop|daemon)
if [ ! -f "$DASHBOARD_FILE" ]; then
start_dashboard
fi
update_loop
;;
serve)
if [ ! -f "$DASHBOARD_FILE" ]; then
start_dashboard
fi
echo "Iniciando servidor web en puerto 8080..."
cd "$DASHBOARD_DIR"
if command -v python3 >/dev/null 2>&1; then
python3 -m http.server 8080
elif command -v python >/dev/null 2>&1; then
python -m SimpleHTTPServer 8080
elif command -v node >/dev/null 2>&1; then
npx http-server -p 8080
else
echo "No se encontró Python o Node.js para servir el dashboard"
echo "Instale uno de estos o use nginx/apache"
exit 1
fi
;;
help)
echo "Uso: $0 [start|update|loop|serve|help]"
echo ""
echo "Comandos:"
echo " start - Generar dashboard inicial"
echo " update - Actualizar datos una vez"
echo " loop - Actualizar datos continuamente"
echo " serve - Generar y servir dashboard web"
echo " help - Mostrar esta ayuda"
;;
*)
echo "Comando no válido: $1"
echo "Use '$0 help' para ver opciones disponibles"
exit 1
;;
esac
}
# Verificar permisos para crear directorios
if [ ! -w "$(dirname "$DASHBOARD_DIR")" ]; then
echo "Advertencia: No se puede escribir en $(dirname "$DASHBOARD_DIR")"
echo "Usando directorio temporal..."
DASHBOARD_DIR="/tmp/system_monitor_dashboard"
DASHBOARD_FILE="$DASHBOARD_DIR/index.html"
DATA_FILE="$DASHBOARD_DIR/data.json"
mkdir -p "$DASHBOARD_DIR"
fi
# Ejecutar función principal
main "$@"
sudo ./web_dashboard.sh serve
Desarrolla un sistema para monitorear múltiples servidores:
Crea un sistema de monitoreo con capacidades predictivas: