日付を指定してMackerelのアラート一覧を取得するスクリプトを書いた

Mackerel Advent Calendar 2020 17日目の記事です。

こんにちは。株式会社はてな MackerelチームでCREをしています。 今回はよくユーザーの方からお問い合わせをいただいていることについて素朴にbashを書いてみたというお話です。

モチベーション

アラートの一覧をCSVなどでダウンロードできませんか?というようなお問い合わせをユーザーの方から受けることが度々あります。 用途としては、直接Mackerelを参照しない上司や、企画・開発チームへ運用チームから定期的にレポートを提出する際に週や月のアラート件数を掲載したい、などの場合です。

それ以外にも様々な状況から最終的に「アラートの一覧をCSVなどでダウンロードしたい」という要望になっているのだろうと想像しますが、たとえば、アラートが多すぎてそれに対する調査や分析をしたいとき、なんだかんだでアラート一覧をスプレッドシートExcelを使ってごにょごにょしたい、ということはありそうだな、と思っています。メモを書いて分類したり、関数やピボットテーブルを使って件数などを調べたり...数分でぱぱっとやりたいということもありそうですよね。

今回はbashでこのケースに答えられるようなスクリプトを書いてみました。 ユースケースは定期的なレポートへの利用を想像していたので、日付を指定してその期間のものだけを取得できるようにしました。

できたものその1:日付を指定してアラート一覧を取得するスクリプト

実際のコード

実際のコードはgistに置いてあります。

get-alerts-list-date-range.sh · GitHub

(同じような処理を2回書いているので、もっとスリム化できるかもしれません...)

長くなってしまったのでここに全行を載せるということはしませんが、かいつまんでポイントになっていそうなところをご紹介していきます。 このスクリプトの中では、Mackerelのアラート一覧を取得するAPIを実行しています。 詳しい仕様はヘルプページに記載があります。 APIを実行している箇所を抜き出すとこのような形です。

MACKEREL_APIKEY=<YOUR_MACKEREL_APIKEY>
LIMIT=100

curl -GsS \
     -X GET \
     -H 'X-Api-Key: '${MACKEREL_APIKEY} \
     -H 'Content-Type: application/json' \
     -d withClosed=true \
     -d limit=${LIMIT} \
     https://api.mackerelio.com/api/v0/alerts

オプションとして指定しているwithClosedlimitはそれぞれ以下のようなものです。

  • withClosed:クローズ済みのアラートも合わせて取得されます。
  • limit:最大で100まで指定できます。一度のAPIリクエストで取得するアラート件数を指定できます。

これをこのまま手元で実行してみても結果が返ります。

{
  "alerts": [
    {
      "monitorId": "3fRvMzJdWgA",
      "hostId": "3y8DxzS6Y6W",
      "id": "42fDeqZZTqL",
      "type": "connectivity",
      "status": "CRITICAL",
      "openedAt": 1599188103
    },
    {
      "monitorId": "3gvaG3eP4cN",
      "id": "42fCW1JANsU",
      "type": "external",
      "message": "net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)",
      "value": null,
      "status": "CRITICAL",
      "openedAt": 1599187945
    }
  ],
  "nextId": "42fyMXWiWK3"
}

結果はJOSN形式で返るので、それをjqコマンドで整形していきます。

整形後の区切り文字はカンマ(CSV)ではなくタブ(TSV)にします。 なぜかというと、messageの値に,が含まれる可能性があるためです。

echo "${JOSN}" | jq -r '.'| jq -r '.alerts[]|[.id,.status,.monitorId,.type,.hostId,.value,.message,.reason,.openedAt,.closedAt] | @tsv'

整形するとこんな感じになります。このスクリプトでは指定した期間内のアラートを以下のようなTSV形式で出力するので、これをファイルなどに書き込めば、スプレッドシートExcelで読み込むことができます。

42fDeqZZTqL  CRITICAL    3fRvMzJdWgA connectivity    3y8DxzS6Y6W             1599188103  
42fCW1JANsU CRITICAL    3gvaG3eP4cN external            net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)        1599187945

100件以上のアラートを取得したいとき(nextIdについて)

上記でもご紹介したとおり、アラート取得APIでは、一度に取得できるアラートが100件までと決まっています。 100件以上のアラートを取得するには、APIの応答に含まれるnextIdをオプション指定して再度APIを実行する必要があります。

