Monit でログを監視してプロセスを再起動させる
Monit を使って、
ログに特定の文字列が書き込まれた時にプロセスを再起動させる例です。
以下の要件を満たすために検証しました。
- 原因を調べきれていないけれど時々セグフォしてしまう
- ずっと落ちたままだと困るので再起動させたい
- 数分で起き上がってくれれば特に問題ない
例として httpd を再起動させるものとします。
検証した Monit のバージョン
今回検証したのは、Monit 5.1.1 です。
Install Monit
epel repo を追加した状態で以下を実行。
yum install -y monit
最新版から離れているので、最新版を使いたい場合はビルドしたほうが良いです。
自動起動の設定をしておきます(設定ファイルを追加するので、まだ起動しない)。
chkconfig monit on
Monit 設定ファイル
Default では、/etc/monit.d/以下のファイルを include するようになっているので、
以下を /etc/monit.d/httpd として追加。
check file messages with path /var/log/messages if match "segfault" then exec "/usr/local/bin/httpd_restart"
構文の説明は以下のとおりです。
check file <unique name> with path <file path> - check file <unique name> -> ファイル監視をする、<unique name> はその名のとおり、重複しない任意の名前で良い - with path <file path> -> <file path> のファイルを監視
if match {regex|path} then <action> - if match {regex|path} -> 正規表現か、正規表現を列挙したファイルの絶対パスを指定 - then <action> -> 任意の action を指定(今回は exec) => exec は指定したスクリプトを実行する action
これらを踏まえると設定した監視の条件は、
「/var/log/messages に segfault という文字列が書き込まれたら /usr/local/bin/httpd_restart を実行する」
となります。
プロセスを再起動するスクリプト
今回のケースでは、セグフォすると service restart ができなかったので、
kill -KILL でプロセスを殺してから service start しています。
service restart が使える場合は、そちらのほうが良いでしょう。
#!/bin/bash set -e MSG="httpd force restarted." kill -KILL $(pidof httpd) rm -f /var/run/httpd/httpd.pid service httpd start logger -p local0.info $MSG -t "Monit"
上記スクリプトを /usr/local/bin/httpd_restart に配置します。
(chmod +x /usr/local/bin/httpd_restart も忘れずに)
Start Monit
service monit start
実験
/var/log/messages に対象となる文字列を追記します。
echo "segfault" >> /var/log/messages
しばらくすると、/var/log/monit に以下のようなログが流れます。
[JST May 7 13:01:54] error : 'messages' content match [segfault] [JST May 7 13:01:54] info : 'messages' exec: /usr/local/bin/httpd_restart
再起動したか一見わからないので、
以下の様なコマンドを実行してプロセスの起動時間を確認します。
ps -eo pid,ppid,lstart,cmd | grep httpd
起動時間が直近になっていれば成功です。
まとめ
Monit でログを監視して、プロセスを再起動する例を示しました。
正規表現を使った柔軟なログ監視ができるので、使えるケースは多そうです。