Azure Monitor でログ クエリの使用を開始する

Note

少なくとも 1 つの仮想マシンからデータを収集する場合は、独自の環境でこの演習を行うことができます。 その他のシナリオでは、サンプル データが多数含まれている Microsoft のデモ環境を使用してください。

Kusto 照会言語 (KQL) でクエリを実行する方法は既にわかっているが、リソースの種類に基づいて便利なクエリをすばやく作成する必要がある場合は「Azure Monitor Log Analytics でのクエリの使用」の保存済みサンプル クエリ ペインを参照してください。

このチュートリアルでは、Azure Monitor でログ クエリを記述する方法について説明します。 この記事では、次の方法について説明します。

  • クエリの構造の概要。
  • クエリ結果の並べ替え。
  • クエリ結果のフィルター処理。
  • 時間の範囲の指定。
  • 結果に含めるフィールドの選択。
  • カスタム フィールドの定義と使用。
  • 結果の集計とグループ化。

Azure portal での Log Analytics の使用に関するチュートリアルについては、Azure Monitor Log Analytics の使用開始に関するページを参照してください。

Azure Monitor でのログ クエリの詳細については、Azure Monitor でのログ クエリの概要に関するページをご覧ください。

このチュートリアルの動画バージョンをご覧ください。

必要なアクセス許可