nextIdを指定したAPIの実行はこのような形です。

curl -GsS \
       -X GET \
       -H 'X-Api-Key: '${MACKEREL_APIKEY} \
       -H 'Content-Type: application/json' \
       -d withClosed=true \
       -d limit=${LIMIT} \
       -d nextId=${NEXT_ID} \
       https://api.mackerelio.com/api/v0/alerts

100件、200件と遡らないと取得したい期間のアラートがすべて取得できない場合は、取得しきるまでforwhileで繰り返し処理をする必要があります。 スクリプトでは、その処理をwhileで実行しています。

詳しくはスクリプトをご覧ください。

別に日付指定はしなくてよいという場合はmkrコマンドが圧倒的に楽

今回は、日付指定したい場合を想定していたのでbashを書いてみたのですが、日付を指定せず直近xx件のアラート一覧を見たい、という場合であればmkrコマンドを利用するのが圧倒的に楽です。

MackerelにはmkrコマンドというCLIツールがあります。

作業端末や踏み台サーバーなどにインストールしておけば、curlコマンドやスクリプトを書かなくても簡単にAPIと同様の操作を実行することができます。 ただし、mkrコマンドでは一部のAPIは実行することができないので注意が必要です。

mkrで何ができるかを確認するには一度インストールして、mkr --help を見てみるのが手っ取り早いです。

mkrのインストール方法などはヘルプページに記載があります。

mackerel.io

mkrコマンドでアラート一覧を取得するコマンドは以下です。

mkr alerts list -w -l 1000

-wAPIで言うところのwithClosed-llimitに当たります。

見てお気づきかもしれませんが、mkrコマンドでは、limitに100件以上の件数を指定することができます。 コマンド内で繰り返しの処理を行ってまとめて出力してくれるので自分で処理を書く必要がありません。 ここでは1000件取得するコマンド例を記載しています。

他にもオプションによって、取得する対象のサービスを絞ることなどもできます。

実行結果はこのような形です。

42fDeqZZTqL 2020-09-04 11:55:03 CRITICAL  connectivity missasan-wp poweroff [missasan-blog:db,web]
42fCW1JANsU 2020-09-04 11:52:25 CRITICAL  wp-url http://<URL> 0.00 msec, net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

APIを実行した際にIdで出力されていたホスト名や監視ルール名なども表示されていて、わかりやすいです。

区切り文字がスペースなので、出力結果から列を抜き出したい場合などには少し工夫が必要そうです。

できたものその2:アラート件数をサービスメトリックとして投稿するスクリプト

せっかく一覧が取得できるようになったので、アラートの件数をサービスメトリックとしてMackerelに投げてみるということも試してみました。

作成したスクリプトは以下2つです。

  • get-alerts-list-1day.sh
    • コード:get-alerts-list-1day.sh · GitHub
    • 使用方法:get-alerts-list-1day.sh > /path/to/logfile
    • 実行すること:現在から過去1日分のアラートを取得する
  • post-mackerel-alerts-count.sh

これら2つをcronなどで定期実行すると、get-alerts-list-1day.sh の出力結果をファイルに書き出し、post-mackerel-alerts-count.shでそのファイルを読み込んで件数をサービスメトリックとして投稿する、という処理が動き、こんな感じでアラート数がグラフとして記録されていきます。

cronの記載例はシンプルですが、こんな感じです。

* * * * * /path/to/get-alerts-list-1day.sh > /path/to/logfile
* * * * * /path/to/post-mackerel-alerts-count.sh

あまり稼働しておく時間をとれなかったので平坦なグラフになってしまいましたが、イメージは伝わるかと思います。

f:id:missasan:20201216113639p:plain:w600

過去1日で、チェック監視(check)が226件、ホストメトリック監視が33件のアラートが起票されたことがわかります。

最後に

あらためてポイントをまとめます。

  • APIでアラートを取得するときは、1リクエストにつき最大100件まで
  • nextIdを指定して100件以上のアラートを取得する
  • mkr alertsは便利

以上です。

アドベントカレンダーらしく、日々のちょっとした気になりごとを実際に試してみました。 アラート取得APIでもまだまだいろいろと遊んでみることができそうです。




お知らせ

普段は、Mackerelをこれからはじめる、またははじめたてのユーザーの方々に向けてオンラインセミナーを開催させていただいたりもしています。