Plik dziennika ogona na wielu komputerach przez ssh


36

Próbuję tailutworzyć plik dziennika na wielu zdalnych komputerach i przekazać dane wyjściowe na moją lokalną stację roboczą. Chcę, aby połączenia były zamykane po naciśnięciu Ctrl- C.

W tej chwili mam następującą funkcję, która prawie działa zgodnie z przeznaczeniem.

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
}

Połączenia się zamykają i otrzymuję dane wyjściowe z tail. ALE dzieje się coś w rodzaju buforowania, ponieważ dane wyjściowe przychodzą partiami.

A oto część zabawy…

Widzę to samo zachowanie buforowania podczas wykonywania następujących czynności i dołączam „test” do pliku /var/log/server.logna zdalnych komputerach 4-5 razy…

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

… I znalazłem dwa sposoby na wyłączenie…

  1. Dodaj flagę -t do ssh.

    ssh -t server-01 "tail -f /var/log/server.log | grep test"
  2. Usuń ofertę ze zdalnego polecenia.

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

Jednak żadne z tych podejść nie działa w przypadku funkcji wykonywanej na wielu komputerach wymienionych powyżej.

Próbowałem dsh, które mają takie samo zachowanie buforowania podczas wykonywania.

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

To samo tutaj, jeśli usunę cytat, buforowanie zniknie i wszystko działa dobrze.

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

Próbowałem także, parallel-sshktóry działa dokładnie tak samo jak dsh. Czy ktoś może wyjaśnić, co się tutaj dzieje?

Jak rozwiązać ten problem? Byłoby idealnie pasować do prostej, sshjeśli to możliwe.

PS Nie chcę używać multitailani podobnych, ponieważ chcę być w stanie wykonywać dowolne polecenia.


Możesz go dbitailpobrać i pobrać stąd .

Odpowiedzi:


36

To, co widzisz, jest efektem standardowego bufora standardowego grepdostarczanego przez Glibc. Najlepszym rozwiązaniem jest wyłączenie go za pomocą --line-buffered(GNU grep, nie jestem pewien, jakie inne implementacje mogłyby go obsługiwać lub coś podobnego).

Jeśli tak, to dzieje się tylko w niektórych przypadkach:

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

uruchamia całe polecenie w cudzysłowie na serwerze - w ten sposób grepczeka na wypełnienie bufora.

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

działa grepna komputerze lokalnym na wyjściu tailwysyłanym przez kanał ssh.

Kluczową kwestią jest to, że grepdostosowuje swoje zachowanie w zależności od tego, czy stdinjest to terminal, czy nie. Po uruchomieniu ssh -tpolecenie zdalne działa z terminalem sterującym, dzięki czemu pilot grepzachowuje się jak lokalny.


Bardzo dziękuję za szczegółowe wyjaśnienie. Ma to dla mnie sens teraz, a skrypt działa zgodnie z oczekiwaniami z --line-buffered.
deephacks

@deephacks W takim przypadku rozważ zaakceptowanie odpowiedzi - daje to wskazówkę dla innych osób mających ten sam problem.
peterph

1
Buforowanie grep / glibc zależy od jego standardowego wyjścia . ssh tail | grepwyjścia do lokalnego terminala, niebuforowane. ssh -t "tail|grep"wyprowadza na pty, niebuforowane. ssh "tail|grep"wyjścia do potoku (do sshd), buforowane (chyba że --line-buffered).
dave_thompson_085

2

Sprawdź to: multitail

MultiTail umożliwia monitorowanie plików dziennika i danych wyjściowych poleceń w wielu oknach w terminalu, kolorowanie, filtrowanie i scalanie.

Aby dopasować dzienniki na wielu serwerach, użyj:

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

3
Ale nie pozwala ci to zrobić przez ssh, co jest warunkiem tego pytania. (A także pytanie wyraźnie mówi: „nie chcę korzystać z multitail”.)
biskup

1
@bishop: Uważam, że ta krytyka jest po części niesprawiedliwa, ponieważ chociaż w pytaniu mogło być stwierdzone, że nie można korzystać z wielotorowych połączeń, wydaje się, że jest to spowodowane nieporozumieniem. Powyższy przykład pokazuje, jak używać dowolnych poleceń, a także działają zwykłe rozszerzenia powłoki - multitail <(ssh …) <(ssh …)- pozwalając na pożądany wynik, nawet jeśli pierwotnie nie sądzili, że na pytanie można odpowiedzieć.
Chris Adams,

0

Możesz sprawdzić w dzienniku bocznym.

Stworzyłem narzędzie Java, które potrafi czytać lokalne i odległe pliki dziennika za pomocą SSH. Jest dość prosty w użyciu.

Kilka dodatkowych wyjaśnień: https://github.com/pschweitz/insidelog/wiki

Po prostu pobierz wersję odpowiadającą Twojemu systemowi operacyjnemu, natywnego wydania jar do wykonania w środowisku Java Runtime (wymaga java 8_40 lub wyższej):

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

Możesz znaleźć pełną dokumentację (osadzoną również na stronie Githuba)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.