Tengo un script bash que se ejecuta mientras la máquina Linux está encendida. Lo comienzo como se muestra a continuación:
( /mnt/apps/start.sh 2>&1 | tee /tmp/nginx/debug_log.log ) &
Después de que se inicia, puedo ver el comando tee en mi salida ps como se muestra a continuación:
$ ps | grep tee
418 root 0:02 tee /tmp/nginx/debug_log.log
3557 root 0:00 grep tee
Tengo una función que monitorea el tamaño del registro que produce tee y mata el comando tee cuando el registro alcanza un cierto tamaño:
monitor_debug_log_size() {
## Monitor the file size of the debug log to make sure it does not get too big
while true; do
cecho r "CHECKING DEBUG LOG SIZE... "
debugLogSizeBytes=$(stat -c%s "/tmp/nginx/debug_log.log")
cecho r "DEBUG LOG SIZE: $debugLogSizeBytes"
if [ $((debugLogSizeBytes)) -gt 100000 ]; then
cecho r "DEBUG LOG HAS GROWN TO LARGE... "
sleep 3
#rm -rf /tmp/nginx/debug_log.log 1>/dev/null 2>/dev/null
kill -9 `pgrep -f tee`
fi
sleep 30
done
}
Para mi sorpresa, matar el comando tee también mata por instancia de start.sh. ¿Por qué es esto? ¿Cómo puedo finalizar el comando tee pero que mi start.sh continúe ejecutándose? Gracias.
tee -a
paratee
abrir el archivo en modo anexar, de lo contrario, tee continuará escribiendo en el archivo con el mismo desplazamiento después de truncarlo (y en sistemas que no admiten archivos dispersos como en macOS que reasignar la sección del archivo que conduce a esa posición, ocupando el doble de espacio en disco).logger -s
para que syslog se encargue del registro (-s
para imprimir también en stderr).logrotate
. Gran programaExplicando el "por qué"
En resumen: si el error de escritura no causa que un programa salga (por defecto), tendríamos un desastre. Considere
find . | head -n 10
: no deseafind
seguir ejecutándose, escaneando el resto de su disco duro, después dehead
haber tomado las 10 líneas que necesitaba y continuar.Haciéndolo mejor: gire dentro de su registrador
Considere lo siguiente, que no se usa
tee
en absoluto, como un ejemplo demostrativo:Si se ejecuta como:
... esto comenzará agregando
/tmp/nginx/debug_log
, renombrando el archivo a/tmp/nginx/debug_log.old
más de 100 KB de contenido. Debido a que el registrador mismo está haciendo la rotación, no hay una tubería rota, ningún error ni una ventana de pérdida de datos cuando se realiza la rotación: cada línea se escribirá en un archivo u otro.Por supuesto, implementar esto en bash nativo es ineficiente, pero lo anterior es un ejemplo ilustrativo. Existen numerosos programas disponibles que implementarán la lógica anterior para usted. Considerar:
svlogd
, el registrador de servicios de la suite Runit.s6-log
, una alternativa mantenida activamente de la suite skanet.multilog
de DJB Daemontools, el abuelo de esta familia de herramientas de supervisión y monitoreo de procesos.fuente