はじめに
td-agentの監視と万が一の時の自動起動にmonitを使いたいと思って調べた
monit とは?
個人的な解釈としては monit とは以下のような機能がある。
- 指定されたプロセスの監視
- 指定されたプロセスが停止した場合には自動的にプロセスを再起動する
公式サイトはこちら。
monit -h
とりあえず monit -h でどんなオプションがあるかを確認。
Usage: monit [options] {arguments}
Options are as follows:
-c file Use this control file
-d n Run as a daemon once per n seconds
-g name Set group name for start, stop, restart, monitor and unmonitor
-l logfile Print log information to this file
-p pidfile Use this lock file in daemon mode
-s statefile Set the file monit should write state information to
-I Do not run in background (needed for run from init)
-t Run syntax check for the control file
-v Verbose mode, work noisy (diagnostic output)
-vv Very verbose mode, same as -v plus log stacktrace on error
-H [filename] Print SHA1 and MD5 hashes of the file or of stdin if the
filename is omited; monit will exit afterwards
-V Print version number and patchlevel
-h Print this text
Optional action arguments for non-daemon mode are as follows:
start all - Start all services
start name - Only start the named service
stop all - Stop all services
stop name - Only stop the named service
restart all - Stop and start all services
restart name - Only restart the named service
monitor all - Enable monitoring of all services
monitor name - Only enable monitoring of the named service
unmonitor all - Disable monitoring of all services
unmonitor name - Only disable monitoring of the named service
reload - Reinitialize monit
status - Print full status information for each service
summary - Print short status information for each service
quit - Kill monit daemon process
validate - Check all services and start if not running
procmatch <pattern> - Test process matching pattern
(Action arguments operate on services defined in the control file)
-t オプションでテストも出来るというのは怠惰な自分には有り難い。
試す
以下の環境で試した。
簡単な設定
インストール直後は下記のように /etc/minit/ 以下にファイルが作成される。尚、インストールは apt-get install monit で楽ちん。
# tree
.
|-- conf.d
| `-- cron
|-- monitrc
|-- monitrc.d
| |-- cron
| `-- openssh-server
`-- templates
|-- rootbin
|-- rootrc
`-- rootstrict
3 directories, 7 files
cron のプロセスを監視するので monitrc.d 以下にある cron ファイルを conf.d 以下にコピーして利用した。(※monitrc.d 以下に置いておくだけではプロセスは監視してくれなかった...)
sudo cp monitrc.d/cron conf.d/
コピーしたら monit のプロセスを再起動する。
/etc/init.d/monit restart
これで monit から crond の監視が開始されることになる。ちなみに、 /etc/monit/conf.d にコピーした cron ファイルは下記の通り。
check process crond with pidfile /var/run/crond.pid group system group crond start program = "/etc/init.d/cron start" stop program = "/etc/init.d/cron stop" if 5 restarts with 5 cycles then timeout depend cron_bin depend cron_rc depend cron_spool check file cron_bin with path /usr/sbin/cron group crond include /etc/monit/templates/rootbin check file cron_rc with path "/etc/init.d/cron" group crond include /etc/monit/templates/rootbin check directory cron_spool with path /var/spool/cron/crontabs group crond if failed permission 1730 then unmonitor if failed uid root then unmonitor if failed gid crontab then unmonitor
cron のプロセスを止めてみる
早速、意図的に cron のプロセスを止めてみる。
/etc/init.d/cron stop
しばらく(今回の環境で計測したら約 120 秒)すると /var/log/monit.log に以下のようなログが出力されて crond が再起動される。
[JST Dec 6 11:03:20] error : 'crond' process is not running [JST Dec 6 11:03:20] info : 'crond' trying to restart [JST Dec 6 11:03:20] info : 'crond' start: /etc/init.d/cron [JST Dec 6 11:05:20] info : 'crond' process is running with pid 3192
cron のプロセスが起動しているかを確認する。
# ps aux | grep cron root 3192 0.0 0.0 18880 860 ? Ss 11:03 0:00 /usr/sbin/cron
おお。
も少し突っ込んで挙動を見てみる
デバッグモードで起動
-vv を付けて monit を起動するとデバッグモードで起動するので、それを利用して monit がどんなお仕事をしているのかを見てみる。
--- monit.original 2013-12-06 11:10:36.995894157 +0900 +++ monit 2013-12-06 11:08:40.035898212 +0900 @@ -25,7 +25,7 @@ DELAY="/etc/monit/monit_delay" NAME=monit DESC="daemon monitor" -MONIT_OPTS= +MONIT_OPTS="-vv" PID="/var/run/$NAME.pid" # Check if DAEMON binary exist
/etc/init.d/monit を上記のように修正して monit を再起動する。
もう一回 cron を止めてみる
先ほどと同様に cron のプロセスを停止してからしばらくすると以下のようなログが出力された。
[JST Dec 6 11:10:43] debug : 'cron_bin' file exists check succeeded [JST Dec 6 11:10:43] debug : 'cron_bin' is a regular file [JST Dec 6 11:10:43] debug : 'cron_bin' has valid checksums [JST Dec 6 11:10:43] debug : 'cron_bin' permission check succeeded [current permission=0755] [JST Dec 6 11:10:43] debug : 'cron_bin' uid check succeeded [current uid=0] [JST Dec 6 11:10:43] debug : 'cron_bin' gid check succeeded [current gid=0] [JST Dec 6 11:10:43] debug : 'cron_rc' file exists check succeeded [JST Dec 6 11:10:43] debug : 'cron_rc' is a regular file [JST Dec 6 11:10:43] debug : 'cron_rc' has valid checksums [JST Dec 6 11:10:43] debug : 'cron_rc' permission check succeeded [current permission=0755] [JST Dec 6 11:10:43] debug : 'cron_rc' uid check succeeded [current uid=0] [JST Dec 6 11:10:43] debug : 'cron_rc' gid check succeeded [current gid=0] [JST Dec 6 11:10:43] debug : 'cron_spool' directory exists check succeeded [JST Dec 6 11:10:43] debug : 'cron_spool' is directory [JST Dec 6 11:10:43] debug : 'cron_spool' permission check succeeded [current permission=1730] [JST Dec 6 11:10:43] debug : 'cron_spool' uid check succeeded [current uid=0] [JST Dec 6 11:10:43] debug : 'cron_spool' gid check succeeded [current gid=102] [JST Dec 6 11:10:43] debug : monit: pidfile '/var/run/crond.pid' does not exist [JST Dec 6 11:10:43] error : 'crond' process is not running [JST Dec 6 11:10:43] debug : ------------------------------------------------------------------------------- [JST Dec 6 11:10:43] debug : /usr/bin/monit() [0x41c07a] [JST Dec 6 11:10:43] debug : /usr/bin/monit(LogError+0xa0) [0x41c7d0] [JST Dec 6 11:10:43] debug : /usr/bin/monit(Event_post+0x20a) [0x418ada] [JST Dec 6 11:10:43] debug : /usr/bin/monit(check_process+0xa2) [0x42b312] [JST Dec 6 11:10:43] debug : /usr/bin/monit(validate+0x2fe) [0x42b23e] [JST Dec 6 11:10:43] debug : /usr/bin/monit(main+0x99f) [0x40d32f] [JST Dec 6 11:10:43] debug : /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd) [0x7f024d240ead] [JST Dec 6 11:10:43] debug : /usr/bin/monit() [0x40d6b5] [JST Dec 6 11:10:43] debug : ------------------------------------------------------------------------------- [JST Dec 6 11:10:43] info : 'crond' trying to restart [JST Dec 6 11:10:43] debug : monit: pidfile '/var/run/crond.pid' does not exist [JST Dec 6 11:10:43] debug : monit: pidfile '/var/run/crond.pid' does not exist [JST Dec 6 11:10:43] info : 'crond' start: /etc/init.d/cron [JST Dec 6 11:10:43] debug : monit: pidfile '/var/run/crond.pid' does not exist
どうやら下記のようなことが /etc/monit/conf.d/cron に記述された内容に基づいて行われているっぽい。
- プロセスの実行ファイルの所在のチェックとパーミッションチェック
- rc スクリプトの所在のチェックとパーミッションチェック
- cron のスプールディレクトリの所在のチェックとパーミッションチェック
- PID ファイルの所在確認
改めて /etc/monit/conf.d/cron とログを照らしあわせて確認すると...
プロセスの実行ファイルの所在のチェックとパーミッションチェック
check file cron_bin with path /usr/sbin/cron group crond include /etc/monit/templates/rootbin
rc スクリプトの所在のチェックとパーミッションチェック
check file cron_rc with path "/etc/init.d/cron" group crond include /etc/monit/templates/rootbin
cron のスプールディレクトリの所在のチェックとパーミッションチェック
check directory cron_spool with path /var/spool/cron/crontabs group crond if failed permission 1730 then unmonitor if failed uid root then unmonitor if failed gid crontab then unmonitor
という感じであらかじめ各プロセスの監視ファイル(例:/etc/monit/conf.d/cron)に プロセスが正しく稼働している状態を任意で記述 することで、それを基に monit はチェックを行いプロセスの死活を監視していると思われる。
最後に
- なにげなく
monitを使えばイイヂャんって思っていたけどちゃんと調べて良かった - 正しく動作している状態を記述してテストするという意味では監視ツールという側面と
serverspecのようなツールの側面も持ちあわせていると思った - 異常を検知してプロセスを再起動するまでの時間はどこで定義されていて調整が可能なのかな?
- まだまだ続く(
td-agentで利用しなければいけないので) - そもそもだけど、
td-agentって運用開始してから落ちてしまうってことが無いくらいに安定しているからなー