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
は少数のレコードを取得するのに便利ですが、結果を特定の順序で選択または並べ替えることはできません。 順序付けされたビューを取得するには、sort
と top
を使用します。
並べ替え
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
出力は次のようになります。
結果のフィルター処理
フィルター処理は、クエリ結果を関連する情報に制限する最も一般的な方法です。
クエリにフィルターを追加するには、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
のように int
や long
などの数値型にキャストする必要があります。
時間の範囲を指定する
時間の範囲は、時刻の選択または時間フィルターを使用して指定できます。
Note
クエリに時間の範囲を含める場合、時間ピッカーはクエリで設定に自動的に変更されます。 時間ピッカーを手動で別の値に変更した場合、Log Analytics では 2 つの時間範囲のうち小さい方が適用されます。
日時ピッカーを使用する
時刻の選択は [実行] ボタンの横に表示され、過去 24 時間のレコードのみのクエリを実行していることを示しています。 この既定の時間範囲が、すべてのクエリに適用されます。 過去 1 時間のレコードのみを取得するには、[過去 1 時間] を選択してから、クエリを再度実行します。
クエリに時間フィルターを追加する
また、時間フィルターをクエリに追加して、独自の時間の範囲を定義することもできます。
テーブル名の直後に時間フィルターを配置することをお勧めします。
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
残念ながら、異なるパフォーマンス カウンターを混在させたため、このクエリの結果は意味がありません。 より意味のある結果にするために、CounterName
と Computer
の組み合わせごとに個別に平均を計算します。
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)
出力をよりわかりやすくするために、時系列で使用可能なメモリを示す時間グラフとして表示することを選択できます。 これを行うには、[グラフ] ビューに切り替え、右側の [グラフのフォーマット] サイドバーを開き、[グラフの種類] で [折れ線] を選択します:
よく寄せられる質問
このセクションでは、一般的な質問への回答を示します。
Azure Monitor ログに重複するレコードが表示されるのはなぜですか?
場合によっては、Azure Monitor ログに重複するレコードが表示されることがあります。 通常、この重複は次の 2 つの条件のいずれかが原因です。
- パイプライン内のコンポーネントは、配信先に確実に配信されるように再試行を行います。 場合によっては、この機能が原因で、わずかながらテレメトリ項目が重複する可能性があります。
- 重複するレコードが仮想マシンから配信される場合、Log Analytics エージェントと Azure Monitor エージェントの両方がインストールされている可能性があります。 今後も Log Analytics エージェントをインストールしておく必要がある場合は、Azure Monitor エージェントが使用しているデータ収集ルールによって収集されるデータが今後は収集されないように、Log Analytics ワークスペースを構成します。
次のステップ
- ログ クエリでの文字列データの使用の詳細について、Azure Monitor ログ クエリでの文字列の操作に関するページをご覧ください。
- ログ クエリでのデータの集計の詳細について、Azure Monitor ログ クエリでの高度な集計に関するページをご覧ください。
- 複数のテーブルのデータを結合する方法について、Azure Monitor ログ クエリでの結合に関するページをご覧ください。
- KQL 言語のリファレンスで、Kusto 照会言語全体のドキュメントを参照してください。