daemontools

提供: FreeBSD入門
2015年9月27日 (日) 22:12時点におけるDaemon (トーク | 投稿記録)による版 (関連項目)

(差分) ←前の版 | 最新版 (差分) | 次の版→ (差分)
移動: 案内検索
スポンサーリンク

daemontools とは、Unixのデーモンのコントロール(起動、終了、再起動)、ログ取得などのプログラムを集めたユーティリティです。デーモンプログラムの作成やデーモンの設置が簡単になります。デーモンプログラムが落ちても、自動で起動します。標準エラー出力がロギングされ、ログローテーションが自動で行われます。FreeBSDだけでなく、Linuxでも使用できます。フォアグラウンドで実行できるプログラムがdaemontoolsの対称です。

読み方

daemontools
でーもん つーるず

概要

daemontoolsは、memcachedやnodoe.jsなどのプログラムなどの制御に向いています。そういったプログラム達は、自身が落ちてしまったときに、自主的に上がってきません。死活監視を行いながら、落ちたプロセスを自動起動するプログラムが必要になります。その役目をdaemontoolsは行うことができます。memcachedを複数起動したいときにも簡単に対応できます。

daemontools の svscan をデーモン化するには、daemonコマンドで実現します。

daemontoolsのコマンド

daemontoolsには、いろいろなコマンドが用意されています。

svscan

svscan は、次のような動作をします。

  • svscanがディレクトリを監視します。
  • 新しいディレクトリがあれば、supervise プロセスを起動します。
  • superviseが終了している場合は、 supervise を起動します。
  • .(ドット)ではじまるディレクトリは、無視します。

supervise

supervise は、サービスのプロセスを起動します。

  • run を実行します。
  • run が終了したら、 run を起動します。
  • supervise の起動時に、 down があれば、 run を実行しません。

multilog

ログの収集は、 multilog コマンドを使用します。

  • 標準入力をロギングします。
  • タイムスタンプをつけられます。
  • ログを自動で切り替えられます。
  • 指定されたサイズを超えたら、ローテーションされます。
  • 指定された個数以上のログを削除します。

setuidgid

uidとguidを指定したuidとgidにセットします。補助グループ権限は、削除されます。 サービスのユーザーやロギングのためのmultilogのユーザーを設定します。 runやlog/runのスクリプトのexecで使用します。

#!/bin/sh
exec setuidgid nobody /path/to/command arguments

インストール

pkgコマンドでインストールする場合

sudo pkg install daemontools

ファイル

daemontools-0.76_16:
        /usr/local/bin/envdir
        /usr/local/bin/envuidgid
        /usr/local/bin/fghack
        /usr/local/bin/multilog
        /usr/local/bin/pgrphack
        /usr/local/bin/readproctitle
        /usr/local/bin/setlock
        /usr/local/bin/setuidgid
        /usr/local/bin/softlimit
        /usr/local/bin/supervise
        /usr/local/bin/svc
        /usr/local/bin/svok
        /usr/local/bin/svscan
        /usr/local/bin/svscanboot
        /usr/local/bin/svstat
        /usr/local/bin/tai64n
        /usr/local/bin/tai64nlocal
        /usr/local/etc/rc.d/svscan
        /usr/local/man/man8/envdir.8.gz
        /usr/local/man/man8/envuidgid.8.gz
        /usr/local/man/man8/fghack.8.gz
        /usr/local/man/man8/multilog.8.gz
        /usr/local/man/man8/pgrphack.8.gz
        /usr/local/man/man8/readproctitle.8.gz
        /usr/local/man/man8/setlock.8.gz
        /usr/local/man/man8/setuidgid.8.gz
        /usr/local/man/man8/softlimit.8.gz
        /usr/local/man/man8/supervise.8.gz
        /usr/local/man/man8/svc.8.gz
        /usr/local/man/man8/svok.8.gz
        /usr/local/man/man8/svscan.8.gz
        /usr/local/man/man8/svscanboot.8.gz
        /usr/local/man/man8/svstat.8.gz
        /usr/local/man/man8/tai64n.8.gz
        /usr/local/man/man8/tai64nlocal.8.gz
        /usr/local/share/licenses/daemontools-0.76_16/LICENSE
        /usr/local/share/licenses/daemontools-0.76_16/PD
        /usr/local/share/licenses/daemontools-0.76_16/catalog.mk

設定

/etc/rc.conf , rc.conf.local, /etc/rc.conf.d/svscan などに設定できます。

# svscan_enable         Set to "YES" to run svscan.
# svscan_servicedir     The directory containing the various service.
#                       directories to be monitored.  Professor Daniel J.
#                       Bernstein recommends "/service", but the FreeBSD
#                       port has a default of "/var/service" instead, which
#                       is consistent with the FreeBSD filesystem hierarchy
#                       guidelines as described in the hier(7) manual page.
# svscan_logdir         If set, then svscan will not log its output through
#                       readproctitle, but through multilog instead, and
#                       the logs will be placed in the specified directory.
#                       The FreeBSD port default is to run svscan through
#                       readproctitle.
# svscan_lognum         The number of logfiles that multilog will keep if
#                       svscan_logdir is set; the multilog default is 10.
# svscan_logmax         The maximum logfile size for multilog if svscan_logdir
#                       is set; the multilog default is 99999.
 
 
svscan_enable="YES"
svscan_servicedir=/path/to/service
# svscan_logdir
# svscan_lognum
# svscan_logmax

svscanのコントロール

起動

sudo /usr/local/etc/rc.d/svscan start

