Файл журналу хвоста на декількох машинах через ssh


37

Я намагаюся tailстворити файл журналу на декількох віддалених машинах і переслати висновок на свою локальну робочу станцію. Я хочу, щоб з'єднання закривалися при натисканні Ctrl- C.

На даний момент у мене є така функція, яка майже працює за призначенням.

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
}

З'єднання закриваються, і я отримую вихід від tail. АЛЕ, відбувається якесь буферизація, оскільки вихід надходить партіями.

А ось і найцікавіша частина ...

Я бачу таку саму буферну поведінку під час виконання наступного та додаю "тест" до файлу /var/log/server.logна віддалених машинах 4-5 разів ...

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

… І знайшов два способи відключити це…

  1. Додайте прапор до ssh.

    ssh -t server-01 "tail -f /var/log/server.log | grep test"
  2. Видаліть цитату з віддаленої команди.

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

Однак жоден з цих підходів не працює для функції, яка виконується на кількох згаданих вище машинах.

Я спробував dsh, які мають однакову буферну поведінку під час виконання.

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

Тут же, якщо я видалю цитату, буферизація проходить і все працює добре.

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

Також спробував, parallel-sshякий працює точно так само, як dsh. Хтось може пояснити, що тут відбувається?

Як виправити цю проблему? Було б ідеально їхати з прямою, sshякщо можливо.

PS Я не хочу використовувати multitailабо подібне, оскільки я хочу мати можливість виконувати довільні команди.


Оформити замовлення dbitailта завантажити його можна звідси .

Відповіді:


36

Те, що ви бачите, - це ефект від стандартного буфера stdout, grepнаданого Glibc. Найкраще рішення - відключити його за допомогою --line-buffered(GNU grep, я не впевнений, які інші програми можуть його підтримувати чи щось подібне).

Що стосується того, чому це відбувається лише в деяких випадках:

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

виконує всю команду в лапках на сервері - таким чином grepчекає заповнення свого буфера.

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

працює grepна локальній машині на виході, що tailнадсилається через ssh-канал.

Ключова частина тут полягає в тому, що grepкоригує свою поведінку залежно від того stdin, термінал це чи ні. Під час запуску ssh -tвіддалена команда працює з керуючим терміналом, і, таким чином, пульт grepповодиться як ваш локальний.


Велике спасибі за детальне пояснення. Для мене це має сенс, і сценарій працює так, як очікувалося, з --line-buferi.
deephacks

@deephacks У цьому випадку, будь ласка, подумайте про прийняття відповіді - це дає підказку іншим, хто має таку ж проблему.
петерф

1
буферизація grep / glibc залежить від її викладу . ssh tail | grepвиходи на локальний термінал, небуферовані. ssh -t "tail|grep"виводить на pty, небуферовані. ssh "tail|grep"виходи в трубу (до sshd), буферизовану (якщо немає --line-buffered).
dave_thompson_085

2

Перевір це: multitail

MultiTail дозволяє відстежувати логіни та команди команд у кількох вікнах у терміналі, розфарбовувати, фільтрувати та об’єднувати.

Для хвостових журналів на декількох серверах використовуйте:

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

3
Але це не дозволяє вам робити це за ssh, що є умовою цього питання. (І, також, питання конкретно говорить: "Не хочу використовувати багатоповерхівку".)
єпископ

1
@bishop: Я вважаю, що ця критика частково несправедлива, оскільки, хоч у цьому питанні, можливо, було вказано, що не використовується багатоповерхівка, це, мабуть, пов'язане з непорозумінням. Наведений вище приклад показує, як використовувати довільні команди і регулярні розширення оболонки також працюють - multitail <(ssh …) <(ssh …)- дозволяючи бажаний результат, навіть якщо це не те, як вони спочатку думали, що на питання можна відповісти.
Кріс Адамс

0

Ви можете оформити замовлення у зовнішньому журналі.

Я створив інструмент Java, який міг читати локальні та віддалені файли журналів за допомогою SSH. Він досить простий у використанні.

Ще кілька пояснень: https://github.com/pschweitz/insidelog/wiki

Просто завантажте версію, що відповідає вашій операційній системі, з нативної версії випуску jar в режимі Java Runtime (потрібно java 8_40 або вище):

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

Ви можете знайти повну документацію (вбудовану на сторінку Github та її також)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.