Próbuję tail
utworzyć 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.log
na zdalnych komputerach 4-5 razy…
ssh server-01 "tail -f /var/log/server.log | grep test"
… I znalazłem dwa sposoby na wyłączenie…
Dodaj flagę -t do ssh.
ssh -t server-01 "tail -f /var/log/server.log | grep test"
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-ssh
któ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, ssh
jeśli to możliwe.
PS Nie chcę używać multitail
ani podobnych, ponieważ chcę być w stanie wykonywać dowolne polecenia.
dbitail
pobrać i pobrać stąd .Odpowiedzi:
To, co widzisz, jest efektem standardowego bufora standardowego
grep
dostarczanego 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:
uruchamia całe polecenie w cudzysłowie na serwerze - w ten sposób
grep
czeka na wypełnienie bufora.działa
grep
na komputerze lokalnym na wyjściutail
wysyłanym przez kanał ssh.Kluczową kwestią jest to, że
grep
dostosowuje swoje zachowanie w zależności od tego, czystdin
jest to terminal, czy nie. Po uruchomieniussh -t
polecenie zdalne działa z terminalem sterującym, dzięki czemu pilotgrep
zachowuje się jak lokalny.źródło
ssh tail | grep
wyjścia do lokalnego terminala, niebuforowane.ssh -t "tail|grep"
wyprowadza na pty, niebuforowane.ssh "tail|grep"
wyjścia do potoku (dosshd
), buforowane (chyba że--line-buffered
).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:
źródło
multitail <(ssh …) <(ssh …)
- pozwalając na pożądany wynik, nawet jeśli pierwotnie nie sądzili, że na pytanie można odpowiedzieć.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)
źródło