Prometheus から切り離して Alertmanager を運用するための amtool の取り扱い

# amtool って最高じゃね？

Howdy! [Prometheus Advent Calendar 2018](https://qiita.com/advent-calendar/2018/prometheus) 23日目の sugitak です :yo: ！

Prometheus が良い点は色々あるわけですが、その多くの部分は Alertmanager の素晴らしさでもあります。 Alertmanager はその名の通り、アラートの出力抑制・内容まとめ・サイレンスやルーティングなど、開発運用に必要なアラートの細やかな制御を実現します。

そんな Alertmanager ですが、いまいち使い方の話が盛り上がっていない… MOTTAINAI
Alertmanager 付属の `amtool` を使えば Alertmanager の中身を自由自在にいじれるので、テストやデバッグはもちろん、 Prometheus　を使わずに単体で Alertmanager を使用することすら可能になってきます。

ということで、この記事では Alertmanager のパワーを最大限に生かすためのツールである amtool の使い方を載せておきます。自分用アンチョコとも言う。

# 準備

`alertmanager` 及び `amtool` を準備します。
alertmanager は apt や docker で気軽に利用可能となっています。

### alertmanager install

```
$ sudo apt install prometheus-alertmanager
```

apt の dependency に prometheus が入っていないので、 Alertmanager 単体でのインストールができます。これ、「わかってる」感あって好き。
docker では `prom/alertmanager` のイメージを持って来れば動くので、手が慣れていればそちらの方が安定するかと。

で、 alertmanager をいれただけだと `amtool` は入らないので、 `go get` でいれましょう。

```
$ go get github.com/prometheus/alertmanager/cmd/amtool
$ amtool
usage: amtool [<flags>] <command> [<args> ...]

View and modify the current Alertmanager state.

Config File: The alertmanager tool will read a config file in YAML format from one of two default config locations:
$HOME/.config/amtool/config.yml or /etc/amtool/config.yml

All flags can be given in the config file, but the following are the suited for static configuration:

  alertmanager.url
  	Set a default alertmanager url for each request
...
```

# amtool の使い方

amtool は、 golang で作られたシンプルな CLI ソフトウェアです。
アクセスさせたい Alertmanager のアドレスをオプションとして渡す必要があります。

```
$ amtool --alertmanager.url http://localhost:9093 alert
Alertname  Starts At  Summary
```

いちいち `--alertmanager.url http://localhost:9093` とか書いていられないので、設定ファイルを作成しましょう。 `/etc/amtool/config.yml` または `$HOME/.config/amtool/config.yml` に置いたものが反映されます。

```
$ cat /etc/amtool/config.yml
alertmanager.url: "http://localhost:9093"
```


## アラートの作成

このような形式でアラートを追加できます。 Prometheus でのデバッグ用途だけでなく、他ツールからもアラートを発行できるので最高に便利ですね。

```
$ amtool add <Alertname> [<label>=<value>]
```

例えばこんなアラートを追加して…

```
$ amtool alert add TooMuchOpenFiles Stage=staging Role=web
```

アラート一覧を見てみると、確かにアラートが追加されているのがわかります。わぁいアラート！あかりアラート大好き

```
$ amtool alert
Alertname         Starts At                Summary
TooMuchOpenFiles  2018-12-23 15:28:12 UTC
```

単に `alert` だと label が表示されないのでちょっと不便です。そんな時は `-o extended` オプション。ラベルも含め、詳細に閲覧できます。やったね。

```
$ amtool alert -o extended
Labels                                                   Annotations  Starts At                Ends At                  Generator URL
Role="web" Stage="staging" alertname="TooMuchOpenFiles"               2018-12-23 15:28:12 UTC  0001-01-01 00:00:00 UTC
```

こちらをデフォルト表示にしたい場合、設定ファイルに `output: "extended"` という行を付け加えることで設定できます。ちな verbose オプションは（まだ？）ない

```
$ cat /etc/amtool/config.yml
alertmanager.url: "http://localhost:9093"
output: "extended"
```

## アラートの削除

すでに作成されたアラートは、削除そのものはできません。できるのは、「終了した」と上書きすることか、それ以上発報されないようサイレントをすることだけです。
サイレンス設定は次の項目で見るとして、ここでは「削除」をみてみましょう。

```
$ amtool alert add TooMuchOpenFiles Stage=staging Role=web --end='2018-12-23T16:02:00Z'
$ amtool alert
Labels                                                   Annotations  Starts At                Ends At                  Generator URL
Role="web" Stage="staging" alertname="TooMuchOpenFiles"               2018-12-23 16:01:00 UTC  2018-12-23 16:02:00 UTC
```

先ほど追加した `TooMuchOpenFiles` アラートを上書きします。このとき、アラートの終了時刻を `--end` オプションに RFC 3339 形式にて渡します。

このとき、　`--end` オプションには、今より未来の時間を入れる必要があります。上の書き方では `--start` オプションを省略しているため、デフォルトとして現在時刻を入れられており、そして `end` は `start` よりもあとでなければならないという制約があるのです。 `amtool: error: start time must be before end time (code: 400)` というエラーが出たら多分これです。（結構ハマった）
なお `--start` を過去の時間にして `--end` も過去の時刻にするというのは可能です。

## アラートのサイレント

うるさいアラートを一時的に黙らせたいなら、 `amtool silence` コマンドの出番です。
まあ本来であれば黙らせるようなアラートは作るなという話なんですが、現実はそうはいかないので、どうしてもこういうシーンは出てきますよね。

……えっ、出てこない？……そっか、よかったね……ここでおかえりください……

```
$ amtool silence add alertname=TooMuchOpenFiles -c 'sugitak: うるさーい！'
bef9a58f-7cfc-49d9-b01c-2aea98080eb9
```

出る人向けに説明すると、 `amtool silence add` でサイレンスを追加します。また、 `-c` オプションでそのサイレンスのコメントを追加します。私のバージョン（`alertmanager 0.16.0-alpha.0`）ではコメント必須でした。

```
$ amtool silence
ID                                    Matchers                    Starts At                Ends At                  Updated At               Created By  Comment
bef9a58f-7cfc-49d9-b01c-2aea98080eb9  alertname=TooMuchOpenFiles  2018-12-23 15:33:27 UTC  2018-12-23 16:33:27 UTC  2018-12-23 15:33:27 UTC  sugitak     sugitak: うるさーい！
```

silence 削除は `amtool silence expire <ID>` と素直。

```
$ amtool silence expire bef9a58f-7cfc-49d9-b01c-2aea98080eb9
```

全部消すなら単純なシェル芸で十分。

```
$ amtool silence | awk '/^[^I]/ {print $1;}' | xargs amtool silence expire
```

そんな感じです。便利ですね！

# まとめ

というわけで、 Alertmanager を使ううえで便利このうえない `amtool` の使い方をご説明しました。まあ、全部 `github.com/prometheus/alertmanager` のどこかには書いてあるんですけどね。見つけるのは地味に大変なので、勉強がてら記事にしてみた、というわけです。

さて、今年は Qiita の Prometheus Advent Calendar があまりに閑散としているのでビックリしていますが、これも Prometheus が使われていないからではなく、むしろ普通に使うだけなら工夫しなくても使えてしまってあまり書くことがないからだろうなと思っています。
Kubernetes や Gitlab は既に Prometheus に対応し、さまざまな場面で活用されているわけですが、今年は [Nomad](https://www.hashicorp.com/blog/nomad-learning-resources-2018-12) までも Prometheus 形式での出力を発表し、勢いはとどまるところを知りません。いよいよ observability が開発者のものになりつつあるのを感じますね。

みなさま、 Happy Prometheus Life および良い年末年始をお過ごしください。