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
は少数のレコードを取得するのに便利ですが、結果を特定の順序で選択または並べ替えることはできません。 順序付けされたビューを取得するには、sort
と top
を使用します。
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
出力は次の例のようになります。
where 演算子: 条件に基づいたフィルター処理
フィルターは、その名前のとおり、特定の条件に基づいてデータをフィルター処理します。 フィルター処理は、クエリ結果を関連する情報に制限する最も一般的な方法です。
クエリにフィルターを追加するには、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
などの数値型にキャストする必要があります。
時間の範囲を指定する
時間の範囲は、時刻の選択または時間フィルターを使用して指定できます。
日時ピッカーを使用する
時刻の選択は [実行] ボタンの横に表示され、過去 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
残念ながら、異なるパフォーマンス カウンターを混在させたため、このクエリの結果は意味がありません。 より意味のある結果にするために、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 == "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 ワークスペースを構成します。
次のステップ
- ログ クエリでの文字列データの使用の詳細について、Azure Monitor ログ クエリでの文字列の操作に関するページをご覧ください。
- ログ クエリでのデータの集計の詳細について、Azure Monitor ログ クエリでの高度な集計に関するページをご覧ください。
- 複数のテーブルのデータを結合する方法について、Azure Monitor ログ クエリでの結合に関するページをご覧ください。
- KQL 言語のリファレンスで、Kusto 照会言語全体のドキュメントを参照してください。