上記の続き。
目的
- プロセスが落ちてautorestartが頻繁に使われるようなら、それを検知しておきたい。
- いくらautorestartを指定していても、異常終了後に即起動できない状態だと デフォルト5回リトライで落ちてしまう。
- supervisorでデーモン化したプロセスが終了してしまった場合に、 メールで通知させたい。
supervisorのイベントリスナー
-
異常終了イベントを検知するイベントリスナーを実装して組み込めばいい。
- バージョン3.0からの機能。
- 公式のドキュメントとしては以下の機能の部分。
- メールを送るだけのリスナーなら、
superlance
パッケージがリスナーの実装の一つとして存在するので、今回はこれを使う。
superlance
pythonのパッケージ。
記述時点でversion 0.11を使用。
インストールは easy_install
や pip
で。
(pythonのパッケージ管理ツール。なければyumなりapt-getなりでpython-setuptoolsをどうぞ)
pip install superlance
又は
easy_install superlance
supervisorのイベント
リスンしたいイベントは2種類。
- デーモンが予期せぬリターンコードで終了した。 ==>
PROCESS_STATE_EXITED
- デーモンが起動に何度も失敗する。 ==>
PROCESS_STATE_FATAL
それぞれ、 superlance
パッケージ内の crashmailbatch
と fatalmailbatch
を使う。
(これらのイベントを対象としたもの以外にも、superlanceにはリスナー実装が存在する)
crashmailbatch
-
PROCESS_STATE_EXITED
イベントをリスンし、メール通知する。 - これ自身をsupervisorの管理対象プロセスとして登録することで動作する。
/etc/supervisord.d/crashmailbatch.ini
として以下の様に作成。
[eventlistener:crashmailbatch]
command=crashmailbatch --subject="Supervisord EXITED STATE report" --toEmail="toname@example.com" --fromEmail="fromname@example.com"
events=PROCESS_STATE,TICK_60
autorestart=true
stderr_logfile=/var/log/supervisor/jobs/crashmailbatch.log
stderr_logfile_maxbytes=1MB
stderr_logfile_backups=5
stderr_capture_maxbytes=1MB
前の記事同様、/var/log/supervisor/jobs/ディレクトリにエラーログを吐くのでディレクトリは作成しておくこと。
crashmailbatchコマンド
command
で指定している通り、これ自身はただのコマンド。
crashmailbatch
を引数なしで打つとヘルプがでるので、
SMTPサーバ、認証ユーザ等を変更する場合には参照する。
SMTPサーバ
デフォルトではlocalhost。
適宜サービスを立てるか、上記のcrashmailbatch
コマンドオプション(-H)で指定する。
メール送信インターバル
デフォルトは 1分に1度。
こちらもcrashmailbatch
のコマンドオプション(-I)で変更可能。
リスンするイベント
events
でリスンするイベントを書く。
PROCESS_STATE
としてもPROCESS_STATE_EXITED
としても結果は変わらない。
PROCESS_STATE
をリスンすれば、その子イベントとなるPROCESS_STATE_EXITED
もキャッチする。
しかしcrashmailbatch
が処理するイベントはPROCESS_STATE_EXITED
のみである。(crashmailbatch
のソースに記述…)
stdoutをキャプチャしないこと。
上記のコンフィグではstderrのキャプチャを行っているが、 stdoutは取ってはいけない。
どうもメールの送信時に標準出力を使っているらしく、stdoutをこの設定で取るとメールが送信されない。
fatalmailbatch
PROCESS_STATE_FATAL
イベントをリスンし、メール通知する。
これ自身をsupervisorの管理対象プロセスとして登録することで動作する。
/etc/supervisord.d/crashmailbatch.ini
として以下の様に作成。
[eventlistener:fatalmailbatch]
toname@example.com" --fromEmail="fromname@example.com"
command=fatalmailbatch --subject="Supervisord FATAL STATE report" --toEmail="toname@example.com" --fromEmail="fromname@example.com"
events=PROCESS_STATE,TICK_60
autorestart=true
stderr_logfile=/var/log/supervisor/jobs/fatalmailbatch.log
stderr_logfile_maxbytes=1MB
stderr_logfile_backups=5
stderr_capture_maxbytes=1MB
コンフィグの指定方法はcrashmailbatch
とほぼ同じ。
リスナーの起動
他のsupervisor管理プロセスと方法は同じ。
上記のようにコンフィグを作成した後に、例えば下記の様に実行する。
% supervisorctl
supervisorctl > reread
supervisorctl > add crashmailbatch
supervisorctl > add fatalmailbatch
supervisorctl > status
supervisorctl > exit
確認方法
- supervisor管理のプロセスを、
kill
コマンドでTERMINATEさせてみる。- EXITEDのメール通知が
crashmailbatch
によって行われる。
- EXITEDのメール通知が
- supervisord管理のプロセスを、コンフィグを編集して
command
のパスを存在しないものにし、FATAL終了させてみる。- FATALのメール通知が
fatalmailbatch
によって行われる。
- FATALのメール通知が
この設定の意味
- 結局supervisorの生成プロセスだけ監視しても、 supervisord自身が落ちては意味がない。
- イベントリスナー自身もsupervisorのプロセスなので。
- monitとか使って簡単にプロセス監視書いた方がよくないか。
- ついでにその監視でsupervisordも監視させた方がよくないか。
......はい。あえて使う意味はというと。
- 設定が容易。
- supervisor外部の監視を使わなくても、supervisordだけで完結する。
- supervisordにプロセスを増やしても、監視設定を増やさなくて良い。
- 外部の監視はsupervisor自身のみでよい。
- supervisordでデーモン化するようなものはプロセス名が特定しにくい( ことが多い、かもしれない)のでmonitとかで書きにくい。
- ただのこじつけ。
真面目に監視したいならやはり外部の監視に頼った方が良いでしょう。