logging - ¿Cómo puedo registrar la salida estándar de un proceso iniciado por start-stop-daemon?
stdout init.d (10)
Asumiendo que es bash (aunque algunos otros caparazones pueden permitir esto también), la línea:
exec >>/tmp/myDaemon.log
enviará todos los futuros resultados estándar a ese archivo. Eso es porque el exec
sin un nombre de programa solo hace un poco de magia de redirección. Desde la página del hombre bash
:
Si no se especifica el comando, cualquier redirección tendrá efecto en el shell actual.
La gestión de dicho archivo es otro problema, por supuesto.
Estoy usando un script de inicio para ejecutar un proceso simple, que se inicia con:
start-stop-daemon --start --quiet --chuid $DAEMONUSER /
--make-pidfile --pidfile $PIDFILE --background /
--exec $DAEMON $DAEMON_ARGS
El proceso llamado $ DAEMON generalmente imprime información de registro en su salida estándar. Por lo que puedo decir, estos datos no se almacenan en ningún lado.
Me gustaría escribir o anexar el estándar de $ DAEMON a un archivo en alguna parte.
La única solución que conozco es decirle a start-stop-daemon que llame a un shellscript en lugar de $ DAEMON directamente; el script llama a $ DAEMON y escribe en el archivo de registro. Pero eso requiere un script extra que, al igual que la modificación del daemon en sí, parece ser la forma incorrecta de resolver una tarea tan común.
Citando una lista de correo anterior:
https://lists.ubuntu.com/archives/ubuntu-uk/2005-June/000037.html
Un sencillo - y si desea utilizar start-stop-daemon quizás el único - camino a su alrededor es crear un pequeño script que contenga:
#!/bin/sh exec /home/boinc/boinc/boinc > /home/boinc/log/boinc.log
y luego use esa secuencia de comandos como argumento para start-stop-daemon.
Sin embargo, quizás la verdadera pregunta sea si realmente es necesario usar start-stop-daemon en primer lugar.
Con openrc (que es el valor predeterminado en gentoo o alpine linux por ejemplo) start-stop-daemon
tiene las opciones -1
y -2
:
-1, --stdout Redirige stdout al archivo
-2, --stderr Redireccionar stderr al archivo
Entonces puedes escribir:
start-stop-daemon --start --quiet --chuid $DAEMONUSER /
--make-pidfile --pidfile $PIDFILE --background /
--exec $DAEMON $DAEMON_ARGS -1 $LOGFILE -2 $LOGFILE
Necesitas hacer:
start-stop-daemon --start --quiet --chuid $DAEMONUSER /
--make-pidfile --pidfile $PIDFILE --background /
--exec /bin/bash -- -c "$DAEMON $DAEMON_ARGS > /var/log/some.log 2>&1"
Además, si usa --chuid
o --user
, asegúrese de que el usuario pueda escribir en /var/log
o el /var/log/some.log
existente. La mejor manera es que el usuario tenga un /var/log/subdir/
though.
No es demasiado difícil capturar la salida de daemon y guardarla en un archivo:
start-stop-daemon --start --background /
--pidfile $PIDFILE --make-pidfile /
--chuid $DAEMON_USER /
--startas $DAEMON --no-close /
-- $DAEMON_ARGS >> $LOGFILE 2>&1
Sin embargo, esta solución puede ser subóptima para logrotate
.
Podría ser mejor capturar salida a syslog. En Debian esto coincidiría con el comportamiento de los servicios systemd. El siguiente intento directo de reescribir el ejemplo anterior es incorrecto porque deja atrás dos procesos sin padres ("zombie") (registrador y daemon) después de detener el daemon porque start-stop-daemon
termina solo su hijo pero no todos los descendientes:
## Do not use this!
start-stop-daemon --start --background /
--pidfile $PIDFILE --make-pidfile /
--chuid $DAEMON_USER /
--startas /bin/sh /
-- -c """exec $DAEMON $DAEMON_ARGS | /usr/bin/logger --tag $NAME"""
Para que funcione, necesitamos un contenedor que termine con sus hijos al recibir SIGTERM
de start-stop-daemon
. Hay algunos:
start-stop-daemon --start --background /
--pidfile $PIDFILE /
--startas /usr/sbin/duende /
-- --pid $PIDFILE --chroot=/ --uid 65534 --ident $NAME /
/bin/su --login $DAEMON_USER --shell /bin/sh --command """exec ${DAEMON} $DAEMON_ARGS"""
Nota: uid=65534
es un usuario nobody
.
Pros : funciona y es relativamente fácil.
Contras : 4 procesos (supervisor duende
, su fork con privilegios caídos (logger), su
y daemon en sí); obligatorio --chroot
; Si el daemon termina inmediatamente (por ejemplo, un comando no válido) status_of_proc -p $PIDFILE "$DAEMON" "$NAME"
informa que se inició correctamente.
start-stop-daemon --start --pidfile $PIDFILE /
--startas /usr/bin/daemon /
-- --noconfig --name $NAME --stderr=syslog.info --stdout=syslog.info /
-- /bin/su --login $DAEMON_USER --shell /bin/sh --command """exec $DAEMON $DAEMON_ARGS"""
Pros : 3 procesos (supervisor daemon
, su
y daemon en sí).
Contras : Difícil de administrar $PIDFILE
debido a las confusas opciones de la línea de comando de daemon ; Si el daemon termina inmediatamente (por ejemplo, un comando no válido) status_of_proc -p $PIDFILE "$DAEMON" "$NAME"
informa que se inició correctamente.
pipexec ( el ganador ):
start-stop-daemon --start --background /
--pidfile $PIDFILE --make-pidfile /
--chuid $DAEMON_USER /
--startas /usr/bin/pipexec -- -k /
-- [ D $DAEMON $DAEMON_ARGS ] [ L /usr/bin/logger --tag $NAME ] ''{D:2>D:1}'' ''{D:1>L:0}''
Pros : 3 procesos (supervisor pipexec
, logger
y daemon en sí); Si el daemon termina inmediatamente (por ejemplo, un comando no válido) status_of_proc -p $PIDFILE "$DAEMON" "$NAME"
informa correctamente el error.
Contras : ninguno.
Este es el ganador, la solución más fácil y ordenada que parece funcionar bien.
No estoy seguro de si "$ DAEMON $ DAEMON_ARGS> /var/log/some.log 2> & 1" alguna vez cerrará el descriptor de archivo para el archivo de registro ... lo que significa que si su daemon se ejecuta para siempre, no estoy seguro ese logrotate u otros mecanismos para limpiar el espacio en disco funcionarían. Como es> en lugar de >>, el comando sugerido también truncaría los registros existentes al reiniciar. Si quiere ver por qué el daemon se colgó y se reinicia automáticamente, puede que no sea muy útil.
Otra opción podría ser "$ DAEMON | logger". logger es un comando que se registrará en syslog (/ var / log / messages). Si también necesita stderr, creo que podría usar "$ DAEMON 1> & 2 | logger"
Para ampliar la respuesta de ypocat, ya que no me deja comentar:
start-stop-daemon --start --quiet --chuid $DAEMONUSER /
--make-pidfile --pidfile $PIDFILE --background /
--startas /bin/bash -- -c "exec $DAEMON $DAEMON_ARGS > /var/log/some.log 2>&1"
El uso de exec
para ejecutar el daemon permite parar para detener correctamente el proceso secundario en lugar de solo el padre bash.
El uso de --startas
lugar de --exec
asegura que el proceso será detectado correctamente por su pid y no iniciará erróneamente varias instancias del daemon si se invoca el inicio varias veces. De lo contrario, start-stop-daemon buscará un proceso / bin / bash e ignorará el proceso hijo real que ejecuta el daemon.
Parece que debería poder usar ahora el parámetro --no-close
al iniciar start-stop-daemon
para capturar la salida del daemon. Esta nueva característica está disponible en el paquete dpkg
desde la versión 1.16.5 en Debian:
Agregue una nueva opción --no-close para desactivar el cierre de fds en --background.
Esto permitió a la persona que llama ver los mensajes de proceso para la depuración, o para poder redirigir los descriptores de archivos a archivos de registro, syslog o similares.
Por lo general, start-stop-daemon
cierra los descriptores de archivos estándar cuando se ejecuta en segundo plano. Desde la página de manual de start-stop-daemon
:
-C, --no-cerrar
No cierre ningún descriptor de archivo al forzar al daemon a un segundo plano. Se usa con fines de depuración para ver la salida del proceso o para redirigir descriptores de archivo para registrar la salida del proceso. Solo relevante cuando se utiliza --background.
Este trabajó para mí:
start-stop-daemon -b -C -o -c /
$DAEMON_USER -S -x $DAEMON > $DAEMON_LOG 2>&1
Qué tal si:
sudo -u myuser -i start-stop-daemon ...