戻る

swatch: ログ監視

[更新履歴]

04/02/17 … 起動・停止用 init.d スクリプト追記
03/07/02 … 複数プロセスの見分け方修正。
03/06/16 … 起動コマンドを修正。
syslog …に限らず、ログファイルを監視し、特定文字列が現れるとアラームとして、ベルを鳴らしたり、そのログの内容をメールで送信したりできる swatch っつーのを利用する。はっきり行って簡単。もっと早くからやってりゃよかったな。

インストール

# apt-get install swatch

設定

MRTG もそうだったが、どっか特定のパスにある設定ファイルをロードして起動〜ってわけではない。詳しくは、@IT へどーぞ。

うちは、込み入った設定が面倒だったので、「/var/log/syslog , /var/log/auth.log それぞれにおいて、"reject"もしくは"error"もしくは"fail"という文字列が現れたらアラーム」というポリシー(?)で運用することにした。

なお、1回の実行(バックグラウンドで動かすので1つのプロセスって感じか?)では、1つのファイルしか監視できないので、複数のファイルを監視するときは、ファイルの数だけプロセスを実行する。その際、設定ファイル(指定する文字列や、マッチした際のアクションを記述)は、共通でも構わない。

設定サンプル
watchfor   /reject|error|fail/i
        mail=root,subject=swatch_error_log
        bell 3
こいつを、例えば /root/.swatch で保存しておき、以下のコマンドでバックグラウンドで実行
# swatch -c /root/.swatch -t /var/log/syslog &
# swatch -c /root/.swatch -t /var/log/auth.log &
実行すると、この設定ファイルを元に、専用(?)の Perlスクリプトが生成され、そいつが指定ファイルを監視、って流れっぽい。なお、実行時にPIDが表示されるが、複数起動した際には、ps コマンドでは PID 以外には、あんまり見分けがつかないんで、メモっといたほうが吉。まぁ、生成されるスクリプトにPIDが付加されてるから、それと指定ファイルをキーに grep してやれば、わからなくもないが。
07/02 訂正:「# ps ag」でわかりました。あとは「# pstree -a」とか。

んで、このときにどっかのスパマーとかがうちの MTA 使おうとすると、Reject した旨が syslog に記録されるんで、root 宛にその行のログが届く。ついでに、root に届いたメールは、普段常用しているユーザと、ケータイに転送するよう設定している。…夜中は勘弁してくれ。

ちなみに、インストール時に一緒にコピーされる(公式?)サンプルは、以下の場所にある。
/usr/share/doc/swatch/examples
まぁ、エラーなく侵入されてこのプロセスを殺されたら、何の意味もないかもしれんが。。。
/etc/inittab に respawn とかで設定するといいんかな?

起動設定

起動は簡単になったが、相変わらず停止が面倒(pid確認 -> kill)なので、起動・停止スクリプトを作成。ついでに OS 起動時などに自動起動するように、/etc/init.d 以下へ起動スクリプトを登録する。
また、単純に実行すると、実行 owner のホームディレクトリに .swatch_script.PID ファイルが作成され、ちと見通しが悪いので、"--script-dir"オプションで、スクリプト生成先を変更する(BASEDIR)。あらかじめ mkdir で作成しておくこと。
# mkdir /var/swatch
# ls
swatch.rule  swatch.sh*
swatch.sh の中身
start を引数に実行すると、swatch.rule をルールに、syslog と auth.log を監視スタート。stop を引数に実行すると、.swatch_script.PID ファイルから PID を拾ってきて、プロセスを kill する。
※ 2重起動防止や、停止時の stop 実行の処理は入ってないです…
#!/bin/sh

SWATCH="/usr/bin/swatch"
BASEDIR="/var/swatch"
RULE="swatch.rule"
SYSLOG="/var/log/syslog"
AUTHLOG="/var/log/auth.log"
SCRIPT=".swatch_script."
KILL="/bin/kill"
BASENAME="/usr/bin/basename"

case "$1" in
  start)
    echo "start swatch"
    ${SWATCH} -c ${BASEDIR}/${RULE} -t ${SYSLOG} --script-dir=${BASEDIR} &
    ${SWATCH} -c ${BASEDIR}/${RULE} -t ${AUTHLOG} --script-dir=${BASEDIR} &
    ;;

  stop)
    echo "stop swatch"
    LIST=`ls ${BASEDIR}/${SCRIPT}* | sed s/${SCRIPT}//`
    for PID in $LIST
    do
      PID=`${BASENAME} ${PID}`
      ${KILL} ${PID}
    done
    ;;

  restart)
    $0 stop
    $0 start
    ;;

  *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
    ;;

esac
/etc/init.d 以下へコピー(もしくはリンク)し、/etc/rc#.d 以下へリンクをはって OS ブート時に起動するように設定。
# cd /etc/init.d
# ln -s /var/swatch/swatch.sh .
# update-rc.d swatch.sh defaults 99
 Adding system startup for /etc/init.d/swatch.sh ...
   /etc/rc0.d/K99swatch.sh -> ../init.d/swatch.sh
   /etc/rc1.d/K99swatch.sh -> ../init.d/swatch.sh
   /etc/rc6.d/K99swatch.sh -> ../init.d/swatch.sh
   /etc/rc2.d/S99swatch.sh -> ../init.d/swatch.sh
   /etc/rc3.d/S99swatch.sh -> ../init.d/swatch.sh
   /etc/rc4.d/S99swatch.sh -> ../init.d/swatch.sh
   /etc/rc5.d/S99swatch.sh -> ../init.d/swatch.sh
ちなみに現在のルールは紆余曲折を経てこんな感じに。
ignore     /kernel: smb_get_length: recv error = 5/
ignore     /postfix\/smtp.*\(Name service error for.*Host not found, try again\)/

watchfor   /fail|error|reject/i
        mail=root,subject=swatch_error_log
        bell 3
watchfor で指定する文字列では"|"で or 設定が一行でできるが、ignore による「除外設定」の複数指定は、複数行にて設定する。まぁこのへんは Perl の世界だけど。

ちなみに上から順に、
1. smbmount でたまにエラーがでるがサーバの稼動には支障がないため除外
2. ADSL モデムがコケてるときにメールを送信しようとすると名前解決できずにこのエラーになるが、その際のエラーメール送信を拾って無限ループに陥るので除外