Amazon Linuxでmonitを使ってカジュアルにプロセス監視する！


Amazon Linuxで構築したサーバでプロセス監視したいなぁと思って調べたところ、[monit](https://mmonit.com/monit/ "monit")が簡単そうだったので導入してみた。

## 初期セットアップ

### インストール

yumでサクッとインストールできる。

```bash
$ yum install -y monit
```

2015年11月現在では、下記のバージョンでインストールされた。

```bash
$ monit -V
This is Monit version 5.2.5
```


### デフォルト設定：/etc/monit.conf

では初期設定を確認してみよう。

コメントがいっぱい書いてあるが、それを無視すると、初期設定で書かれてるのは二行だけ。

```bash
$ cat /etc/monit.conf | grep -v -e '^\s*#' -e '^\s*$'
set daemon 60
include /etc/monit.d/*
```

簡単に解説。

```bash
set daemon 60
```

これは監視間隔。デフォルトでは60秒に設定されてるようだ。

monitは秒単位で監視間隔が設定でき、もっと短い間隔でも監視できるが、短くし過ぎると負荷が上がりそうなので、普通のアプリケーションはこのぐらいの間隔でいい気がする。

```bash
include /etc/monit.d/*
```

設定ファイルのinclude設定。デフォルトでは **/etc/monit.d/** ディレクトリ配下にmonitの設定ファイルを置くと、勝手に読んでくれる。


### デフォルト設定：/etc/monit.d/

では次に、 **/etc/monit.d/** を覗いてみる。

```bash
$ ls /etc/monit.d/
logging
```

すると、最初からロギング設定のファイルが置いてある。


```bash
$ cat /etc/monit.d/logging | grep -v -e '^\s*#' -e '^\s*$'
set logfile /var/log/monit
```

ログが **/var/log/monit** に出力されるという設定だけが記述されている。

ログはsyslogに吐いたりもできるらしいが、ここではとりあえずそのままにしておく。


## 監視設定

デフォルト設定が確認できたので、早速プロセス監視を試してみる。

ここでは、sshdを例に設定ファイルを作成する。

### 設定ファイル作成

**/etc/monit.d/** 配下に適当なファイル名で設定ファイルを作成する。

```bash
$ vi /etc/monit.d/sshd.conf

check process sshd with pidfile /var/run/sshd.pid
start program = "/etc/rc.d/init.d/sshd start"
stop  program = "/etc/rc.d/init.d/sshd stop"
if 5 restarts within 5 cycles then unmonitor
```

ほとんど見たまんまだが、軽く解説。

```bash
check process sshd with pidfile /var/run/sshd.pid
```

監視対象のプロセスのpidファイルを指定。

なお、Webで検索すると、ほとんどpidファイルを指定した監視設定ばかり出てくるが、pidがないアプリケーションも監視できる。


```bash
start program = "/etc/rc.d/init.d/sshd start"
stop  program = "/etc/rc.d/init.d/sshd stop"
```

プロセスの起動／終了方法を指定。

```bash
if 5 restarts within 5 cycles then unmonitor
```

5回再起動を試みて、ダメだったら監視対象から外す。

どう頑張っても起動しないのに、無限に再起動を試みないようにしている。


### monit起動

それでは、monitを動かしてみよう。


```bash
$ service monit start
```


### 動作確認

とりあえず、sshdを止めてみる。

```bash
$ service sshd stop
$ service sshd status
openssh-daemon is stopped
```

この状態で、monitのログをtailしてみる。

監視間隔がデフォルトのままなら、一分以内に、下記のようなのログが流れてくる。

```bash
$ tail -f /var/log/monit
・・・・・・
[JST Nov  1 13:12:38] error    : 'sshd' process is not running
[JST Nov  1 13:12:38] info     : 'sshd' trying to restart
[JST Nov  1 13:12:38] info     : 'sshd' start: /etc/rc.d/init.d/sshd
```

ログを確認した後に、sshdのステータスを見てみる。

```bash
$ service sshd status
openssh-daemon (pid  2562) is running...
```

ちゃんとプロセスが再起動した。ヤッタネ！


## monit自体が死なないようにする

プロセス監視をするmonitさんがお亡くなりになると、非常にツライことになるので、upstartを使って死なないようにする。

### 起動してるサービスを停止

先ほど手動で起動したサービスは一旦止めておく。

```bash
$ service monit stop
```

### 設定ファイル作成

[ココ](https://github.com/arnaudsj/monit/blob/master/contrib/monit.upstart)を参考に設定ファイルを作成。


```
$ vi /etc/init/monit.conf

description "Monit service manager"

start on runlevel [2345]
stop on runlevel [!2345]

respawn

exec /usr/bin/monit -Ic /etc/monit.conf

pre-stop exec /usr/bin/monit -Ic /etc/monit.conf quit
```

### 設定反映＆起動

作成した設定を読みこませる。

```bash
$ initctl reload-configuration
```

設定が読み込まれてることを確認。

```bash
$ initctl list | grep monit
monit stop/waiting
```

次にmonitを起動する。

```bash
$ initctl start monit
monit start/running, process 7145
```

では、早速monitを殺してみる。


```bash
$ kill 7145
```

で、プロセスを確認。

```bash
$ initctl list | grep monit
monit start/running, process 7148
```

ちゃんと蘇った！


## 定期的に監視を復活させる

監視設定で、下記のような記述を書くと、監視が外れる場合がある。

```bash
if 5 restarts within 5 cycles then unmonitor
```

無限に再起動を試みられるのも問題だが、ずっと監視が外れるのも具合が悪い。

というわけで、定期的にmonitによる監視を復活させる。


### 事前準備

定期的に監視を復活させるのに使う、monitor allはhttp経由で実行される。

というわけで、http経由で叩けるように **/etc/monit.conf** 設定を追加する。

```bash
$ echo "set httpd port 2812 and use address localhost allow localhost" >> /etc/monit.conf
```

ちなみに、外から叩ける必要がないので、ココでは、localhostからのアクセスのみ許可している。


### cronを仕掛ける

とりあえず、一時間に一回ぐらいの頻度で実行することにした。

```bash
$ echo "0 */1 * * * /usr/bin/monit monitor all" >> /var/spool/cron/root
```

### 参考

* monit使う場合は定期的にmonit monitor allしたほうが良い
 * http://hogem.hatenablog.com/entry/20090723/1248358467


## CloudWatch Logsにログを投げつける

AWSを使っている場合、CloudWatch Logsにログを集約しておくと便利なので、monitのログも放り込んでおこう。

なお、CloudWatch Logs自体のインストールが完了していない場合は、先にそちらを済ませておいてほしい。


### monitのログを収集するよう追記

**/var/log/monit** をCloudWatch Logsに食わせる設定を追記。

```
$ vi /etc/awslogs/awslogs.conf

[/var/log/monit]
file = /var/log/monit
log_stream_name = {hostname}
log_group_name = /var/log/monit
```

### 再起動

再起動しておく。

```bash
$ service awslogs restart
```

で、しばらくすると、CloudWatch Logsにmonitのログが流れてくるようになる。

必要があればアラーム設定とか入れとくといい感じだろう。

ちなみに、monit単体でもメール投げたりできるけど、AWSの場合は、CloudWatch Logsを活用したほうが柔軟性が高くなると思う。


## まとめ

というわけで、monit歴1日のオレの作業メモを元に、手順を整理してみた。

まだちゃんと運用してないので、ツッコミどころも多いだろうけど、スタートとしては悪くないと思うので、monit初心者な人はぜひ参考にしてほしい。

ちなみに、はじめてQiitaに投稿してみたけど、外部に公開する文章を書くのは非常にエネルギーが必要だという事がわかった。


いつも情報公開をして助けてくれてる皆様、本当にありがとう。