File di registro di coda su più macchine su ssh


37

Sto provando a tailun file di registro su più macchine remote e inoltrare l'output alla mia workstation locale. Voglio chiudere le connessioni quando si preme Ctrl- C.

Al momento ho la seguente funzione che funziona quasi come 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
}

Le connessioni si chiudono e ricevo l'output da tail. MA, c'è un qualche tipo di buffering in corso perché l'output arriva in batch.

Ed ecco la parte divertente ...

Riesco a vedere lo stesso comportamento di buffering quando eseguo quanto segue e accedo "test" al file /var/log/server.logsui computer remoti 4-5 volte ...

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

... e ho trovato due modi per disabilitarlo ...

  1. Aggiungi -t flag a ssh.

    ssh -t server-01 "tail -f /var/log/server.log | grep test"
  2. Rimuovere la quotazione dal comando remoto.

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

Tuttavia, nessuno di questi approcci funziona per la funzione che viene eseguita su più macchine sopra menzionate.

Ho provato dsh, che ha lo stesso comportamento di buffering durante l'esecuzione.

dsh -m server-01,server-02 -c "tail -f /var/log/server.log | grep test"

Lo stesso qui, se rimuovo il preventivo, il buffering scompare e tutto funziona bene.

dsh -m server-01,server-02 -c tail -f /var/log/server.log | grep test

Ho anche provato parallel-sshche funziona esattamente come dsh. Qualcuno può spiegare cosa sta succedendo qui?

Come posso risolvere questo problema? Sarebbe l'ideale per andare dritto, sshse possibile.

PS Non voglio usare multitailo simili poiché voglio essere in grado di eseguire comandi arbitrari.


Puoi effettuare il checkout dbitaile scaricarlo da qui .

Risposte:


36

Quello che vedi è l'effetto di un buffer stdout standard grepfornito da Glibc. La soluzione migliore è disabilitarlo usando --line-buffered(GNU grep, non sono sicuro di quali altre implementazioni potrebbero supportarlo o qualcosa di simile).

Per quanto riguarda il motivo per cui ciò accade solo in alcuni casi:

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

esegue l'intero comando tra virgolette sul server, quindi grepattende di riempire il suo buffer.

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

viene eseguito grepsul computer locale sull'output tailinviato tramite il canale ssh.

La parte fondamentale qui è, che grepregola il suo comportamento a seconda che si stdintratti di un terminale o meno. Quando si esegue ssh -t, il comando remoto è in esecuzione con un terminale di controllo e quindi il telecomando grepsi comporta come quello locale.


Grazie mille per la spiegazione dettagliata. Ora ha senso per me e lo script funziona come previsto con --line-buffered.
deephacks

@deephacks In tal caso, considera di accettare la risposta: fornisce un indizio ad altri che hanno lo stesso problema.
peterph

1
Il buffering di grep / glibc dipende dal suo stdout . ssh tail | grepuscite al terminale locale, senza buffer. ssh -t "tail|grep"produce un pty, senza buffer. ssh "tail|grep"output in una pipe (to sshd), bufferizzato (a meno che --line-buffered).
dave_thompson_085,

2

controllalo: multitail

MultiTail consente di monitorare i file di registro e di comandare l'output in più finestre in un terminale, colorare, filtrare e unire.

Per adattare i log in più server, utilizzare:

multitail -l 'ssh user@host1 "tail -f /path/to/log/file"' -l 'ssh user@host2 "tail -f /path/to/log/file"'

3
Ma non ti consente di farlo su SSH, che è una condizione di questa domanda. (E, inoltre, la domanda dice specificamente "non voglio usare il multitail".)
vescovo

1
@bishop: Penso che questa critica sia in parte ingiusta perché mentre la domanda potrebbe aver specificato di non usare il multitail, sembra essere dovuta a un malinteso. L'esempio sopra mostra come usare i comandi arbitrari e funzionano anche le normali espansioni della shell - multitail <(ssh …) <(ssh …)- permettendo il risultato desiderato anche se non è come inizialmente pensavano di poter rispondere alla domanda.
Chris Adams,

0

Puoi effettuare il checkout nel registro laterale.

Uno strumento Java che ho creato, in grado di leggere file di registro locali e distanti utilizzando SSH. È abbastanza semplice da usare.

Qualche spiegazione in più: https://github.com/pschweitz/insidelog/wiki

Basta scaricare la versione corrispondente al proprio sistema operativo, con eseguibile di rilascio jar nativo all'interno di Java Runtime (richiede Java 8_40 o successivo):

https://github.com/pschweitz/insidelog/releases

Puoi trovare una documentazione completa (incorporata anche nella pagina di Github)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.