こんにちは。クラウド製品を担当している金沢です。
Azure Monitorを使用する際にLog Analyticsワークスペースに存在しているデータを拾うときは、KQLクエリで該当データを拾って通知するというやり方を行います。このときにLog Analyticsワークスペースからデータを拾ってくるやり方で少し手こずったので、備忘録代わりに残しておこうと思います。
結論から申し上げますと、診断設定とKQLクエリの2つを使いこなすことが肝要です。
1.診断設定・DCRを確認する
Log Analyticsワークスペースにデータを送信するには、事前に診断設定もしくはDCRを設定する必要があります。
以下をご参照ください。
learn.microsoft.com
どこで設定するかによってLog Analyticsワークスペースのデータ検索時にもっとも基礎となるテーブルをどれにするかが変わってきます。
テーブルとは、Log Analyticsワークスペースでデータが格納されている大きな枠組みです。
テーブル>LogManagementにてワークスペースに存在するテーブルの一覧が見られます。

診断設定
Azure アクティビティログ
Azure サービスにてイベントに関するログがサブスクリプション レベルで格納されます。
対応リソース>アクティビティログ>「診断設定」から設定が可能です。

Log Analyticsワークスペースでは「AzureActivity」テーブルが対応します。
AzureActivity
で出力できます。
【サービス置き換え予定】プラットフォームのメトリック
Azureリソース内で展開されているリソースのメトリックに関するログが格納されます。
対象Log Analyticsワークスペース>「診断設定」から設定が可能です。

メトリックとは、Microsoft Learnにて以下のように定義されています。
Azure Monitor メトリックは、監視対象のリソースから時系列データベースに数値データを収集する Azure Monitor の機能です。 メトリックは、一定の間隔で収集される数値であり、特定の時刻におけるシステムの何らかの特性を表しています。
以下リンクより引用
learn.microsoft.com
このあたりのメトリックとはなにか、またアクティビティログとメトリックとの違いに関してはAzure認定試験でもよく見た項目のような気がします。
CPU使用率など、時間によって一定さが決まるものを確認する場合はこちらを確認します。
Log Analyticsワークスペースでは「AzureMetrics」テーブルが対応します。
クエリは
AzureMetrics
です。
2025年8月25日現在、後述するDCRに置き換えるサービスの一環にこの「プラットフォームのメトリック」が存在します。
レガシーとなるサービスは以下です。
| レガシメソッド | DCRメソッド |
|---|---|
| Log Analyticsエージェント | Azure Monitorエージェント |
| 診断設定(メトリックのみ) | メトリックのエクスポート |
| データ コレクター API | ログ インジェスト API |
現状、DCRでも上記でもこちらでも機能は問題なく使えており、完全に移行した、という感覚はありません。しかしここで示したメトリックに関する診断設定もいずれ使えなくなる日が来るのかもしれません。
以下サイトより引用しています。
learn.microsoft.com
Azure リソースログ
ある特定の機能にて設定できる、リソース内部操作に関連するためのログのことです。
AzureDiagnostics テーブル、もしくはリソース固有のテーブルが作られます。
たとえば、ストレージアカウントサービスのBlobスキーマはこれに対応しています。
以下のように診断設定を作ると、LogAnalyticsワークスペースに専用のテーブルが出現します。


サービスが限定されるほか、Azure Diagnosticsエージェントが必要となるものもあります。Azure Diagnosticsエージェントはサポートが近いうちに終了いたしますので、対応するかどうかは以下のMicrosoft Learnをご参照ください。

Data Collection Rule(データ収集ルール)

診断設定とよく似た機能です。モニター>データ収集ルールで設定可能です。
上記で述べた「診断設定」とは違い、外部的なリソースに関するログではなく、より内部的なデータが格納されます。Log Analyticsワークスペースで閲覧する際のクエリは、
Event
です。
下記はDCRにて送信されたLog Analyticsワークスペース内のデータのひとつです。

たとえば「Azure Policyに違反している」「Azure Update Managerで指示されたアップデートが行われた」などのように、Azureリソースに関連したものではなく、その内部のサービスや設定に関してのログです。それゆえに送られるものとしてはVMに関する内容が主となります。
以下をご参照ください。
learn.microsoft.com
2.クエリの書き方
目的に応じたデータ送信設定ルールが作成できました。Log Analyticsワークスペースからデータを拾いに行きます。
対象Log Analyticsワークスペース>ログにて、クエリを開くことができます。

KQLの設定の前に、Log Analyticsワークスペースに記録されているログがどういった形で記録されているかを見てみます。以下は、「AzureActivity」テーブルにて保存されているデータの一部のキャプチャです。

Log Analyticsワークスペースには、上記のように各テーブルに対して項目名が設定され、中にそれぞれデータが入っています。これらを目的に合わせて指定、もしくはKQLクエリにて操作することで、データの取り出しを行います。
実際にKQLを使用しクエリを作成する際には、以下のリンクを参照し、KQL文法を理解しながら文章を作成します。
learn.microsoft.com
3.実際に動かしてみる
実際に例を設定してみます。
今回の設定の題材としては「保留中の再起動がある Windows VM の監査」というポリシーに対し非準拠が生まれている場合のアラート通知に関する文章を作ります。
実際にLog Analyticsワークスペースに蓄積されるデータをどう指定するのかのご参考にしていただければと思います。
3-1.診断設定をつける
まずは、どの診断設定をつけるかを判断します。
各ポリシーにはそれぞれ効果があり、これはエラーログが発生する条件のようなものです。たとえば「保留中の再起動がある Windows VM の監査」というポリシーには「auditIfNotExists」効果があり、これらをMicrosoft Learnで引くと以下のようになります。
auditIfNotExists は、リソース プロバイダーがリソースの作成または更新要求を処理し、成功状態コードを返した後に実行されます。 (中略) 新しいリソースと更新されたリソースの場合、Azure Policy はアクティビティ ログに Microsoft.Authorization/policies/audit/action 操作を追加し、リソースを非準拠としてマークします。 トリガーされると、 if 条件を満たすリソースは、非準拠としてマークされているリソースです。
以下参考資料
learn.microsoft.com
リソースを基準とした動きを記録するため、アクティビティログに記録されます。したがって、今回はアクティビティログから診断設定を作る必要があります。

