Script monitor de sistemas de archivos y particiones

Existen herramientas que nos permiten monitorear distintas cosas en un parque de servidores, como Zabbix, Nagios, etc. Pero hay veces que no es posible, ya sea por recursos o por tiempo, implementar una solución de monitoreo de alto nivel, por lo que recurrimos a los scrtips. Estoy seguro que bash, las llaves publicas y privadas para la autentificación, y cron son unos de nuestros mejores amigos al momento de querer monitorear o administrar máquinas simultaneamente.

Con du podemos saber el uso de disco de nuestro sistema y con un pequeño script en bash podemos mejorar la salida de este comando.

ssh 10.0.0.56 -p5022 "df -hPl"|awk -F ' ' '{print $1,$4,$6,$5}' |egrep -v "Avail|Dispo|Use|Use"

Esto nos devuelve en 4 columnas el dispositivo, espacio disponible, punto de montaje y porcentaje usado.

Algo similar a:

/dev/mapper/VolGroup_25980-LogVol1 3.5G / 75%
/dev/sda1 80M /boot 16%
none 16G /dev/shm 0%
/dev/mapper/VolGroup_25980-LogVolHome 30G /home 69%
/dev/mapper/VolGroup_25980-LogVol2 4.6G /tmp 1%
/dev/mapper/VolGroup_25980-LogVol5 6.6G /usr 29%
/dev/mapper/VolGroup_25980-LogVol4 14G /var 87%
/dev/mapper/VolGroup_25980-mysql 7.0G /var/lib/mysql 63%

Mi idea es trabajar con threshold (umbral) y gatillar eventos según el umbral alcanzado. Por ejemplo, con un threshold del 80% asociado al porcentaje utilizado, que envie emails de “advertencias” y con el 90% notificaciones de “criticidad del sistema de archivos”. Lo que querìa lograr era que todos los dias se monitoreen los sistemas de archivos, generando reportes diarios de los sistemas criticos y, semanalmente, un reporte general, donde me muestre detalladamente los “normales”, “advertencias” y los “criticos”. La salida esperada es algo asi:

[+] Server: x.x.x.x (x.hostname)
[-] [Dev:/dev/hda2] [Mount:/] [Free:4.2G] [Used:5%]

[-] [Dev:/dev/hda1] [Mount:/boot] [Free:83M] [Used:11%]

[-] [Dev:/dev/hda3] [Mount:/home] [Free:3.6G] [Used:19%]

[-] [Dev:/dev/hda6] [Mount:/tmp] [Free:1.7G] [Used:1%]

[-] [Dev:/dev/hda5] [Mount:/usr] [Free:8.6G] [Used:3%]

[-] [Dev:/dev/hda7] [Mount:/var] [Free:12G] [Used:21%]

No critical filesystems

[…] cuando no hay sistemas de archivos criticos y,

[+] Server: y.y.y.y (y.hostname)
[-] [Dev:/dev/mapper/VolGroup00-LogVol00] [Mount:/] [Free:16G] [Used:14%]

[-] [Dev:/dev/sda1] [Mount:/boot] [Free:80M] [Used:15%]

[-] [Dev:/dev/shm] [Mount:/dev/shm] [Free:2.0G] [Used:0%]

[-] [Dev:/dev/mapper/VolGroup00-LogVol02] [Mount:/var] [Free:7.4G] [Used:74%]

[-] [Dev:/dev/mapper/VolGroup00-LogVol03] [Mount:/backup] [Free:13G] [Used:66%]

[-] [Dev:/dev/mapper/VolGroup00-LogVol04] [Mount:/home] [Free:6.6G] [Used:93%] [***CRITICAL***]

[-] [Dev:/dev/mapper/VolGroup00-LogVol05] [Mount:/usr/local] [Free:7.3G] [Used:89%] [***WARNING***]

cuando hay criticos y cuando hay emergencias, es decir, cuando se alcanza el umbral del 90% y 80%, respectivamente.

El script que hice es el siguiente:

#/bin/bash -e
warning_threshold="80%"
critical_threshold="90%"


warnings=0;
critical=0;
for host in $(grep -v ^# ips.txt);
do
	critical_count=0;
	hostname=$(echo -n $host|cut -f1 -d ":")
        ip=$(echo -n $host|cut -f2 -d ":")
        port=$(echo -n $host|cut -f3 -d ":")
	echo "\n[+] Server: $ip ($hostname)"
	filesystems=$(ssh $ip -p$port "df -Phl"|egrep -v 'Avail|Dispo|tmpfs|udev|Uso|Use'|awk -F ' ' '{print $6}');
	for FS in $filesystems;
	do
		alert="";
		temp=$(ssh $ip -p$port "df -hPl $FS"|awk -F ' ' '{print $1,$4,$6,$5}' |egrep -v 'Avail|Dispo|Uso|Use');
		dev=$(echo $temp |cut -f1 -d " ");
		mountpoint=$(echo $temp |cut -f3 -d " ");
		size=$(echo $temp |cut -f2 -d " ");
		used=$(echo $temp |cut -f4 -d " ");
		_wthreshold=$(echo -n $warning_threshold |sed 's/%//g');
		_cthreshold=$(echo -n $critical_threshold |sed 's/%//g');
		_used=$(echo -n $used |sed 's/%//g');
		case "$1" in
			weekly)
				if [ $_used -gt $_wthreshold ]; then
                                        alert="[***WARNING***]"; warning=$(expr $warning + 1);
                                fi
				if [ $_used -gt $_cthreshold ]; then
					alert="[***CRITICAL***]"; critical=$(expr $critical + 1);
				fi
				echo "[-] [Dev:$dev] [Mount:$mountpoint] [Free:$size] [Used:$used] $alert";
				echo "";
			;;
			daily)
                                if [ $_used -gt $_cthreshold ]; then
                                        alert="[***CRITICAL***]";
					critical_count=$(expr $critical_count + 1);
                                	echo "[-] [Dev:$dev] [Mount:$mountpoint] [Free:$size] [Used:$used] $alert";
					echo "";
				fi
			;;
		esac
	done
	if [ $critical_count -eq 0 ]; then
		echo "No critical filesystems"
		critical_count=0;
	fi
done
if [ "$1" = "weekly" ]; then
	echo "________________"
	echo "Warnings: $warning\t|";
	echo "Criticals: $critical\t|";
fi

Para que el script funcione, es necesario que en la misma ruta donde se encuentra, exista el archivo ips.txt que debe tener, bajo la sintaxis hostname:ip:port, la información para que el script se conecté por ssh a las máquinas. Para que sea más dinámico y no requiera la intervención de un humano, la máquina donde se ejecutará el script debe tener una llave privada cuya llave publica esté repartida en los servidores que se desean monitorear.
El script necesita un argumento para funcionar, puede ser “weekly” o “daily”, segun se necesite. Con daily el script genera reportes donde mostrará solamente los criticos, mientras que con weekly hará un reporte general.

En el cron tengo agregado que todos los dias a las 9AM, haga un reporte diario y todos los lunes a las 8AM uno general (weekly) y los envie por correo a los responsables.

8 * * 1 cd /root/du_alert; sh alert.sh weekly |mail -s “Weekly Disk Usage Status” encargado@dominio.cl — -F “System Administrator”
0 9 * * * cd /root/du_alert; sh alert.sh daily |mail -s “Daily Disk Usage Status” encargado@dominio.cl — -F “System Administrator”

1 comentario

  1. exelente aporte !! estaba asiendo algo parecido . pero tu lo tenias listo = le agrego algunos detalles mas . pero muchAs gracias esta genial

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Esto sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.