Estoy tratando de tail
registrar un archivo en varias máquinas remotas y reenviar el resultado a mi estación de trabajo local. Quiero que las conexiones se cierren al presionar Ctrl- C.
Por el momento tengo la siguiente función que casi funciona según lo previsto.
function dogfight_tail() {
logfile=/var/log/server.log
pids=""
for box in 02 03; do
ssh server-$box tail -f $logfile | grep $1 &
pids="$pids $!"
done
trap 'kill -9 $pids' SIGINT
trap wait
}
Las conexiones se cierran y recibo la salida de tail
. PERO, hay algún tipo de almacenamiento en búfer porque la salida viene en lotes.
Y aquí está la parte divertida ...
Puedo ver el mismo comportamiento de almacenamiento en búfer cuando ejecuto lo siguiente y agrego "prueba" al archivo /var/log/server.log
en las máquinas remotas 4-5 veces ...
ssh server-01 "tail -f /var/log/server.log | grep test"
... y encontré dos formas de desactivarlo ...
Agregue el indicador -t a ssh.
ssh -t server-01 "tail -f /var/log/server.log | grep test"
Eliminar la cita del comando remoto.
ssh server-01 tail -f /var/log/server.log | grep test
Sin embargo, ninguno de estos enfoques funciona para la función que se ejecuta en varias máquinas mencionadas anteriormente.
He intentado dsh, que tienen el mismo comportamiento de almacenamiento en búfer al ejecutar.
dsh -m server-01,server-02 -c "tail -f /var/log/server.log | grep test"
Lo mismo aquí, si elimino la cita, el almacenamiento en búfer desaparece y todo funciona bien.
dsh -m server-01,server-02 -c tail -f /var/log/server.log | grep test
También probé parallel-ssh
cuál funciona exactamente igual quedsh
. ¿Alguien puede explicar lo que está pasando aquí?
¿Cómo soluciono este problema? Sería ideal para ir directamente ssh
si es posible.
PD: no quiero usar multitail
o similar, ya que quiero poder ejecutar comandos arbitrarios.
dbitail
y descargarlo desde aquí .Respuestas:
Lo que ve es el efecto de un buffer estándar stdout
grep
provisto por Glibc. La mejor solución es deshabilitarlo usando--line-buffered
(GNU grep, no estoy seguro de qué otras implementaciones podrían soportarlo o algo similar).En cuanto a por qué esto solo sucede en algunos casos:
ejecuta todo el comando entre comillas en el servidor, por lo tanto,
grep
espera para llenar su búfer.se ejecuta
grep
en su máquina local en la salidatail
enviada a través del canal ssh.La parte clave aquí es que
grep
ajusta su comportamiento dependiendo de sistdin
es un terminal o no. Cuando ejecutassh -t
, el comando remoto se ejecuta con un terminal de control y, por lo tanto, el control remoto segrep
comporta como su terminal local.fuente
ssh tail | grep
salidas a la terminal local, sin búfer.ssh -t "tail|grep"
salidas a pty, sin búfer.ssh "tail|grep"
salidas a una tubería (asshd
), almacenadas (a menos que--line-buffered
).mira esto:
multitail
MultiTail le permite monitorear archivos de registro y salida de comandos en múltiples ventanas en una terminal, colorear, filtrar y fusionar.
Para seguir los registros en varios servidores, use:
fuente
multitail <(ssh …) <(ssh …)
, lo que permite el resultado deseado, incluso si no es como originalmente pensaron que la pregunta podría responderse.Puede pagar en el registro lateral.
Una herramienta Java que creé, capaz de leer archivos de registro locales y distantes usando SSH. Es bastante simple de usar.
Algunas explicaciones más: https://github.com/pschweitz/insidelog/wiki
Simplemente descargue la versión correspondiente a su sistema operativo, del ejecutable de lanzamiento de jar nativo dentro de su Java Runtime (requiere java 8_40 o superior):
https://github.com/pschweitz/insidelog/releases
Puede encontrar una documentación completa (incrustada con y en la página de Github también)
fuente