daemontools es una colección de herramientas para manejar servicios en Unix.
supervise sirve para monitorear un servicio. Levanta el servicio con un script específico y lo vuelve a levantar si el servicio se cae.
multilog guarda mensajes de error (en realidad la salida de un proceso) en uno o más logs. Opcionalmente puede poner un timestamp en cada línea o excluir líneas que matcheen con patrones especificados. Maneja la rotación de los logs y limita la cantidad de espacio en disco usado. Si el disco se llena, espera y reintenta sin perder datos.
Tabla de Contenidos
Creación de Servicios
Supongamos que tenemos un servicio instalado en /etc/servicio, para hacer que el servicio se levante automáticamente al bootear y si se cae sea levantado automáticamente hay que hacer lo siguiente:
Supongamos que el daemon del servicio se llama /usr/lib/servicio/servd.
/usr/lib/servicio/servd DEBE correr en FOREGROUND (en general la mayoría de los daemons tiene una opción de configuración para correr en foreground).
- Crear el directorio para el run script:
mkdir -m 1755 /etc/servicio/service
Crear el script /etc/servicio/service/run (debe llamarse run).
El contenido debería ser algo así como:
# # combinar stderr con stdout exec 2>&1 # # OJO: NO PONER "&" para que no pase a background # si tuviera una opcion especifica para correr en foreground USARLA exec /usr/lib/servicio/servd <opciones> ###################################################################
- Hacer que el run script sea ejecutable:
chmod 755 /etc/servicio/service/run
- Linkear el directorio correspondiente a /service para que svscan lo controle.
ln -s /etc/servicio/service /service/nombre-servicio
En menos de 5 segundos el servicio estará corriendo. Si el servicio se cae (o se lo mata), se reiniciará automáticamente en menos de 5 segundos.
Control de Servicios
Guía rápida
LEVANTAR un servicio (creando el link)
export RUNSCRIPTDIR=<path absoluto del directorio donde está el run script>
export SERVICENAME=<nombre lógico que se le da al servicio en /service>
ln -s ${RUNSCRIPTDIR} /service/${SERVICENAME}
RESTARTEAR un servicio
export SERVICENAME=<nombre lógico que se le da al servicio en /service>
svc -t /service/${SERVICENAME}
BAJAR totalmente un servicio
export SERVICENAME=<nombre lógico que se le da al servicio en /service>
svc -dx /service/${SERVICENAME} ; rm -fv /service/${SERVICENAME}
BAJAR totalmente un servicio que usa multilog con su log asociado
export SERVICENAME=<nombre lógico que se le da al servicio en /service>
svc -dx /service/${SERVICENAME} /service/${SERVICENAME}/log ; rm -fv /service/${SERVICENAME}
Explicación de los comandos
svscan levanta un supervise por cada subdirectorio del directorio /service. Para controlar los servicios monitoreados por supervise se utiliza el comando svc.
svc -u (up) Si el servicio no está corriendo, levantarlo (ejecuta el script run). Si el servicio para, restartearlo.
svc -d (down) Si el servicio está corriendo, pararlo (enviarle una señal TERM). Luego de que el servicio se apague, no restartearlo.
svc -o (once) Si el servicio no está corriendo, levantarlo. Si el servicio para, no restartearlo.
svc -p (pause) Enviar una señal STOP al servicio.
svc -c (continue) Enviar una señal CONT al servicio.
svc -h (hangup) Enviar una señal HUP al servicio.
svc -a (alarm) Enviar una señal ALRM al servicio.
svc -i (interrupt) Enviar una señal INT al servicio.
svc -t (terminate) Enviar una señal TERM al servicio.
svc -k (kill) Enviar una señal KILL al servicio.
svc -x (exit) supervise va a salir en cuanto el servicio pare (no usar).
Utilización de multilog
multilog es el logger que viene con las daemontools. Mantiene un conjunto de logs rotados automáticamente en un mismo directorio.
Normalmente, multilog lee todo lo que le llega al standard input y lo escribe en un archivo current en el directorio en cuestión.
Si se quiere loggear la salida de un servicio que se controla con supervise, lo que conviene hacer es crear un subdirectorio log en el directorio donde está el run script y poner, a su vez, un run script para el multilog en ese directorio.
Una línea típica de invocación de multilog (desde adentro de un run script puede ser):
exec setuidgid dnslog multilog t s250000 n20 /logs/dns/dnscache
notar que los parámetros de multilog son los que le siguen.
Esta línea le indica que el directorio donde tiene que mantener los logs es /logs/dns/dnscache.
La opción "t" le pide que ponga al principio de cada línea un timestamp en formato TAI64N externo. Esta opción, si está, debe ser la primera.
El programa tai64nlocal es útil para traducir estos timestamps a formato legible por humanos.
La opción "s250000" le indica que cuando el archivo de logging llegue a los 250.000 bytes, debe rotarlo, es decir, renombrarlo y comenzar con un nuevo archivo current vacío. El valor por default (si no se pone "sXXX") es 99999.
La opción "n20" le indica que mantenga a lo sumo 20 archivos de log en el directorio (contando current). Una vez que se alcanza este número, el archivo más viejo se borra. El valor por default (si no se pone "nXX") es 10.
Los archivos rotados tienen su nombre con el siguiente formato: @XXXXXXXX.y, donde "XXXXXXXX" es un string en formato TAI64N externo correspondiente al instante en que fue rotado e "y" es la letra "s" si el archivo fue escrito correctamente sin inconvenientes, o la letra "u" si el archivo fue escrito durante un problema del sistema operativo o algo similar y podría no estar completo.
Troubleshooting
No arranca el servicio
¿Esta ejecutándose el proceso readproctitle?
Revisar la salida del readproctitle (con un ps -x | grep readproctitle | grep -v grep )
¿El servicio tira cosas a stderr? exec 2>&1
Restartear todo (si no esta el readproctitle)
Si no esta el readproctitle, los procesos no volveran a arrancar Asi que debemos restartear los daemontools: Primero bajamos los servicios (para que no se peleen por los mismos puertos/recursos
svc -dx /service/* /service/*/log
Matar en este orden los procesos:
- svscan
- readproctitle
Fijarse que no queden procesos supervise colgando del init (proceso 1).
Fijarse que restartee todo, incluyendo al svscanboot
Restartear los servicios
svc -u /service/*
¿Dónde ver información de debug si no arranca algun proceso (suponiendo que en los logs no salga nada)?
Las daemontools no levantan un proceso que esta configurado en el /service ??
El error probablemente se pueda ver haciendo un
ps -auxwww |grep readproctitle | grep -v grep
En el proceso del readproctitle sale toda la línea del error. Por ejemplo:
root 1192 0.0 0.2 1336 156 ? S May28 5:20 readproctitle service errors: ...ory ../env: file does not exist?envdir: fatal: unable to switch to directory ../env: file does not exist?envdir: fatal: unable to switch to directory ../env: file does not exist?envdir: fatal: unable to switch to directory ../env: file does not exist?envdir: fatal: unable to switch to directory ../env: file does not exist?envdir: fatal: unable to switch to directory ../env: file does not exist?
Más información
Además de la página oficial de daemontools, tenemos:
Los paquetes para debian y las man pages mantenidas por Gerrit Pape