Azure Monitor のログアラートの対象ログを入手する

# やりたいこと

通知されたログアラートの詳細情報を取得するために、このアラートで実行されたログクエリの実行結果 (このアラートの対象ログ) を取得したいです。

ここでは、Azure Monitor アラートルールのアクションで、[[共通アラートスキーマ] を有効にし](https://learn.microsoft.com/ja-jp/azure/azure-monitor/alerts/alerts-common-schema?WT.mc_id=AZ-MVP-5003113#enable-the-common-alert-schema)、通知されるアラートの本文が「共通アラートスキーマ」の定義 ([アラートを生成した監視サービスまたはソリューション (```essentials``` 配下の ```monitoringService``` プロパティ) が「Log Alerts V2」](https://learn.microsoft.com/ja-jp/azure/azure-monitor/alerts/alerts-common-schema?WT.mc_id=AZ-MVP-5003113#sample-log-alert-when-the-monitoringservice--log-alerts-v2)) で届くことを前提としています。

https://learn.microsoft.com/ja-jp/azure/azure-monitor/alerts/alerts-common-schema?WT.mc_id=AZ-MVP-5003113


# Log Alerts V2 の場合のログアラート

```monitoringService=Log Alerts V2``` の場合のログアラートの本文には、アラートルールで実行されたログクエリの実行結果は含まれておらず、```alertContext``` 配下の ```linkToFilteredSearchResultsAPI``` プロパティ、または ```linkToSearchResultsAPI``` プロパティに掲載されている URL にアクセス (HTTP GET) することで、ログクエリの実行結果 (JSON 形式) を取得することができます。

また、GUI (Azure ポータル) で対象ログを確認したい場合は、```alertContext``` 配下の ```linkToFilteredSearchResultsUI``` プロパティ、または ```linkToSearchResultsUI``` プロパティに掲載されている URL にブラウザーでアクセスすると、ログクエリのページを開くことができます。

https://learn.microsoft.com/ja-jp/azure/azure-monitor/alerts/alerts-common-schema?WT.mc_id=AZ-MVP-5003113#sample-log-alert-when-the-monitoringservice--log-alerts-v2


# ディメンション分割

アラートルールでディメンションを使用すると、ひとつのルールで複数のリソース インスタンスを監視することができ、発報されるアラートは、ディメンションで指定したカラムの値ごとで分割 (グループ化) されます。

https://learn.microsoft.com/ja-jp/azure/azure-monitor/alerts/alerts-types?WT.mc_id=AZ-MVP-5003113#log-alerts

https://learn.microsoft.com/ja-jp/azure/azure-monitor/vm/monitor-virtual-machine-alerts?WT.mc_id=AZ-MVP-5003113#log-alert-rules


## ディメンション分割されたログアラート

たとえば、下図のような条件のログアラートルールを用意します。

[ディメンションで分割する] の [リソース ID 列] で ```_ResourceId``` を指定し、 ```Computer``` と ```RenderedDescription``` で分割します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/a729482e-4885-91a2-7102-ad8e318875ff.png)

そして、下図のようなログが収集されたとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/5a6ad2d6-c1d1-24b5-4fd3-f74b9cd0af16.png)

その結果、アラートが発報されると、ディメンション分割で指定したカラムの値ごとに分割されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/35fab3c2-da69-6356-89ae-ec16a589f35c.png)

各アラートの概要を見ると、ディメンション分割で指定したカラムの値ごとにアラートが発報されたことが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/f19437fe-fabf-0164-9047-254ad63a0ff8.png)
※クリックして、大きい画像でご覧ください。


## ログアラートの対象ログを取得

ディメンション分割されたログアラートの場合のログクエリの実行結果の取得方法は[前述のとおり](monitoringservicelog-alerts-v2-%E3%81%AE%E5%A0%B4%E5%90%88%E3%81%AE%E3%83%AD%E3%82%B0%E3%82%A2%E3%83%A9%E3%83%BC%E3%83%88)ですが、各プロパティに掲載されている URL で取得できるログクエリの実行結果が以下のように異なります。

- ```linkToFilteredSearchResultsAPI``` (```linkToFilteredSearchResultsUI```)
ディメンション分割で指定されたカラムの値で**絞り込む条件が含まれる**ログクエリの実行結果が取得できる。

- ```linkToSearchResultsAPI``` (```linkToSearchResultsUI```)
アラートルールで設定したログクエリの実行結果が取得できる。

それでは、以下で上記の違いを確認してみます。


### Azure ポータルから確認

Azure ポータルからでも、発報されたアラートの対象ログを確認することができます。

