prometheusでテストアラート by pushgateway

# TL;DR
- prometheusの通知テストしたい
- pushgateway使ったらできた
- metricsごとテストをshell scriptにまとめとくと便利

# はじめに
prometheusのalert ruleやalertmanagerのreviecer定義を変えた際､その通知テストがしたい｡
てかpromtoolのcheck-configがとてもざるなので､slack上とかで実際にアラート鳴らしてみたら表示崩れたり...

そこでpushgatewayを使って偽metrics情報を送り込めるので(本来の使い方とは違うが)やってみた｡

# pushgatewayについて
- [prometheus/pushgateway: push acceptor for ephemeral and batch jobs](https://github.com/prometheus/pushgateway)
- exporterはpull型前提だけど､バッチとかpushでデータためたい時用のもの
- prometheus同様goのバイナリ落としてきて起動するだけ [release page](https://github.com/prometheus/pushgateway/releases)
- prometheusにはpushgatewayをみるようjob追加しておくこと

インストール+起動はこんな感じ

```bash:installation_of_pushgateway
# install
$ cd your_pushgateway_dir
$ wget https://github.com/prometheus/pushgateway/releases/download/v0.3.1/pushgateway-0.3.1.linux-amd64.tar.gz
$ tar xvf pushgateway-0.3.1.linux-amd64.tar.gz

# run
$ cd pushgateway-0.3.1.linux-amd64
$ ./pushgateway > pushgateway.log 2>&1 &

# confirm behavior
$ curl localhost:9091/metrics
---
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 6.0085000000000005e-05
go_gc_duration_seconds{quantile="0.25"} 6.0085000000000005e-05
...
---

```

prometheus側の設定もpushagateway足しとく

```bash:adding_pushgateway_to_prometheus

$ cd your_prometheus_dir
$ vim prometheus.yml
# add following
---
scrape_configs:
...
# add following
  - job_name:       'pushgateway'
    static_configs:
      - targets: ['localhost:9091']
        labels:
          environment: "hoge"
          category: "pushgateway"
...
# maybe following job has already existed.
  - job_name:       'hoge'
    static_configs:
      - targets: ['localhost:XXXX']
        labels:
          environment: "hoge"
          category: "anything"

...
---
# reload prometheus setting
$ curl -X POST http://localhost:9090/prometheus/-/reload

```

# pushgatewayへmetricsをpush
[pushgatewayのREADME.md](https://github.com/prometheus/pushgateway)にあるように
`hoge_metrics{job="TEST_JOB",host_name="TEST_HOST"}`

というgaugeのmetricsのアラートを鳴らしたいなら以下のようにcurlで送ればよい｡
labelをもっと足したければURLの後ろにどんどん/label_name/label_string/label_name/label_string/...と増やせば良い

```bash:push_sample_metrics
# push metrics
$ cat <<EOF | curl --data-binary @- http://localhost:9091/metrics/job/TEST_JOB/host_name/TEST_HOST/ENVIRONMENT/TEST_LOCATION
# TYPE hoge_metrics gauge
# HELP hoge_metrics
hoge_metrics 0.0
EOF

# confirm pushgaway metrics
$ curl localhost:9091/metrics
---
...
# TYPE hoge_metrics gauge
hoge_metrics{host_name="TEST_HOST",instance="",job="TEST_JOB"} 0
...
---

```

![prometheus.png](https://qiita-image-store.s3.amazonaws.com/0/26677/9ee0e3ea-885e-c227-c208-b7c91a92a189.png)
prometheus上からも確認できる｡

# テストアラートを鳴らす
では実際にアラート鳴らしてみる｡お試し条件としては､以下とする｡

alert rule定義例

```bash:alert.rule
ALERT hoge_alert
  IF hoge_metrics == 0
  FOR 1s
  LABELS {
    severity="critical",
  }
  ANNOTATIONS {
    summary = "hoge of {{ $labels.host_name }} is NG.",
  }

```

alertmanagerのreciever定義例


```bash:alertmanager.yml
global:

route:
  receiver: 'slack'
  group_by: [alertname, host_name]
  group_interval: 5s
  group_wait: 5s

receivers:
- name: 'slack'
  slack_configs:
    - api_url: 'https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXXXXXXXX'
      channel: '#alerting-test'
      text: "{{ .CommonAnnotations.summary }}"
      send_resolved: true

...

```

また､pushgatewayへのmetrics送付はshell script化(テストアラートスクリプト)しておくと便利｡
ここで､NG用だけだとずっとアラート鳴りっぱなしなのでOK用も作っておく(正常値のvalueにするだけ)｡
で､あとは鳴らすだけ｡

```bash:alert_scripts
$ cd your_pushgateway_dir
$ mkdir alert_tests
$ cd alert_tests

# create ng script
$ vim hoge_metrics_ng
---
cat <<EOF | curl --data-binary @- http://localhost:9091/metrics/job/TEST_JOB/host_name/TEST_HOST/ENVIRONMENT/TEST_LOCATION
# TYPE hoge_metrics gauge
# HELP hoge_metrics
hoge_metrics 0.0
EOF
---

# create ok script
$ vim hoge_metrics_ok
---
cat <<EOF | curl --data-binary @- http://localhost:9091/metrics/job/TEST_JOB/host_name/TEST_HOST/ENVIRONMENT/TEST_LOCATION
# TYPE hoge_metrics gauge
# HELP hoge_metrics
hoge_metrics 1.0
EOF
---

$ chmod +x hoge_metrics_*

# fire ng script
$ ./hoge_metrics_ng

# fire ok script
$ ./hoge_metrics_ok

```

![slack.png](https://qiita-image-store.s3.amazonaws.com/0/26677/32316107-03a3-f0a5-1172-5fcec668f38f.png)

できた｡

# まとめ
- alertを実際にならしてみてどう通知されるか?がコマンド1つ2つでできるのは便利
    - 特にresolved時に文言打ち分けとかlabelとvalueの情報をバキバキ通知に使ってると...
- 運用上気にすること
    - labelは好きに増やせるけどlabel名と中身のペアが崩れてるとエラーで拾ってくれない
    - metricsを増やしたらテストアラートスクリプトも一緒につくる
    - アラート種別分､テストアラートスクリプトにコマンドまとめるといっぺんに確認できて便利
    - NG用だけだとずっとアラート鳴りっぱなしなのでOK用も作っておく
    - metrics情報を汚す｡なので検証環境のprometheusに向け｡deleteもあるが...
    - pushgateway経由のmetricsはjobはるとexprted_jobとして突っ込まれる(↑のprometheusの図参照)
- その他
    - pushgatewayをmetrics/label変更時の過去データ引っ越しに使えないか...
なくはないが... 
    - しかしpushgatewayの使い方として､既存のmetrics上書きはいかがなものか

以上｡