Pythonスクリプトをデーモン化するのにsupervisorを利用した話
簡単なスクリプトをデーモン化出来ないかと調べたところ
supervisorを使うことでスクリプトをデーモン化させることが出来そう
↓参考にしたサイト
SupervisorでPythonのスクリプトをデーモンプロセスとして動かす - Symfoware
私が大好きなCentOS6.8でやってみた
ちなみに私の環境はこんな感じ
見出し
supervisor(version 2.1)のインストール
supervisorのインストールにepelリポジトリが必要なのでyumでインストール
# yum install epel-release
supervisorのインストール
# yum install supervisor
デーモン化するスクリプトの作成
とりあえず簡単なスクリプトを
supervisorの動作確認のため、簡単なスクリプトを作成
「/usr/local/bin/」ディレクトリにファイル名「test.py」でスクリプトを作成
# cd /usr/local/bin/ # mkdir /test # vim test.py
test.pyの中身(Python3.5用)
#!/usr/bin/env python # -*- coding: utf-8 -*- from time import sleep from datetime import datetime while True: now = datetime.now() now_str = now.strftime('%Y-%m-%d %H:%M:%S') print('[%s] %s' % (now_str, 'unko')) sleep(5)
スクリプトの機能としては、単純に時刻付きで「unko」を出力するだけ
supervisorの設定
先程作成したPythonスクリプトを動作させるため、supervisorの設定ファイルを編集する
# vim /etc/supervisord.conf
設定ファイル内に、コメントで設定のテンプレートがあるので、コピペで以下の内容をファイルの最後に追記した。
[program:unko] command=/usr/local/lib/anaconda3/bin/python /usr/local/bin/test.py ;priority=999 ; the relative start priority (default 999) autostart=true ; start at supervisord start (default: true) autorestart=true ; retstart at unexpected quit (default: true) startsecs=10 ; number of secs prog must stay running (def. 10) startretries=3 ; max # of serial start failures (default 3) ;exitcodes=0,2 ; 'expected' exit codes for process (default 0,2) ;stopsignal=QUIT ; signal used to kill process (default TERM) ;stopwaitsecs=10 ; max num secs to wait before SIGKILL (default 10) ;user=chrism ; setuid to this UNIX account to run the program log_stdout=true ; if true, log program stdout (default true) log_stderr=true ; if true, log program stderr (def false) logfile=/var/log/supervisor/unko.log ; child log path, use NONE for none; default AUTO ;logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB) ;logfile_backups=10 ; # of logfile backups (default 10)
commmandのキーに、実行するコマンドを記載
自分の環境ではAnaconda3を利用しているので、Anaconda3のpythonコマンドのフルパスを記載している
supervisorハマった点
インターネットで調べると3.x系の設定方法が結構見つかるけど、それを書いてしまうともちろん動作しない
supervisorで使用できる設定は、2.x系・3.x系両方ともコメントでテンプレート化されている感じ
別の言い方をすると「/etc/supervisord.conf」のコメントに無い設定は、多分使えない
自分は以下の点で結構ハマった
- [include]セクションが使えない
- 環境変数がほとんど設定されていない状態
- カレントを設定する「directory」キーが使えない
- 変数(?)が使えない
1. [include]セクションが使えない
色んな所で書かれている設定だけど
[include] files = /etc/supervisord.d/*.ini
これはsupervisor2では使えない・・・
supervisor3ではコメント化されてるけど、supervisor2はコメントに無いじゃないですかー
2. 環境変数がほとんど設定されていない状態
自分が使用したsupervisor2では、環境変数が設定されていなかった
正確に言うとPATHの中身が「/sbin:/bin:/usr/sbin」って感じ
なので自分のようにデフォルトではないpythonを使わないときにうまくいかなかった
「/etc/profile」、「/etc/profile.d/*.sh」の設定を使うためには、commandの設定を変更する
↓設定例
command=bash -c 'python /usr/local/bin/test.py;'
3. カレントを設定する「directory」キーが使えない
supervisor2では「directory」キーが使えない(supervisor3では使えるし、コメントにも書いてある)
カレントを変更する場合は、commandの設定を工夫する
↓例
command=bash -c 'cd /usr/local/bin; python /usr/local/bin/test.py;'
「bash -c」便利やな
4. 変数(?)が使えない
supervisorの設定を調べると、時々以下のような設定を見ることがあった。
[program:sample] logfile=/var/log/supervisor/%(program_name)s.log ; child log path, use NONE for none; default AUTO ```
supervisor3.xでは%(program_name)sに[program:sample]のsampleが自動置換されるのだろうが、supervisor2.xでは置換されなかった。
supervisorでスクリプトを起動
supervisorを起動する
# service supervisord start supervisord を起動中: [ OK ]
起動状態の確認
# supervisorctl status unko RUNNING pid 6647, uptime 00:00:56
ここで何も表示されていないときは、(ほぼ)設定ファイルに問題がある
スクリプトがすぐ落ちる場合は、別のメッセージが表示される
ログファイル(/var/log/supervisor/unko.log)の中身の確認
[2017-01-28 23:15:17] unko [2017-01-28 23:15:22] unko [2017-01-28 23:15:27] unko [2017-01-28 23:15:32] unko [2017-01-28 23:15:37] unko
supervisorでpythonをデーモン化することができた。
今は別のスクリプトを起動させているが、1日経って特に今のところ問題なし
ログファイル周りの設定をデフォルトのまま使っているので、次はsupervisorのログファイル周りを調査しないといけませんな