Protokolldatei auf mehreren Rechnern über ssh nachverfolgen

36

Ich versuche, taileine Protokolldatei auf mehreren Remotecomputern zu erstellen und die Ausgabe an meine lokale Arbeitsstation weiterzuleiten. Ich möchte, dass die Verbindungen geschlossen werden, wenn ich Ctrl- drücke C.

Im Moment habe ich folgende Funktion, die fast wie vorgesehen funktioniert .

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
}

Die Verbindungen werden geschlossen und ich erhalte die Ausgabe von tail. ABER es gibt eine Art Pufferung, da die Ausgabe stapelweise erfolgt.

Und hier ist der lustige Teil ...

Ich kann das gleiche Pufferverhalten feststellen, wenn ich Folgendes ausführe und "test" /var/log/server.log4-5 Mal an die Datei auf den Remotecomputern anhänge ...

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

… Und zwei Möglichkeiten gefunden, es zu deaktivieren…

  1. Füge -t Flag zu ssh hinzu.

    ssh -t server-01 "tail -f /var/log/server.log | grep test"
  2. Entfernen Sie das Zitat aus dem Remote-Befehl.

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

Keiner dieser Ansätze funktioniert jedoch für die Funktion, die auf mehreren oben genannten Maschinen ausgeführt wird.

Ich habe versucht, dsh, die das gleiche Pufferverhalten beim Ausführen haben.

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

Gleiches gilt, wenn ich das Zitat entferne, verschwindet die Pufferung und alles funktioniert einwandfrei.

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

Auch ausprobiert parallel-sshwas genauso funktioniert wie dsh. Kann jemand erklären, was hier los ist?

Wie behebe ich dieses Problem? Wäre ideal, sshwenn möglich mit Straight zu gehen .

PS Ich möchte keine multitailoder ähnliche Befehle verwenden, da ich willkürliche Befehle ausführen können.

Deephacks
quelle
Sie können dbitailes hier auschecken und herunterladen .

Antworten:

36

Was Sie sehen, ist die Wirkung eines grepvon Glibc bereitgestellten Standard-Standardausgabepuffers . Die beste Lösung ist, es zu deaktivieren --line-buffered(GNU grep, ich bin mir nicht sicher, welche anderen Implementierungen es unterstützen könnten oder ähnliches).

Was , warum dies geschieht nur in einigen Fällen:

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

Führt den gesamten Befehl in Anführungszeichen auf dem Server aus und grepwartet, bis der Puffer gefüllt ist.

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

Läuft grepauf Ihrem lokalen Rechner auf dem Ausgang tail, der über den SSH-Kanal gesendet wird.

Der entscheidende Teil hier ist, dass grepdas Verhalten angepasst wird, je nachdem, ob stdines sich um ein Terminal handelt oder nicht. Wenn Sie ausführen ssh -t, wird der Remote-Befehl mit einem steuernden Terminal ausgeführt, und daher grepverhält sich der Remote-Befehl wie Ihr lokaler.

peterph
quelle
Vielen Dank für die ausführliche Erklärung. Es macht jetzt für mich Sinn und das Skript funktioniert wie erwartet mit --line-buffered.
Deephacks
@deephacks In diesem Fall ziehen Sie bitte in Betracht, die Antwort zu akzeptieren - sie gibt anderen, die das gleiche Problem haben, einen Hinweis.
Peterph
1
Die Pufferung von grep / glibc hängt von der Standardausgabe ab . ssh tail | grepAusgänge zum lokalen Terminal, ungepuffert. ssh -t "tail|grep"Ausgänge zu einer Pty, ungepuffert. ssh "tail|grep"Ausgaben an eine Pipe (to sshd), gepuffert (es sei denn --line-buffered).
Dave_thompson_085
2

schau dir das an: multitail

Mit MultiTail können Sie Protokolldateien und Befehlsausgaben in mehreren Fenstern eines Terminals überwachen, einfärben, filtern und zusammenführen.

Um die Protokolle auf mehreren Servern zu erweitern, verwenden Sie:

multitail -l 'ssh user@host1 "tail -f /path/to/log/file"' -l 'ssh user@host2 "tail -f /path/to/log/file"'
LeoChu
quelle
3
Aber Sie können es nicht über ssh tun, was eine Bedingung für diese Frage ist. (Und in der Frage steht auch ausdrücklich "Ich möchte kein Multitail verwenden".)
Bischof
1
@bishop: Ich halte diese Kritik zum Teil für unfair, da die Frage zwar angegeben haben mag, kein Multitail zu verwenden, sie aber auf ein Missverständnis zurückzuführen zu sein scheint. Das obige Beispiel zeigt, wie beliebige Befehle verwendet werden und die regulären Shell-Erweiterungen funktionieren ebenfalls - multitail <(ssh …) <(ssh …)- und ermöglichen das gewünschte Ergebnis, auch wenn sie ursprünglich nicht der Meinung waren, dass die Frage beantwortet werden könnte.
Chris Adams
0

Sie können in'side log auschecken.

Ein von mir erstelltes Java-Tool, das lokale und entfernte Protokolldateien mit SSH lesen kann. Es ist ziemlich einfach zu bedienen.

Weitere Erklärungen: https://github.com/pschweitz/insidelog/wiki

Laden Sie einfach die Ihrem Betriebssystem entsprechende Version der in Ihrer Java Runtime ausführbaren JAR-Version herunter (erfordert Java 8_40 oder höher):

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

Sie finden eine vollständige Dokumentation (eingebettet in und auf Githubs Seite).

Philippe Schweitzer
quelle