keisyuのブログ

最近めっきりエンジニアリングしなくなった厄年のおじさんがIT技術をリハビリするブログ。

daemontools でプロセス監視 (svscan, supervise, multilog)

daemontools ( http://cr.yp.to/daemontools.html )でプロセス監視を運用上よくやりますが、毎度ググってを繰り返すので自分で書いとこうと思います。

daemontools は以下のツールで構成されるプロセス監視のユーティリティです

svscan サービスディレクトリの監視
supervise プロセスの監視および制御
multilog ロギング

daemontools - Wikipedia

daemontools のインストール

yumrpm もイマイチこれや!ってのがないので、本家?からソース毎ダウンロードしてインストールします

$ curl -O http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
$ tar zxvf daemontools-0.76.tar.gz
$ cd admin/daemontools-0.76/
$ curl -O http://djbware.csi.hu/patches/daemontools-0.76.errno.patch
$ patch -p1 < daemontools-0.76.errno.patch
$ sudo ./package/install 

インストールが完了すると /usr/local/bin, /command あたりにそれらしい実行ファイルが作成されていると思いますが、すべての実体がソースを展開したところに配置されているのでまじめに運用するときにはそこからちゃんと検討しないといけない。

svscan

まずはdaemontools本丸である svscan を起動しなければいけない。起動は svscanboot コマンドで行うがインストールでは /etc/inittab にそれが記載されている

SV:123456:respawn:/command/svscanboot

が、CentOSでは?これが効かないのでこれはコメントアウトしてupstartによる起動に変更する。以下のような内容の /etc/init/svscan.conf を作成する

start on runlevel [12345]
respawn
exec /command/svscanboot

これでOS起動時に svscan が立ち上がるし、このプロセスが落ちても自動復旧(再立ち上げ)される。

$ ps ax | grep svscan
  586 ?        Ss     0:00 /bin/sh /command/svscanboot
  594 ?        S      0:00 svscan /service

試しにsvscanのプロセスをkillしてみると、/var/log/messages に

Feb 12 22:49:01 localhost init: svscan main process ended, respawning

と記録され再びsvscanが立ち上がってます。これでsvscanがプロセスから消えることは無い状態になりました.

supervise

次にパッケージ(デーモンサービス)を監視する supervise です。パッケージはそれぞれひとつのディレクトリ内で管理されます。

daemon_name/run   #デーモンの実行ファイルをrunとして配置する。

としてそれを

/service/daemon_name

として配置することでsvscanの管理下となります。( daemon_name を別のパスで作成してシンボリックリンクを貼ることで配置することも一般的です)
今回は動作確認のため簡単なデーモン?をシェルで作ってみました。

$ cat run 
#!/bin/sh

i=1
while [ 1 ];
do
  echo $i
  i=`expr $i + 1`
  sleep 1
done;

実際にはrunはデーモンで動作するプログラムを起動するシェルになる場合が一般的です。その場合は run のシェルの中で exec を利用して目的のプログラムを起動します。
今回のディレクトリ構成は

$ find ~/test_job/
/home/keisyu/test_job/
/home/keisyu/test_job/run
$ chmod +t test_job

とします。test_job にスティッキービットを立てる必要があるのでそうします (chmod +t)
これ(test_jobディレクトリ)を/serviceにリンクします。すると run が起動します。

$ sudo ln -s /home/keisyu/test_job 
$ ps ax 
 1221 ?        S      0:00 supervise test_job
 1222 ?        S      0:00 /bin/sh ./run
$ sudo svstat /service/test_job/    #サービスの状態を確認するコマンド
/service/test_job/: up (pid 1222) 197 seconds

test_job/supervise というフォルダが自動的に作成されますがdaemontoolsの管理用なので触らないです.

$ sudo svc -u /service/test_job  # サービス(run)を起動します
$ sudo svc -d /service/test_job  # サービス(run)を停止させます
  • d -u 以外にも run に各種シグナルが送れますので必要であればググってください。

multilog

デーモンが標準/エラー出力等を行う情報を記録するためのコマンドです。supervise と合わせて使うことで deamontoolsで管理しているプロセスにおけるロギングの管理が用意になります。
先ほどの test_job におけるロギングを行うということで実際にやってみます

test_job/
test_job/run
test_job/supervise #これは自動的に作られる
test_job/log
test_job/log/run
test_job/log/supervise #これは自動的に作られる
test_job/log/main #これは自動的に作られる

という形で log のフォルダとその直下に run というファイルを配置します。 run はmultilogを起動するシェルであり最低限の内容として以下にします。

#!/bin/sh
exec multilog t ./main

すると log/main フォルダ以下に current ファイルが生成され run の出力がロギングされます。

# tail -f current 
...
@4000000052fb885a329f8e7c 89
@4000000052fb885b32d7b57c 90
@4000000052fb885c32f7439c 91
@4000000052fb885d3320861c 92
...

なんかよくわからんくなった時の対応

run コマンドを修正したいとかそうした時にsvscanの管理下にある状態で修正すると混乱します
その場合は以下の手順でやる。

# cd /service
# mv test_job .test_job
# svc -dx /service/.test_job
# log 以下の supervise, multilogってプロセスが死んでくれないのでkillする。正しい方法がわからん...
# 色々修正
# mv .test_job test_job
# svc -u /service/test_job

|