Implementando un watchdog de emergencia
Un watchdog es, como su nombre indica, un perro guardian
;), que en general se encarga de monitorizar un aspecto del sistema para llevar a cabo una acción cuando algo falla. Alguna vez he puesto uno por aquí.
Bueno, es una definición un poco de estar por casa, como lo que voy a explicar ahora: cómo hacer un sencillo watchdog para un servicio, con un shell y herramientas comunes en cualquier entorno Unix.
Ayer un compañero me pidió que le echara una mano con el servidor de un ex-cliente, y como cada vez se puede dedicar menos tiempo a mantener esa máquina, decidimos poner un watchdog para un servicio que había dado problemas ocasionalmente pero no podíamos diagnosticar y corregir.
Vamos a suponer un caso bastante frecuente, en el que el servicio es un solo proceso, que además guarda su PID en un fichero.
Nuestro watchdog haría lo siguiente:
- Comprobar que el fichero
PIDexiste: sino existe, eso es seguramente señal de que el servicio está parado. - Verificar que el proceso indicado por ese
PID, efectivamente está funcionando: sino encontramos el proceso, suponemos que el servicio ha terminado de forma imprevista (y no ha borrado el fichero, como es habitual). - Si se cumple cualquiera de los puntos anteriores, lanzamos el servicio (borrando el fichero del
PIDen caso de ser necesario, para evitar que el servicio piense que ya está en marcha).
Es un watchdog muy rudimentario que correríamos desde cron(8) con la frecuencia que creamos conveniente.
Más o menos la implementación que hice ayer fue la siguiente, un poco revisada para publicarlo aquí (claro :D):
#!/bin/sh # configurable PIDFILE="/var/run/bogom/bogom.pid" DAEMON="/usr/local/libexec/bogom" MAILTO=administrador # Arranca el servicio y manda un mail al admin up_and_notice() { $DAEMON echo "He arrancado $DAEMON (resultado $?), un saludo :)" \ | mail -s "$0 en `hostname`" $MAILTO } # existe el fichero con el PID? if [ ! -f $PIDFILE ]; then up_and_notice exit 0 fi PID=`cat $PIDFILE 2> /dev/null` # hay efectivamente un PID? if [ "X" == "X$PID" ]; then up_and_notice exit 0 fi ps -p $PID 2> /dev/null 1> /dev/null # existe el proceso con ese PID? if [ $? -ne 0 ]; then # si no existe, el fichero sobra rm $PIDFILE up_and_notice exit 0 fi # EOF
En el ejemplo he usado el servicio de bogom (no porque lo necesite, ojo :D), y como bonus se envía un correo al administrador para informar de que se ha levantado otra vez el proceso.
En este caso el watchdog lo tiene que correr root, así que añadiríamos el script en el crontab(5) de ese usuario. Sería muy raro que funcionara tal cual para otros casos, pero como es muy sencillo, seguro que resulta fácil de adaptar.
No me gustan mucho los watchdogs, pero es bueno asumir que todos los programas tienen fallos y a veces causan problemas, y no siempre hay un administrador para ver qué está pasando. En la mayoría de las veces el fallo es anecdótico, y con volver a arrancar: solucionado ;).
Los comentarios están cerrados: los comentarios se cierran automáticamente una vez pasados 15 días. Si quieres comentar algo acerca de la anotación, puedes hacerlo por e-mail.