停止

sudo /usr/local/etc/rc.d/svscan stop

再起動

sudo /usr/local/etc/rc.d/svscan restart

ステータス

sudo /usr/local/etc/rc.d/svscan status

コマンドの終了を待つ

sudo /usr/local/etc/rc.d/svscan poll

サービスが有効か確認する

サービスが有効な場合は、0、そうでなければ、1を返します。コマンドは、何も表示しません。

sudo /usr/local/etc/rc.d/svscan enabled

rc.confの設定を表示します

サービスの制御に使われるrc.conf変数を表示します。

sudo /usr/local/etc/rc.d/svscan rcvar

はじめてのdaemontools

ファイルとディレクトリの設置

mkdir -p service/foo/log
chmod +t service/foo

service/foo/run

デーモンにしたいプログラムを指定します。

#!/bin/sh
exec /tmp/foo
# vim: filetype=sh

service/foo/log/run

ロギングに使用するプログラムです。

#!/bin/sh
exec multilog t ./main
# vim: filetype=sh

/tmp/foo

stdoutとstderrにメッセージを出して、カウントが30を超えたら、終了してしまうプログラムです。

/*
 * main.c
 * Copyright (C) 2014 kaoru <kaoru@bsd>
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <err.h>
 
int
main(int argc, char *argv[])
{
        ssize_t c = 0;
        for(;;){
                puts("Hoge");
                warnx("Hello");
                fflush(stderr);
                fflush(stdout);
                c++;
                sleep(1);
                if (c > 30) {
                        puts("bye-bye");
                        exit(EXIT_FAILURE);
                }
        }
        exit(EXIT_SUCCESS);
}

コンパイルします。

$ cc -o /tmp/foo main.c

実行する

サービスを開始するには、svscan にディレクトリを指定して、起動します。svscanは、指定されたディレクトリのサブディレクトリを読み、サービスを起動します。svscanは、デーモンプログラムではありません。

$ svscan service

C-c で停止できます。

プロセスツリー

svscanを実行すると、以下の様なプロセスツリー(htopの表示の抜粋です)になります。

 1232 kaworu    121   0 62028  8348     0 S  0.0  1.7  0:30.63 │  ├─ -zsh
65867 kaworu    120   0 12312  1408     0 S  0.0  0.3  0:00.00 │  │  ├─ svscan service
65869 kaworu    121   0  8172  1384     0 S  0.0  0.3  0:00.00 │  │  │  ├─ supervise log
65871 kaworu    120   0 12280  1420     0 S  0.0  0.3  0:00.00 │  │  │  │  └─ multilog t ./main
65868 kaworu    120   0  8172  1384     0 S  0.0  0.3  0:00.00 │  │  │  └─ supervise foo
65872 kaworu    120   0 12260  1384     0 S  0.0  0.3  0:00.00 │  │  │     └─ /tmp/foo

プロセスの確認

以下は、実行中の状態です。

$ svstat service/foo
service/foo: up (pid 66630) 12 seconds

プロセスが起動していないときは、以下の様なメッセージになります。

$ svstat service/foo
service/foo: supervise not running

サービスの停止や起動

実行中のサービスの起動や停止は、svcコマンドで行います。 svcには、いくつものオプションがあります。起動と停止のオプションは以下の通りです。

-u
起動
-d
停止
$ svstat service/foo
service/foo: up (pid 67004) 31 seconds
$ svc -d service/foo
$ svstat service/foo
service/foo: down 2 seconds, normally up
$ svc -u service/foo
$ svstat service/foo
service/foo: up (pid 67027) 2 seconds

ログファイルの時間を読めるようにする

ログは、このような形で記録されています。これだと時間がよくわかりません。

$ head ./service/foo/log/main/@4000000053895ad80f103574.u
@4000000053895a2e1ef54524 Hoge
@4000000053895a2f1ff776cc Hoge
@4000000053895a3021686bec Hoge
@4000000053895a312211aff4 Hoge
@4000000053895a3222bba7ac Hoge
@4000000053895a33256bc3ec Hoge
@4000000053895a34285971e4 Hoge
@4000000053895a352af959b4 Hoge
@4000000053895a362be1fc64 Hoge
@4000000053895a372dcca5c4 Hoge

tai64nlocalコマンドで時間をヒューマンリーダブル(人間がわかる)にできます。

$ tai64nlocal < ./service/foo/log/main/@4000000053895ad80f103574.u |head
2014-05-31 13:27:16.519390500 Hoge
2014-05-31 13:27:17.536311500 Hoge
2014-05-31 13:27:18.560491500 Hoge
2014-05-31 13:27:19.571584500 Hoge
2014-05-31 13:27:20.582723500 Hoge
2014-05-31 13:27:21.627819500 Hoge
2014-05-31 13:27:22.676950500 Hoge
2014-05-31 13:27:23.720984500 Hoge
2014-05-31 13:27:24.736230500 Hoge
2014-05-31 13:27:25.768386500 Hoge

node.js

#!/bin/sh
exec setuidgid nobody /usr/local/bin/node /home/nodejs/http.js
# vim: filetype=sh

memcached

#!/bin/sh
exec setuidgid nobody /usr/local/bin/memcached -m 1024 -c 10240 -p 11211 -u nobody
# vim: filetype=sh

エラー

svc: warning: unable to control service/foo: supervise not running

おそらく、svscanが動いていません。

$ svc -u service/foo
svc: warning: unable to control service/foo: supervise not running

関連項目




スポンサーリンク