fabricでリモートホストのログファイルをtailするスクリプトを書くTips
fabricでリモートホストのログファイルをtailするスクリプトを書くという事があります。
多分安直に書くとこんな感じ
from fabric.api import sudo,env env.hosts=['ap1','ap2','ap3'] env.password="hogehogepiyopiyo" def tailall(): sudo("tail -f /var/log/httpd/access_log")
ap1とap2とap3のapacheのアクセスログをtailします。 実行はこう
fab tailall
が、このスクリプトではおそらく期待する要件を満たすことは出来ません。 1つずつ解決していきます。
ホストに対して並列に実行してくれない
このままでは、ap1へtail→Ctrl+C→ap2へtail→Ctrl+C→ap3へtail という動作になってしまいます。
複数ホストのログを流し見するために並列にtailしたい場合、起動時にオプション -P
と --linewise
を足します。
fab -P --linewise taillall
こうすることで並列にtailが実行され、いい感じに流し見出来ます。
@parallel
をつけても良いらしいです。
logrotateすると追従出来ない
これはfabricの問題ではなくてtailの問題。
tailf -f
ではリモートファイルが切り替わった時に見失ってしまいます。
その場合は tailf
もしくは tail -F
を使うとlogrotateした際でもそのまま読み込む事ができます。
ctrl+Cで終了した際にリモートホストへtailプロセスが残ってしまう。
これは少し気づき辛い問題です。気づいた時には大量のtailが残ってたり。 上記のスクリプトを単純に実行し、ctrl+cを押して終了した場合、リモートホストにはtailしているプロセスがそのまま残ってしまっています。
[user@ap1 ~]$ ps aux|grep tail root 31669 0.1 0.0 181928 3280 ? Ss 19:39 0:00 sudo -S -p sudo password: /bin/bash -l -c tail -f /var/log/httpd/access_log
該当ホストにいってpsとかしてみないと気づかないので発覚した時は大分驚きます。
これを防ぐためには スクリプト内に env.remote_interrupt = True
を追加します。
from fabric.api import sudo,env env.remote_interrupt = True env.hosts=['ap1','ap2','ap3'] env.password="hogehogepiyopiyo" def tailall(): sudo("tail -f /var/log/httpd/access_log")
これを追加することでCtrl+cしたら、remoteで実行しているコマンドも終了してくれます。
あとは色々キーボード処理などをよしなにキャッチしてあげればそこそこに使い勝手のあるスクリプトが出来上がります。
from fabric.api import sudo,env env.remote_interrupt = True env.hosts=['ap1','ap2','ap3'] env.password="hogehogepiyopiyo" def tailall(): try: sudo("tail -F /var/log/httpd/access_log") except KeyboardInterrupt, e: pass return
fab -P --linewise tailall