Python
supervisor
Slack

SupervisorのEventListenerを使ってプロセスの状態変化をSlackに通知する

More than 1 year has passed since last update.


はじめに

supervisorを運用していて、まれにプロセスが落ちているときはないでしょうか?

外部監視するという方法もあるとは思いますが、以前から気になっていたSupervisorのEventListenerを使ってプロセスの状態変化をSlackに通知するようにしてみました。


やったこと


設定ファイルの作成

下記のように設定ファイルを作成します。


/etc/supervisord.d/process_state_event_listener.conf

[eventlistener:process_state_event_listener]

command=python /path/to/process_state_event_listener.py
events=PROCESS_STATE
redirect_stderr=false
stdout_logfile=/var/log/supervisor/event_listener_stdout.log
stdout_logfile_maxbytes=1MB
stdout_logfile_backups=5
stderr_logfile=/var/log/supervisor/event_listener_stderr.log
stderr_logfile_maxbytes=1MB
stderr_logfile_backups=5
environment=SLACK_WEB_HOOK_URL="https://hooks.slack.com/services/xxxxxxx/xxxxxxx/xxxxxxxxxx"


events

プロセスの状態変化をすべて通知したいので、PROCESS_STATEを指定します。


environment

Slackに通知するために、Incoming WebHook用のURLを環境変数にセットします。


参考URL


イベントリスナーの作成

最終的に下記のようなコードになりました。


/path/to/process_state_event_listener.py

import sys

import os
from supervisor import childutils
from datetime import datetime
import slackweb

def main():
while True:
run_forever()

def run_forever():

headers, payload = childutils.listener.wait(sys.stdin, sys.stdout)
eventname = headers['eventname']

payload_header, data = childutils.eventdata(payload+'\n')

childutils.listener.ok(sys.stdout)

color = "good"
if eventname in ['PROCESS_STATE_BACKOFF', 'PROCESS_STATE_EXITED', 'PROCESS_STATE_FATAL', 'PROCESS_STATE_UNKNOWN']:
color = "danger"

attachment = {
"title": "event",
"text": eventname,
"color": color,
"fields": [{
"title": "datetime",
"value": datetime.now().strftime("%Y/%m/%d %H:%M:%S")
}, {
"title": "hostname",
"value": os.uname()[1]
}]
}

if 'processname' in payload_header:
attachment["fields"].append({
"title": "process",
"value": payload_header['processname']
})

if 'expected' in payload_header:
attachment["fields"].append({
"title": "expected",
"value": payload_header['expected']
})

if 'SLACK_WEB_HOOK_URL' in os.environ:
slack_url = os.environ['SLACK_WEB_HOOK_URL']
slack = slackweb.Slack(url=slack_url)
slack.notify(attachments=[attachment])

if __name__ == '__main__':
main()



通知イメージ

supervisor_slack.png


参考URL


おわりに

メール通知でよければsuperlanceというプラグインがあるのですが、OP25B問題でgmailにメールが届かなかったりしたので、Slackに通知してみました。

Supervisorを利用することが増えてきたので、今後もいろいろ応用していきたいと思います。