passenger-statusを監視するMackerelのプラグイン

業務でPassengerのパラメーターチューニングが必要になり`passenger-status`で状態を見ていましたが、そのコマンドだけでは継続的に監視できませんでした。

たまたま監視ツールにMackerelを使っていて、まだPassengerを監視するプラグインがなかったので作りました。

## 結果

![mackerel-screenshot-00.png](https://qiita-image-store.s3.amazonaws.com/0/20045/9f82e16a-b50b-cdcb-fcb6-c4f5a45dac7e.png)

こんな感じでPassengerの総メモリ使用量と立ち上がっているPassengerのプロセス数、Queueに入っているプロセスの数を監視できるようになりました。

##　やったこと

`passenger-status`コマンドの出力をパースして各指標を計算して標準出力に出力するコマンドをGo言語で実装しました。出力形式はMackerelプラグインの仕様に従っています。

### `passenger-status`の出力

`--no-header`で余分なヘッダーを省いてます。

```
$ sudo bundle exec passenger-status --no-header
----------- General information -----------
Max pool size : 6
App groups    : 1
Processes     : 3
Requests in top-level queue : 0

----------- Application groups -----------
/path/to/passenger-ruby-sinatra-demo/public (development):
  App root: /path/to/passenger-ruby-sinatra-demo
  Requests in queue: 0
  * PID: 60021   Sessions: 0       Processed: 5       Uptime: 45s
    CPU: 0%      Memory  : 8M      Last used: 21s ago
  * PID: 60022   Sessions: 0       Processed: 0       Uptime: 45s
    CPU: 0%      Memory  : 1M      Last used: 45s ago
  * PID: 60025   Sessions: 0       Processed: 0       Uptime: 45s
    CPU: 0%      Memory  : 1M      Last used: 45s ago
```

passengerのサンプルアプリケーションは
https://github.com/phusion/passenger-ruby-sinatra-demo
を使いました。

### `mackerel-plugin-passenger`（今回作ったプラグイン）の出力

```
passenger.memory.total_memory   10485760        1513207571
passenger.processes.processes_in_queue  0       1513207571
passenger.processes.total_processes     3       1513207571
```

ここでは3つのメトリクスを出力していて、
1行目がpassengerのプロセスの合計メモリ使用量
2行目がpassengerのキューに入っているリクエスト数の合計
3行目が立ち上がっているpassengerのプロセスの合計数

です。順番は出力するときによって変わっていいみたいです。というか変わってました。

## 実装したもの

https://github.com/nabewata07/mackerel-plugin-passenger
ここにおいてます。

## 実装方法

プラグインの仕様としては標準出力に
`メトリクス名 値 UNIXタイムスタンプ`
の順に出力すればよく、複数のメトリクスを飛ばす場合は改行してそれぞれ1行ずつに出力すれば良いです。
なので実装はGo言語以外の言語でも可能です。

###　go-mackerel-pluginを利用する

Go以外でも可能なんですが、Go言語であれば
https://github.com/mackerelio/go-mackerel-plugin
こちらのライブラリを使って

https://mackerel.io/ja/docs/entry/advanced/go-mackerel-plugin
こちらの説明を参考にして実装すればプラグインの仕様に沿った出力をいい感じにやってもらえるので楽です。

## mkr plugin installでインストールできるようにする

mackerelは`mkr`というコマンドラインツールを提供していて、Githubからプラグインを直接インストールすることができます。
https://mackerel.io/ja/docs/entry/advanced/install-plugin-by-mkr
https://mackerel.io/ja/blog/entry/feature/20171116

###　必要な作業

`go-mackerel-plugin`を使ってプラグインを実装した後に
https://mackerel.io/ja/docs/entry/advanced/make-plugin-corresponding-to-installer
こちらの「プラグインが仕様を満たすように設定する」の作業を行うだけです。
設定ファイルを1つコピペして、コマンドを高々4つ実行するだけだったのでかなり簡単でした :) 

###　mkrでインストールしてみる

mkr自体のインストール方法は
https://mackerel.io/ja/docs/entry/advanced/cli
にかかれています。

実際にmkrでインストールしてみます。

```
$ sudo mkr plugin install nabewata07/mackerel-plugin-passenger
           Downloading https://github.com/nabewata07/mackerel-plugin-passenger/releases/download/v0.0.7/mackerel-plugin-passenger_darwin_amd64.zip
           Installing /opt/mackerel-agent/plugins/bin/mackerel-plugin-passenger
           Successfully installed nabewata07/mackerel-plugin-passenger
```

https://mackerel.io/ja/docs/entry/advanced/install-plugin-by-mkr
　こちらにも書かれていますがGithub上にあれば

> ```
> $ mkr plugin install <owner>/<repo>[@<release_tag>]
> ```

でインストール可能で、デフォルトだと
`/opt/mackerel-agent/plugins/bin/` 以下にコマンドがインストールされます。

※2017/12/28追記
公式プラグインレジストリに取り込んでもらったので
https://github.com/mackerelio/plugin-registry/pull/14#issuecomment-353944341
リポジトリオーナーを指定しなくても

```
mkr plugin install mackerel-plugin-passenger
```

でインストールできるようになりました。

※追記終わり

## 所感

プラグイン作成用のライブラリを公開してくれていて、公式ページの説明も充実しているので作り始めてから動かすまでがとても早くできる印象です。
また、`goxc`と`ghr`がとても便利で、コマンドを2回叩くだけで各プラットフォーム用の実行バイナリの作成とGithubへのリリースができることに感動しました。