診断設定の詳細は上記のように設定しました。
policy以外に設定することも可能ですが、蓄積が起きるたびに課金が発生する従量課金制のため、必要なデータのみに絞ることをおすすめします。
3-2.クエリをつくってみる
続いてLog Analyticsワークスペースにきちんとログが蓄積されていることを確認し、要件通りのデータが取得できるかを確認します。
まずはAzure Policyのコンプライアンス結果全体が届いているかを確認します。
以下のクエリを実行してみます。
//テーブルを指定 AzureActivity //「カテゴリ」の値が「Policy」であるものを指定 | where CategoryValue == "Policy"
実行結果は以下です。

指定通り「ログカテゴリ」ヘッダーの値に「Policy」が入っているものが蓄積されていることがわかります。クエリを作成する際のひな形は
{テーブル名}
| (演算子)<条件式>
です。テーブル名や条件を明確にし、条件を絞り込みます。
では本番です。全体のログから、指定したポリシーに関するログのみを選んで抽出してみます。
以下は2025/8/21から2025/8/22の間に発生したアクティビティログです。
いくつか「Audit Action」に関するログが発生しています。

赤い四角で囲んだ時間のみをクエリで抽出し、これがLog Analyticsワークスペースに蓄積されているかを確認してみます。
検索条件を以下に決め、クエリを作成します。
- 設定したポリシーのもの →#1
- 状態が「成功」のもの →#2
- 実行が2025/8/21から2025/8/22のもの →#3
- ポリシー効果が「auditIfNotExists」のもの →#4
結果は以下のようになりました。
※サブスクリプションIDとリソースグループ名が含まれている箇所があったため、マスクをかけている場所があります。

日付、出力数、出力内容が前画像にて赤く四角く囲んだ部分と一致しています。また、内容で絞ったことで日付に依存しなくてもデータ数が絞れています。
以下は出力に使用したスクリプトです。
// テーブル名を指定 AzureActivity // カテゴリの値(Value)が「Policy」であるものを指定 | where CategoryValue == "Policy" // Propetiesヘッダー内に指定のポリシー割り当てIDがあるものを指定 →#1 | where Properties contains {ポリシーの割り当てID} // アクティビティの状態が「成功」であるものを指定 →#2 | where ActivityStatusValue == "Success" // 時間範囲を2025/8/21から2025/8/22の間に指定 →#3 | where TimeGenerated >= datetime(2025-08-21) and TimeGenerated < datetime(2025-08-22) // 「Properties」フィールド内の値をJSON配列として解析し、「props」として追加 →#4 | extend props = parse_json(Properties) // 「props」フィールド内にある「policies」データを文字列変換したうえでJSONファイルとして解析、「policiesArray」として追加 →#4 | extend policiesArray = parse_json(tostring(props.policies)) // 「policiesArray」各要素を「policy」フィールドとして展開 →#4 | mv-expand policy = policiesArray //「policy」フィールド内の「policyDefinitionEffect」カラムの内容が「auditIfNotExists」なものを指定 →#4 | where policy.policyDefinitionEffect contains "auditIfNotExists"
条件と文章がひとつひとつ対応していることがわかります。
データの形によっては#4のように形を変換してデータを探しに行く必要があります。
たとえば今回、「Properties」フィールドのデータの内部は以下のようになっています。
※個人情報等につながる部分にマスクをかけている場所があります。

これを一部文字に起こし、簡易化すると以下のようになります。
Properties: { "isComplianceCheck":"False", "resourceLocation":"japaneast", ~~(中略)~~ "policies":[ {"policyDefinitionId":"{ポリシーの定義ID}", "policyAssignmentId":"{ポリシーの割り当てID}", ~~(以下略)~~ } ] }
Log Analyticsワークスペースでは、ログはJSON形式で保存され、それぞれカラム名:データの形で格納されます。そのため、ものによってはデータ自体もJSON形式の配列型で保存されます。たとえば今例で言うと「policies」が当てはまります。
クエリの条件式では基本的には文字列を参照します。データの中身がJSON形式の配列となっている場合、「条件に合致しない」と判断されてしまいます。toString関数やparse_json関数など、文字列の変換や解析形式を指定する関数を使用し、クエリの基本型に合わせて条件式を作成するのがコツです。
このように、クエリを利用したデータ取得は「どこから設定するのか」「何のデータが必要か」を事前に決めたうえで設定を行い、また格納されているデータを確認しながら少しずつ行っていきます。データ型の取得・把握も大切です。
どんな形でデータが格納されているかの確認方法は、Log Analyticsワークスペースで実際にクエリを実行してみることが一番早いと思います。
まずは、
AzureActivity
| where ResourceGroup contains "{リソースグループ名}"
など、確実にわかっている要件を用いて絞り込み、データの全体的な形を見てみることをおすすめします。
終わりに
Log Analyticsワークスペースからデータを取得する際に必要となる機能、またクエリの書き方について書かせていただきました。JSON形式など、慣れていない方からしたら二の足を踏みがちなステップですが、落ち着いて少しずつ試しながら書けば難しくありません。
拙い記事ではありますが、同じことに悩まれていた方の支えとなりましたら幸いです。