Archivo de registro de cola en varias máquinas a través de ssh

37

Estoy tratando de tailregistrar 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.logen las máquinas remotas 4-5 veces ...

ssh server-01 "tail -f /var/log/server.log | grep test"

... y encontré dos formas de desactivarlo ...

  1. Agregue el indicador -t a ssh.

    ssh -t server-01 "tail -f /var/log/server.log | grep test"
  2. 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-sshcuál funciona exactamente igual quedsh . ¿Alguien puede explicar lo que está pasando aquí?

¿Cómo soluciono este problema? Sería ideal para ir directamente sshsi es posible.

PD: no quiero usar multitailo similar, ya que quiero poder ejecutar comandos arbitrarios.

deephacks
fuente
Puedes pagar dbitaily descargarlo desde aquí .

Respuestas:

36

Lo que ve es el efecto de un buffer estándar stdout grepprovisto 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:

ssh server "tail -f /var/log/server.log | grep test"

ejecuta todo el comando entre comillas en el servidor, por lo tanto, grepespera para llenar su búfer.

ssh server tail -f /var/log/server.log | grep test

se ejecuta grepen su máquina local en la salida tailenviada a través del canal ssh.

La parte clave aquí es que grepajusta su comportamiento dependiendo de si stdines un terminal o no. Cuando ejecuta ssh -t, el comando remoto se ejecuta con un terminal de control y, por lo tanto, el control remoto se grepcomporta como su terminal local.

Peterph
fuente
Muchas gracias por la explicación detallada. Ahora tiene sentido para mí y el script funciona como se esperaba con --line-buffered.
deephacks el
@deephacks En ese caso, considere aceptar la respuesta: da una pista de que otros tienen el mismo problema.
Peter
1
El almacenamiento en búfer de grep / glibc depende de su stdout . ssh tail | grepsalidas 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 (a sshd), almacenadas (a menos que --line-buffered).
dave_thompson_085
2

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:

multitail -l 'ssh user@host1 "tail -f /path/to/log/file"' -l 'ssh user@host2 "tail -f /path/to/log/file"'
LeoChu
fuente
3
Pero no te permite hacerlo a través de ssh, que es una condición de esta pregunta. (Y, además, la pregunta específicamente dice "no quiero usar multitail".)
obispo
1
@ obispo: Creo que esta crítica es injusta en parte porque, aunque la pregunta puede haber especificado que no se usa el multitail, parece deberse a un malentendido. El ejemplo anterior muestra cómo usar comandos arbitrarios y las expansiones de shell regulares también funcionan multitail <(ssh …) <(ssh …), lo que permite el resultado deseado, incluso si no es como originalmente pensaron que la pregunta podría responderse.
Chris Adams
0

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)

Philippe Schweitzer
fuente