[PR] あなたが Kindle で読みたいその本、Kindle に対応したら Twitter でお知らせします。

Mackerel でステータスが working 以外のホストを Slack に通知する

Posted on

Mackerel にはステータスという機能があり、監視対象となるホストの状態に合わせて監視や通知を制御できます。ステータスは working, standby, maintenance, poweroff の 4 つがあり、通常は working に設定します。

具体的な使い方として、たとえばサービスから切り離してメンテナンスするときは maintenance にすることで監視と通知を一時的に無効にできます。他にも、アクティブ・スタンバイ構成でスタンバイサーバを standby に設定すれば、監視はするが通知はしないということができます。

ステータス機能は便利な反面、戻し忘れると障害が起きても監視・通知されないという危険な状態になります。

というわけで、working 以外のホストがないかチェックし、あった場合は Slack に通知するようにしてみました。

mkr コマンドでチェックする

Mackerel には API もありますが、mkr という CLI ツールが用意されています。 AWS でいうところの AWS CLI のようなツールです。

mkr コマンドを使うとホストの情報を簡単に取得できます。ステータスで絞り込むには --status オプションを使います。

$ mkr hosts --status standby --status maintenance --status poweroff
[
    {
        "id": "xxxxxxxxxxx",
        "name": "db.test.com",
        "status": "standby",
        "roleFullnames": [
            "test:db"
        ],
        "isRetired": false,
        "createdAt": "Jun 28, 2016 at 10:33pm (JST)",
        "ipAddresses": {
            "eth0": "xxx.xxx.xxx.xxx"
        }
    }
]

こんな感じでステータスが working 以外のホストを取得できます。 JSON のままだと扱いにくいので jq コマンドでホスト名だけ取り出します。

$ mkr hosts --status standby --status maintenance --status poweroff | jq -r 'select(. != null) | .[].name'
db.test.com

このホスト名を Slack に通知します。

Incoming Webhooks を使ってメッセージを投稿する

Slack にメッセージを投稿する方法はいくつかありますが、今回は Incoming Webhooks を使います。この API は割り当てられた Webhook URL に JSON を POST するだけです。ドキュメントにもサンプルがあるように curl コマンドだけで投稿できます。

curl -X POST \
--data-urlencode 'payload={"text":"This is a line of text.\nAnd this is another one."}' \
https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

先ほどの mkr コマンドと組み合わせてシェルスクリプトを書きます。

#!/bin/bash

hosts=$(/usr/local/bin/mkr hosts --status standby --status maintenance --status poweroff | jq -r 'select(. != null) | .[].name')

if [ -n "${hosts}" ]; then
  message="working になっていないホストがあります!!\n\n"
  payload="payload={'username': 'mackerel bot', 'icon_emoji': ':ghost:', 'text': '${message}${hosts}'}"
  webhook_url='https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX'

  curl -sS -X POST --data-urlencode "${payload}" -o /dev/null "${webhook_url}"
fi

1 台でも working 以外のホストがあれば、以下のように Slack に通知されます。

Slack に投稿されたメッセージ

あまり頻繁にチェックしても狼少年になってしまうので、業務時間の始まりと終わりごろに Cron で実行させると良いでしょう。

まとめ

人間は必ずミスする(ステータスの設定を戻し忘れる)ので、あらかじめセーフティネットを張るのはインフラエンジニアの重要な仕事だと思います。

Mackerel はプログラマブルに扱える監視ツールなので、アイデア次第でいろいろと工夫できます。エンジニアがワクワクできるという点でとてもオススメです!