Azure Log AnalyticsアラートをSlackに通知する

Azure Kubernetes Serviceで、Runningステータス以外のコンテナが存在したらSlackにアラート通知するということを実現したく、色々模索しました。
Azure MonitorのメトリクスをSlack通知するときはLogic Appsを使うのが多いと思いますが、Log AnalyticsアラートはLogic Appsだとうまく実現できなかったため、Webhookのカスタムペイロードで対応しました。

# Log Analyticsログ検索
* Log Analyticsワークスペースを開いて、アラート条件となるクエリを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/26cc1449-1272-37f5-1fb6-1e06369011fc.png)

* 今回はAKSでRunning以外のコンテナが存在したらという条件なので、以下のように設定しました。全てRunningステータスならクエリ結果は0件になります。

```
let endDateTime = now();
    let startDateTime = ago(15m);
    let trendBinSize = 1m;
    let clusterName = '[Your AKS Cluster Name]';
    KubePodInventory
    | where TimeGenerated < endDateTime
    | where TimeGenerated >= startDateTime
    | where ClusterName == clusterName
    | distinct ClusterName, TimeGenerated
    | summarize ClusterSnapshotCount = count() by bin(TimeGenerated, trendBinSize), ClusterName
    | join hint.strategy=broadcast (
        KubePodInventory
        | where TimeGenerated < endDateTime
        | where TimeGenerated >= startDateTime
        | distinct ClusterName, Computer, PodUid, TimeGenerated, PodStatus
        | summarize TotalCount = count(),
                    PendingCount = sumif(1, PodStatus =~ 'Pending'),
                    RunningCount = sumif(1, PodStatus =~ 'Running'),
                    SucceededCount = sumif(1, PodStatus =~ 'Succeeded'),
                    FailedCount = sumif(1, PodStatus =~ 'Failed')
                 by ClusterName, bin(TimeGenerated, trendBinSize)
    ) on ClusterName, TimeGenerated
    | extend UnknownCount = TotalCount - PendingCount - RunningCount - SucceededCount - FailedCount
    | project TimeGenerated,
              TotalCount = todouble(TotalCount) / ClusterSnapshotCount,
              PendingCount = todouble(PendingCount) / ClusterSnapshotCount,
              RunningCount = todouble(RunningCount) / ClusterSnapshotCount,
              SucceededCount = todouble(SucceededCount) / ClusterSnapshotCount,
              FailedCount = todouble(FailedCount) / ClusterSnapshotCount,
              UnknownCount = todouble(UnknownCount) / ClusterSnapshotCount
| summarize AggregatedValue = avg(PendingCount) + avg(FailedCount) + avg(UnknownCount) by bin(TimeGenerated, trendBinSize)
| where AggregatedValue > 0
```

* 公式ページにAKSを監視したいときのサンプルクエリが載ってますのでそれを参考にしました。

[コンテナー用 Azure Monitor でパフォーマンスの問題に関するアラートを設定する方法](https://docs.microsoft.com/ja-jp/azure/azure-monitor/insights/container-insights-alerts)

* クエリを実行したら[新しいアラートルール]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/a956d5c1-7213-3800-0078-a8e418b795fe.png)

# アラートルール作成
* 条件を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/2bd3f9da-10dd-18dc-a528-584e9a1ad795.png)

* しきい値を以下のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/2d1b112f-a8a4-7acc-37a3-a8236ca024fb.png)

* 要件に合わせて評価基準を設定します。今回は10分単位に、15分前の期間まで遡ってチェックする設定にしてます。頻度次第で月額料金が変わるので注意です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/7eb09203-1abe-adcc-380a-a4714f620ac7.png)

* 続いてアクショングループを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/5eb63b37-9061-6b6e-5311-e5c688c2ddbd.png)

* アクショングループ名と短い名前を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/f7cb7854-d2e1-f2c1-fdc4-0bda0d62c9fc.png)

* アクション名を入力し、アクションタイプに[Webhook]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/f180098d-3b65-0c80-5987-a73818f2d5bf.png)

* URIにSlack Incomming WebhookのURIを入力します。Incomming WebhookはSlackから取得してください。Slackの手順は割愛します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/3fe2ade1-3588-943a-00d3-bfe79806a909.png)

* [webhook用のカスタムJsonペイロードを含む]にチェックを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/9dcf2fcb-d021-0181-5a6a-b14d65183657.png)

* カスタムJSONペイロードにSlack API Attachementの記法に従って入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/69fde415-7c3b-51aa-ebba-17162699aaf5.png)

* 例として以下のように設定できます。

```
{
    "attachments": [
        {
            "fields": [
                {
                    "title": "Alert Rule Name",
                    "value": "#alertrulename"
                },
                {
                    "title": "重大度",
                    "value": "#severity"
                },
                {
                    "title": "詳細メッセージ",
                    "value": "Failed、Pending、Unknownステータスのコンテナが存在しています"
                }
            ],
            "color": "danger"
        }
    ],
    "username": "Test Alert User",
    "icon_emoji": ":ghost:",
    "channel":"#general"
}
```

* "#alertrulename" などのLog Analytics独自のパラメータは以下を参考ください。
[ログ アラート ルールの webhook アクション](https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/alerts-log-webhook)

* 次にアラートルール名を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/94f7b40b-eed3-6597-4c9b-5bcdf8e6280d.png)

* 必要に応じて[アラートを表示しない期間]を入れておきます。これを付けると、時間内に同じアラートルールで検知した場合アラートを出さなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/96a53a1f-cd33-1d33-bd0f-e685fab77d08.png)

# Slack通知結果
* アラートルールを満たすと、こんな感じで通知されます。カスタムペイロードを変更することで自由にカスタマイズ可能です。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/4d3c91e0-eb83-71bb-a435-2cfc6b021fd8.png)