supervisord (4) - eventlistener -

2014-02-17T00:00:00+00:00 supervisord Python JavaScript Node.js

参考: http://blog.hakutoitoi.com/?p=396

supervisordで管理しているプロセスが落ちたりだとか(規定されている?)一定時間毎に何かコマンドを動かしたい時とかに使える模様

[inet_http_server]
port=127.0.0.1:9001

[unix_http_server]
file=/tmp/supervisor.sock

[supervisord]
logfile=/var/log/supervisord/supervisord.log
loglevel=debug

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock

[eventlistener:hello]
command=/home/kinjouj/Desktop/supervisord/listener.py
events=PROCESS_STATE_STOPPED,PROCESS_STATE_EXITED,TICK_5

[program:redmine]
environment=BUNDLE_GEMFILE=/opt/www/sample/Gemfile
command=/home/kinjouj/.anyenv/envs/rbenv/shims/bundle exec unicorn_rails -E production -c /opt/www/sample/config/unicorn.rb

[eventlistener:]で設定を行う。commandとeventsを指定すれば良い。eventsに指定するのは上記参考に日本語訳されたのがあるのでそれを参考にすれば良い。上記の場合だと

  • プロセス(supervisord本体では無い)が何らかの理由により(正常)停止した (PROCESS_STATE_STOPPED)
  • プロセス(supervisord本体では無い)が何らかの理由により(異常)停止した (PROCESS_STATE_EXITED)
  • 5秒毎

っていう条件下においてcommandで指定したプログラムが起動される。正確にはプログラム自体はsupervisordが起動した時点で起動されているが、イベント等のバッファ?を読み取る事によりイベントを着信させる事が出来るような仕組みな模様。ちなみにPROCESS_STATE_EXITEDはkill -9等でも発生する

例えばPythonだと

#!/usr/bin/env python

import sys
from supervisor import childutils

def write_log(s):
    f = open("log.txt", "a")
    f.write("%sn" % s);
    f.flush()
    f.close()

def main():
    while True:
        headers, payload = childutils.listener.wait(sys.stdin, sys.stdout)

        write_log(headers["eventname"])

        childutils.listener.ok(sys.stdout)

if __name__ == "__main__":
    main()

ていうような感じで使用出来る。着火したイベント名なログを取るだけっていうシンプルな物

んまぁそういう機能がある模様なのでメモ

余談

node.jsなモジュールにsupervisord-eventlistenerっていうのがある模様

#!/usr/bin/env node

var supervisor = require("supervisord-eventlistener");
supervisor.on("PROCESS_STATE", function(type, headers, data) {
});
supervisor.listen(process.stdin, process.stdout);

gradle-android-toolkit+robolectric-plugin gradle-android-test-plugin+Robolectricでテスト