下図の「アラートの詳細」の [Filtered search results] が ```linkToFilteredSearchResultsUI``` に相当するもので、[Search results] が ```linkToSearchResultsUI``` に相当します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/12a949da-08e0-b51b-2245-2d9ea9b8eb5c.png)

それぞれの [View query results] リンクをクリックすると、それぞれのログクエリの実行結果を表示することができます。

- [Filtered search results] (```linkToFilteredSearchResultsUI```)
[Filtered search results] では、ログクエリにディメンション分割で指定されたカラムの値で絞り込む条件 (赤枠の部分) が追加されて、その実行結果を確認することができます。この実行結果は、発報されたログアラートの対象ログだと言えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/be9b4db8-1e33-53cb-492b-895ddd3e6d7b.png)

- [Search results] (```linkToSearchResultsUI```)
一方、[Search results] では、該当のアラートルールで設定したログクエリの実行結果を確認することができます。この実行結果は、発報されたログアラートの対象ログ以外のもの (赤枠の部分) も含まれてしまっているため、望んだログが得られません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/7f736193-10fe-717b-b673-9fd5551a3c71.png)

以上のことから、発報されたログアラートの対象ログは、```linkToFilteredSearchResultsAPI``` (```linkToFilteredSearchResultsUI```) から取得したほうが良いということが分かりました。


### REST API から取得

[ディメンションで分割する] の [リソース ID 列] で ```_ResourceId``` を指定すると、Azure リソースのログに対して直接クエリを実行することができます。

https://learn.microsoft.com/ja-jp/azure/azure-monitor/logs/api/azure-resource-queries?WT.mc_id=AZ-MVP-5003113

よって、発報されたアラートの本文の ```alertContext``` 配下にある ```linkToFilteredSearchResultsAPI``` および ```linkToSearchResultsAPI``` に掲載されている URL は、以下のような Azure リソースからログクエリを実行する URL となります。

```http:URL 形式
https://api.loganalytics.io/v1/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/<providerName>/<resourceType>/<resourceName>/query
```

また、返却されるレスポンスの本文は、テーブルオブジェクトの配列を含む JSON 形式の文字列が返されます。詳しくは、以下のドキュメントをご参照ください。

https://learn.microsoft.com/ja-jp/azure/azure-monitor/logs/api/response-format?WT.mc_id=AZ-MVP-5003113

Azure リソースのログに対して直接クエリを実行する URL にリクエストするには、Azure AD アクセストークンが必要です。

ここでは、[Postman](https://www.postman.com/) を使ってアクセスしてみるので、Azure AD にアプリケーションを登録します。以下のドキュメントを参考に操作します。

https://learn.microsoft.com/ja-jp/azure/azure-monitor/logs/api/overview?WT.mc_id=AZ-MVP-5003113

https://learn.microsoft.com/ja-jp/azure/azure-monitor/logs/api/register-app-for-token?WT.mc_id=AZ-MVP-5003113&tabs=portal

ログクエリの実行結果を取得するため、対象の Azure リソース (今回は仮想マシン) でアプリケーション (Postman) に対してロールを割り当てます。上記のドキュメントでは、[「閲覧者ロール」](https://learn.microsoft.com/ja-jp/azure/role-based-access-control/built-in-roles?WT.mc_id=AZ-MVP-5003113#reader)を割り当てていますが、筆者が試した際は下図のように [「Log Analytics 閲覧者ロール」](https://learn.microsoft.com/ja-jp/azure/role-based-access-control/built-in-roles?WT.mc_id=AZ-MVP-5003113#log-analytics-reader)を割り当てました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/d087abe6-374f-31a5-5051-eb29a5605f30.png)

それでは、Postman を使って、発報されたアラートの対象ログを取得してみます。

まず、以下のドキュメントを参考に Azure AD アクセストークンを取得して、リクエストヘッダーに取得したアクセストークンをセットします。

https://learn.microsoft.com/ja-jp/azure/azure-monitor/logs/api/access-api?WT.mc_id=AZ-MVP-5003113#request-an-authorization-token

そして、Postman で実行結果は下図のとおりです。これで、発報されたアラートの対象ログを取得することができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/a7337654-da34-33dc-fae2-ea5dbeac7a6f.png)
※レスポンス本文を JSON 形式で表示するとすべての内容がキャプチャに収まらなかったので、Text 形式に切り替えています。

なお、ここでは Azure AD にアプリケーションを登録して、そのアプリケーションにロールを割り当ててやってみましたが、マネージド ID を用いても同じように発報されたアラートの対象ログを取得することができます。

[次回につづく](https://qiita.com/tetsuya-ooooo/items/9a7c81ede7e1c5288741)。