次の方法で共有


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

この記事では、次の方法を含む、Azure Monitor ログでのログ クエリの記述の基礎について説明します:

該当する場合、この記事では、Kusto 照会言語 (KQL) と Log Analytics 簡易モードの両方を使用してデータのクエリを実行する例を示します。

Note

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

チュートリアル ビデオ

Note

このビデオでは、以前のバージョンのユーザー インターフェイスを示していますが、この記事全体のスクリーンショットは最新であり、現在の UI を反映しています。


必要なアクセス許可

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

クエリの構成

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

注意

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

テーブルベースのクエリ

Azure Monitor では、ログ データはテーブルに編成され、各テーブルは複数の列で構成されます。 Azure portal では、すべてのテーブルと列は Log Analytics のスキーマ ウィンドウに表示されます。

目的のテーブルを指定し、データの一部を見てみましょう:

SecurityEvent
| take 10

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

  • クエリは、クエリの範囲を定義するテーブル名 SecurityEvent で始まります。
  • パイプ (|) 文字で複数のコマンドを区切ると、最初のコマンドの出力が次の入力になります。 パイプでつないだ要素は、任意の数を追加できます。
  • パイプの後に take 演算子が続きます。 | take 10 を追加せずにクエリを実際に実行することもできます。 このコマンドは引き続き有効ですが、最大で 30,000 件の結果を返す可能性があります。

検索クエリ

検索クエリは、あまり構造化されていません。 特定のテーブルのいずれかの列に特定の値を含むレコードを検索するのに最適です。

このクエリで、SecurityEvent テーブルの "Cryptographic" というフレーズが含まれるレコードが検索されます。それらのレコードの中から、10 個のレコードが返され、表示されます:

search in (SecurityEvent) "Cryptographic"
| take 10

in (SecurityEvent) 部分を省略して search "Cryptographic" のみを実行すると、検索で "すべての"テーブルが調べられます。 そのため、プロセスにかかる時間が長くなり、効率が低下します。

重要

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

結果の制限

take 演算子を使用して、指定された数のレコードを返すことで、レコードの小さなサンプルを表示します。 次に例を示します。

SecurityEvent
| take 10

選択された結果は任意となり、特定の順序で表示されません。 特定の順序で結果を返す必要がある場合は、sort および top 演算子を使用します。

結果の並べ替え

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

並べ替え

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

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

SecurityEvent	
| sort by TimeGenerated

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

desc と asc

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

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

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

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

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

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

SecurityEvent
| top 10 by TimeGenerated

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

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

結果のフィルター処理

フィルター処理は、クエリ結果を関連する情報に制限する最も一般的な方法です。

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

SecurityEvent
| where Level == 8

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

説明
== 等価性をチェックします
(大文字と小文字を区別します)
Level == 8
=~ 等価性をチェックします
(大文字と小文字は区別されません)
EventSourceName =~ "microsoft-windows-security-auditing"
!=, <> 非等価性をチェックします
(両方の式は同じです)
Level != 4
and, or 条件の間に必要です 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 などの数値型にキャストする必要があります。


時間の範囲を指定する

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

Note

クエリに時間の範囲を含める場合、時間ピッカーはクエリで設定に自動的に変更されます。 時間ピッカーを手動で別の値に変更した場合、Log Analytics では 2 つの時間範囲のうち小さい方が適用されます。

日時ピッカーを使用する

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

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

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

また、時間フィルターをクエリに追加して、独自の時間の範囲を定義することもできます。

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

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

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

クエリ結果に列を含めるまたは除外

結果に含める特定の列を選択するには、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)

Note

クエリのアドホック計算には、extend 演算子を使用します。 インジェスト時刻の変換または 集計ルールを使用して、インジェスト時にデータを変換または集計して、より効率的なクエリを実行します。

結果の集計とグループ化

行のグループを集計する

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 == "DC01.na.contosohotels.com" 
| where CounterName == "Available MBytes" 
| summarize avg(CounterValue) by bin(TimeGenerated, 1h)

出力をよりわかりやすくするために、時系列で使用可能なメモリを示す時間グラフとして表示することを選択できます。 これを行うには、[グラフ] ビューに切り替え、右側の [グラフのフォーマット] サイドバーを開き、[グラフの種類][折れ線] を選択します:

KQL モードでの時間の経過に伴うクエリ メモリの値を示すスクリーンショット。

よく寄せられる質問

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

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

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

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

次のステップ