クエリを実行する Log Analytics ワークスペースに対し、Microsoft.OperationalInsights/workspaces/query/*/read アクセス許可が必要です。これは、たとえば、Log Analytics 閲覧者組み込みロールによって提供されます。

新しいクエリを作成する

クエリは、テーブル名または search コマンドから始めることができます。 テーブル名で始めることをお勧めします。クエリの範囲が明確に定義されるためです。 クエリのパフォーマンスと結果の関連性も向上します。

注意

Azure Monitor で使用される KQL では、大文字と小文字が区別されます。 通常、言語のキーワードは小文字で記述されます。 クエリ内でテーブルまたは列の名前を使用する場合は、スキーマ ペインの表示に従って、必ず大文字と小文字を正しく指定してください。

テーブルベースのクエリ

Azure Monitor では、ログ データはテーブルに編成され、各テーブルは複数の列で構成されます。 Analytics ポータルでは、すべてのテーブルと列は Log Analytics のスキーマ ウィンドウに表示されます。 目的のテーブルを指定し、データの一部を見てみましょう。

SecurityEvent
| take 10

上記のクエリは、順不同で SecurityEvent テーブルから 10 件の結果を返します。 これは、テーブルの概要を把握し、その構造と内容を理解するための一般的な方法です。 それでは、どのように構築されているかを見てみましょう。

  • クエリは、クエリの範囲を定義するテーブル名 SecurityEvent で始まります。

  • パイプ (|) 文字で複数のコマンドを区切ると、最初のコマンドの出力が次の入力になります。 パイプでつないだ要素は、任意の数を追加できます。

  • パイプの後に take 演算子が続きます。

    | take 10 を追加せずにクエリを実際に実行することもできます。 このコマンドは引き続き有効ですが、最大で 30,000 件の結果を返す可能性があります。

Take

take 演算子を使用して、指定された数のレコードを返すことで、レコードの小さなサンプルを表示します。 選択された結果は任意となり、特定の順序で表示されません。 特定の順序で結果を返す必要がある場合は、sort および top 演算子を使用します。

検索クエリ

検索クエリは、あまり構造化されていません。 これらは一般的に、任意の列に特定の値が含まれるレコードを検索するのに適しています。

search in (SecurityEvent) "Cryptographic"
| take 10

このクエリは、"Cryptographic" という語句を含むレコードを SecurityEvent テーブルで検索します。これらのレコードのうち、10 個のレコードが返されて表示されます。 in (SecurityEvent) 部分を省略して search "Cryptographic" のみを実行すると、検索で "すべての"テーブルが調べられます。 そのため、プロセスにかかる時間が長くなり、効率が低下します。

重要

検索クエリは通常、処理する必要のあるデータが増えるため、テーブル ベースのクエリより低速です。

sort と top

このセクションでは、sort および top 演算子と、それらの desc および asc 引数について説明します。 take は少数のレコードを取得するのに便利ですが、結果を特定の順序で選択または並べ替えることはできません。 順序付けされたビューを取得するには、sorttop を使用します。

desc と asc

説明

レコードを降順で並べ替えるには、desc 引数を使用します。 降順は sort および top の既定の並べ替え順序であるため、通常は desc 引数を省略できます。

たとえば、次の両方のクエリによって返されるデータは、TimeGenerated 列で降順に並べ替えられます。

  • SecurityEvent	
    | sort by TimeGenerated desc
    
  • SecurityEvent	
    | sort by TimeGenerated
    

Asc

昇順で並べ替えるには、asc を指定します。

並べ替え

sort 演算子を使用できます。 sort は、指定した列でクエリ結果を並べ替えます。 ただし、sort ではクエリによって返されるレコードの数は制限されません。

たとえば、次のクエリは、最大 30,000 レコードまでの SecurityEvent テーブルのすべての使用可能なレコードを返し、TimeGenerated 列で並べ替えます。

SecurityEvent	
| sort by TimeGenerated

上記のクエリでは、返される結果が多すぎる可能性があります。 また、結果が返されるまでに時間がかかることもあります。 このクエリでは、SecurityEvent テーブル全体が TimeGenerated 列で並べ替えられます。 また、Analytics ポータルでは、表示が 30,000 レコードに制限されます。 この方法は最適ではありません。 最新のレコードのみを取得する最適な方法は、top 演算子を使用することです。

top 演算子を使用して、サーバー側でテーブル全体を並べ替えてから、上位のレコードのみを返します。

たとえば、次のクエリは最新の 10 件のレコードを返します。

SecurityEvent
| top 10 by TimeGenerated

出力は次の例のようになります。

降順に並べ替えられた 上位 10 件のレコードを示すスクリーンショット。

where 演算子: 条件に基づいたフィルター処理

フィルターは、その名前のとおり、特定の条件に基づいてデータをフィルター処理します。 フィルター処理は、クエリ結果を関連する情報に制限する最も一般的な方法です。

クエリにフィルターを追加するには、where 演算子に続けて 1 つ以上の条件を使用します。 たとえば、次のクエリでは SecurityEvent である Level equals _8 レコードのみが返されます。

SecurityEvent
| where Level == 8

フィルター条件を記述する場合は、次の式を使用できます。

説明
== 等価性をチェックします
(大文字と小文字を区別します)
Level == 8
=~ 等価性をチェックします
(大文字と小文字は区別されません)
EventSourceName =~ "microsoft-windows-security-auditing"
!=、<> 非等価性をチェックします
(両方の式は同じです)
Level != 4
andor 条件の間に必要です Level == 16 or CommandLine != ""

複数の条件でフィルター処理するには、次のいずれかの方法を使用できます。

次に示すように、and を使用します。

SecurityEvent
| where Level == 8 and EventID == 4672

次に示すように、複数の where 要素を順番にパイプでつなぎます。

SecurityEvent
| where Level == 8 
| where EventID == 4672

Note

値の型は異なる可能性があるため、正しい型に基づいて比較を実行するために型をキャストする必要がある場合があります。 たとえば、SecurityEvent Level 列は文字列型であるため、数値演算子を使用するには、SecurityEvent | where toint(Level) >= 10 のように intlong などの数値型にキャストする必要があります。

時間の範囲を指定する

時間の範囲は、時刻の選択または時間フィルターを使用して指定できます。

日時ピッカーを使用する

時刻の選択は [実行] ボタンの横に表示され、過去 24 時間のレコードのみのクエリを実行していることを示しています。 この既定の時間範囲が、すべてのクエリに適用されます。 過去 1 時間のレコードのみを取得するには、[過去 1 時間] を選択してから、クエリを再度実行します。

時刻の選択とその時間範囲コマンドの一覧を示すスクリーンショット。

クエリに時間フィルターを追加する

また、時間フィルターをクエリに追加して、独自の時間の範囲を定義することもできます。 時間フィルターを追加すると、時刻の選択で選択した時間の範囲がオーバーライドされます。

テーブル名の直後に時間フィルターを配置することをお勧めします。

SecurityEvent
| where TimeGenerated > ago(30m) 
| where toint(Level) >= 10

上記の時間フィルターでは、ago(30m) は "30 分前" を意味します。このクエリは過去 30 分間 (30m のように表記) のレコードのみを返します。 その他の時間単位には、日 (2d など) や秒 (10s など) があります。

project と extend を使用して列を選択および計算する

結果に含める特定の列を選択するには、project を使用します。

SecurityEvent 
| top 10 by TimeGenerated 
| project TimeGenerated, Computer, Activity

上記の例では、次の出力が生成されます。

クエリの

また、project を使用して列の名前を変更し、新しい列を定義することもできます。 次の例では、project を使用して以下を実行します。

  • 元の列の Computer および TimeGenerated のみを選択します。
  • EventDetails として Activity 列を表示します。
  • EventCode という名前の新しい列を作成します。 Activity フィールドの先頭の 4 文字のみを取得するために、substring() 関数が使用されます。
SecurityEvent
| top 10 by TimeGenerated 
| project Computer, TimeGenerated, EventDetails=Activity, EventCode=substring(Activity, 0, 4)

extend を使用すると、元の列をすべて結果セットに保持し、追加のものを定義できます。 次のクエリでは、extend を使用して、EventCode 列が追加されています。 この列は、テーブルの結果の最後に表示されない場合があります。 これを表示するには、レコードの詳細を展開する必要があります。

SecurityEvent
| top 10 by TimeGenerated
| extend EventCode=substring(Activity, 0, 4)

summarize を使用して行のグループを集計する

summarize を使用して、1 つ以上の列に従ってレコードのグループを特定し、それらに集計を適用します。 summarize の最も一般的な用途は、各グループの結果の数を返す count です。

次のクエリでは、過去 1 時間のすべての Perf レコードを確認し、ObjectName でグループ化し、各グループのレコードをカウントします。

Perf
| where TimeGenerated > ago(1h)
| summarize count() by ObjectName

複数の次元でグループを定義することが理にかなっている場合があります。 これらの値の一意の組み合わせで、それぞれ別のグループが定義されます。

Perf
| where TimeGenerated > ago(1h)
| summarize count() by ObjectName, CounterName

もう 1 つの一般的な用途は、各グループに対して数学的または統計的計算を実行する場合です。 次の例では、各コンピューターの平均 CounterValue を計算します。

Perf
| where TimeGenerated > ago(1h)
| summarize avg(CounterValue) by Computer

残念ながら、異なるパフォーマンス カウンターを混在させたため、このクエリの結果は意味がありません。 より意味のある結果にするために、CounterNameComputer の組み合わせごとに個別に平均を計算します。

Perf
| where TimeGenerated > ago(1h)
| summarize avg(CounterValue) by Computer, CounterName

時間列で要約する

結果のグループ化は、時間列または別の連続する値に基づいて行うこともできます。 ただし、これらの値は一意であるため、by TimeGenerated を要約するだけでは、時間の範囲全体に 1 ミリ秒ごとのグループが作成されます。

連続する値に基づいてグループを作成するには、bin を使用して範囲を管理しやすい単位に分割することをお勧めします。 次のクエリでは、特定のコンピューター上の空きメモリ ( Available MBytes ) を測定する Perf レコードを分析します。 過去 7 日間の 1 時間ごとの平均値が計算されます。

Perf 
| where TimeGenerated > ago(7d)
| where Computer == "ContosoAzADDS2" 
| where CounterName == "Available MBytes" 
| summarize avg(CounterValue) by bin(TimeGenerated, 1h)

出力をよりわかりやすくするために、時系列で使用可能なメモリを示す時間グラフとして表示することを選択できます。

時系列でクエリ メモリの値を示すスクリーンショット。

よく寄せられる質問

このセクションでは、一般的な質問への回答を示します。

Azure Monitor ログに重複するレコードが表示されるのはなぜですか?

場合によっては、Azure Monitor ログに重複するレコードが表示されることがあります。 通常、この重複は次の 2 つの条件のいずれかが原因です。

  • パイプライン内のコンポーネントは、配信先に確実に配信されるように再試行を行います。 場合によっては、この機能が原因で、わずかながらテレメトリ項目が重複する可能性があります。
  • 重複するレコードが仮想マシンから配信される場合、Log Analytics エージェントと Azure Monitor エージェントの両方がインストールされている可能性があります。 今後も Log Analytics エージェントをインストールしておく必要がある場合は、Azure Monitor エージェントが使用しているデータ収集ルールによって収集されるデータが今後は収集されないように、Log Analytics ワークスペースを構成します。

次のステップ