Supervisord: Un gestor de procesos para linux

Hoy he tenido que instalar Supervisord en un servidor para tener controlado un proceso php (bucle) cuando se muera.

El proceso en ubuntu ha pasado a ser bastante directo, con aptitude lo instalamos (actualmente en version 3.0a8-1).

aptitude install supervisor

Despues, creamos una configuracion en /etc/supervisord/conf.d/nombredelservicio.conf

[program:nombredelprograma]
command=/el/archivo/ejecutable
process_name=%(program_name)s
numprocs=1
directory=/tmp
umask=022
priority=999
autostart=true
autorestart=true
startsecs=10
startretries=3
exitcodes=0,2
stopsignal=TERM
stopwaitsecs=10
user=www-data
redirect_stderr=false
stdout_logfile=/var/log/supervisor/nombredelproceso.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=10
stdout_capture_maxbytes=1MB
stderr_logfile=/var/log/supervisor/nombredelproceso-error.log
stderr_logfile_maxbytes=1MB
stderr_logfile_backups=10
stderr_capture_maxbytes=1MB
serverurl=AUTO

A continuacion, el despiece de las directivas de configuración (extraido del manual):

command: Se refiere al ejecutable, podemos referenciarlo directamente con la ruta absoluta, o bien, si esta en el path, invocarlo sin mas. (Mejor usar rutas absolutas por seguridad)
process_name: Se usa para buscar el numero de instancias que hay en ejecucion y compararlo con numprocs.
numprocs: Numero de procesos que es deseable que esten ejecutandose a la vez
directory: Especifica desde que directorio se hace la ejecucion del comando
umask: especifica la umask con la que se lanza el proceso, Interesante en caso de que haya que tocar archivos ajenos.
priority: No es la prioridad del proceso, sino la prioridad de inicio del proceso dentro de supervisord. A menor valor, antes se iniciara en el arranque. Interesante para ordenar dependencias. Es efectivo en comandos generales como start all y stop all
autostart: El servicio ha de iniciarse automaticamente cuando lanzamos supervisord
autorestart: Se ha de tratar de reiniciar el servicio automaticamente. Valores validos: true reinicia siempre el servicio, unexpected solo cuando la salida se produce con un exitcode distinto a los autorizados y false nunca reinicia servicios.
exitcodes: Exitcodes asociados a autorestart
startsecs: Segundos que debe permanecer ejecutandose el servicio para que se considere que ha sido lanzado correctamente
startretries: Numero de veces que podemos intentar lanzarlo antes de que supervisord lo pase al estado FATAL
stopsignal: Señal que se envia al proceso cuando hacemos un stop mediante supervisorctl. Puede ser uno de estos: TERM, HUP, INT, QUIT, KILL, USR1, o USR2.
user: El usuario con el que el proceso se lanza.
environment: Valores en la forma VARIABLE=VALOR que se incluiran en el entorno de ejecucion del servicio
redirect_stderr: Redirigir la salida de los errores al log propio de supervisord en vez de al individual del servicio

*log: opciones de log para su rotado, conservacion y clasificacion, se autoexplican.

Una vez tenemos finalizada la configuracion del servicio, vamos a ver el estado del mismo

root@servidor:/etc/supervisor/conf.d# supervisorctl status
root@servidor:/etc/supervisor/conf.d#

Como? Por que no aparece el servicio? Pues porque supervisor no sabe aun que existe… Vamos a hacer que recargue su configuración:

root@servidor:/etc/supervisor/conf.d# supervisorctl reload
Restarted supervisord
root@servidor:/etc/supervisor/conf.d# supervisorctl status
nombreservicio                   STARTING
root@servidor:/etc/supervisor/conf.d# supervisorctl status
nombreservicio                   RUNNING    pid 28182, uptime 0:00:13

Para este ejemplo, he utilizado como comando «sleep 15», con lo que no entra en estado de error al estar funcionando mas de 10 segundos.

si queremos detener un servicio, por ejemplo para una ventana de mantenimiento, podemos de la siguiente manera.

root@servidor:/etc/supervisor/conf.d# supervisorctl stop nombreservicio
nombreservicio: stopped
root@servidor:/etc/supervisor/conf.d# supervisorctl status
nombreservicio                   STOPPED    Jul 21 12:25 PM

Y de la misma manera, iniciarlo con supervisorctl start nombreservicio.