しばやん雑記

ASP.NET とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure のアラートを Azure Functions を使って Slack に投げる

Azure のアラートは前から Webhook での通知に対応しているので、Logic Apps や Flow などで受け取ってあげれば、Slack に簡単に通知できます。

単純な通知なら問題ないですが、Slack のもうちょっとリッチな通知を使いたいので、Azure Functions を使って整形してから Slack に通知するようにします。

素晴らしいことに Azure のアラートはペイロードの JSON が統一されているので、単一の Function を用意するといろんな部分で使いまわせます。ペイロードはドキュメントにまとまってます。

オートスケールの場合にも Webhook で通知できるので、設定しておくと便利でした。

説明するよりコードを出した方が早いので、Function の実装を出しておきます。単純に Webhook を受け取って、Slack 向けに整形しているだけです。オートスケール向けに特殊対応はしています。

#r "Newtonsoft.Json"

using System;
using System.Net;
using System.Net.Http;

using Newtonsoft.Json;

const string SlackEndpoint = "https://hooks.slack.com/services/xxxx";

static HttpClient httpClient = new HttpClient();

public static async Task<object> Run(HttpRequestMessage req, TraceWriter log)
{
    log.Info($"Webhook was triggered!");

    string jsonContent = await req.Content.ReadAsStringAsync();
    dynamic data = JsonConvert.DeserializeObject(jsonContent);

    if (data.status == null || data.context == null)
    {
        return req.CreateResponse(HttpStatusCode.BadRequest);
    }

    var payload = new
    {
        attachments = new []
        {
            new
            {
                pretext = $"{data.context.name} is {data.status}",
                color = (data.operation == "Scale In" || data.operation == "Scale Out") ? "#439FE0" : (data.status == "Activated" ? "danger" : "good"),
                title = data.context.resourceName,
                title_link = data.context.portalLink,
                text = data.context.description ?? data.context.details
            }
        }
    };

    var jsonString = JsonConvert.SerializeObject(payload);

    await httpClient.PostAsync(SlackEndpoint, new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("payload", jsonString)
    }));

    return req.CreateResponse(HttpStatusCode.OK);
}

オートスケールの時なのか判別するために、operation の値をチェックしています。ポータルのリンクも設定するので、アラートが飛んできたときにリンクをクリックすると、該当するリソースに飛べて便利です。

アラートには Description を設定できるので、そこに日本語で説明を入れることで分かりやすくします。通知には Description を含めてあります。

f:id:shiba-yan:20170606232922p:plain

設定後に負荷を掛けてアラートを飛ばしてみると、以下のような通知が Slack に飛んできます。

f:id:shiba-yan:20170606232805p:plain

アラートがアクティブになると赤で、解決すると緑で表示するので一目でわかるようになってます。Description を書いておくと、何のアラートなのか分かりやすいです。

オートスケールの場合は Description を設定できないので、代わりに details を通知に含めています。

f:id:shiba-yan:20170606220635p:plain

インスタンスの増減が Slack で確認できるようになりました。

全く関係ないですが、App Service on Linux でも App Service Plan に対してはアラートを設定できるようになってるみたいです。GA までには Web App に対してのメトリックが欲しいですね。