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"

…そしてそれを無効にする2つの方法を見つけました…

  1. -tフラグを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

表示grepされるのは、Glibc が提供する標準stdoutバッファーの効果です。最善の解決策は、--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-bufferedで期待どおりに動作します。
14年

@deephacksその場合、答えを受け入れることを検討してください-同じ問題を抱えている他の人に手掛かりを与えます。
ペテルフ14年

1
grep / glibcのバッファリングは、そのstdoutに依存します。ssh tail | grepバッファなしでローカル端末に出力します。ssh -t "tail|grep"バッファなしでptyに出力します。ssh "tail|grep"パイプへの出力(to 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
@司教:この批判は不公平だと思う。なぜなら、質問はマルチテールを使わないことを指定しているかもしれないが、それは誤解によるようだ。上記の例は、任意のコマンドの使用方法を示しており、通常のシェル拡張も機能します— multitail <(ssh …) <(ssh …)—質問が答えられると当初考えていなかった場合でも、望ましい結果を可能にします。
クリスアダムス

0

インサイドログでチェックアウトできます。

私が作成したJavaツール。SSHを使用してローカルおよびリモートのログファイルを読み取ることができます。使い方はとても簡単です。

その他の説明:https : //github.com/pschweitz/insidelog/wiki

Javaランタイム内で実行可能なネイティブjarリリースのオペレーティングシステムに対応するバージョンをダウンロードするだけです(java 8_40以降が必要です)。

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

完全なドキュメントを見つけることができます(Githubのページにも埋め込まれています)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.