ログ検索アラート クエリを最適化する
この記事では、最適なパフォーマンスを実現するためにログ検索アラートを記述して変換する方法について説明します。 最適化されたクエリを使用すると、頻繁に実行されるアラートの待機時間と負荷が軽減されます。
アラート ログ クエリの記述を始める
アラート クエリは、問題を示すログ分析のログ データを照会することから開始します。 検出できる内容については、「Azure Monitor Log Analytics でのクエリの使用」をご覧ください。 また、独自のクエリの記述を始めることもできます。
アラートでなく問題を示すクエリ
アラート フローは、問題を示す結果をアラートに変換するために構築されました。 たとえば、次のようなクエリについて考えます。
SecurityEvent
| where EventID == 4624
ユーザーの意図がアラートを発することの場合は、この種類のイベントが発生すると、アラート ロジックによってクエリに count
が追加されます。 実行されるクエリは次のようになります。
SecurityEvent
| where EventID == 4624
| count
クエリにアラート ロジックを追加する必要はなく、それを行うと問題を起こす可能性さえあります。 前の例では、クエリに count
を含めると、アラート サービスは count
の count
を行うため、結果は常に値 1 になります。
limit と take 演算子を使わない
クエリで limit
と take
を使うと、結果が時間の経過とともに一貫しないため、アラートの待機時間と負荷が増加する可能性があります。 必要な場合にのみ使うようにしてください。
ログ クエリの制約
Azure Monitor のログ クエリは、テーブルか、search
演算子または union
演算子のいずれかで始まります。
ログ検索アラート ルールのクエリは、明確な範囲を定義するテーブルから常に始める必要があります。これにより、クエリのパフォーマンスと結果の関連性が向上します。 アラート ルールのクエリは頻繁に実行されます。 search
と union
を使うと、複数のテーブルのスキャンが必要になるため、アラートの待機時間が増加するオーバーヘッドが過剰に生じる可能性があります。 また、これらの演算子は、アラート サービスがクエリを最適化する機能を低下させます。
リソース間のクエリを除き、search
演算子または union
演算子を使用したログ検索アラート ルールの作成または変更を行うことはできません。
たとえば、次のアラート クエリは SecurityEvent テーブルが対象であり、特定のイベント ID を検索します。 これは、このクエリが処理する必要のある唯一のテーブルです。
SecurityEvent
| where EventID == 4624
リソース間のクエリは union
型を使い、これによりクエリの範囲が特定のリソースに制限されるため、リソース間のクエリを使用するログ検索アラート ルールはこの変更による影響は受けません。 以下に、有効なログ検索アラート クエリの例を示します。
union
app('00000000-0000-0000-0000-000000000001').requests,
app('00000000-0000-0000-0000-000000000002').requests,
workspace('00000000-0000-0000-0000-000000000003').Perf
Note
リソース間のクエリは、新しい scheduledQueryRules API でサポートされています。 ログ検索アラートを作成するために従来の Log Analytics Alert API をまだ使っている場合、切り替えについては「従来のルール管理を現在の Azure Monitor のスケジュールされたクエリ ルール API にアップグレードする」を参照してください。
例
次の例には、search
と union
を使うログ クエリが含まれます。 この手順を使うと、これらのクエリを変更してアラート ルールで使用できます。
例 1
search
を使ってパフォーマンス情報を取得する次のクエリを使って、ログ検索アラート ルールを作成するとします。
search *
| where Type == 'Perf' and CounterName == '% Free Space'
| where CounterValue < 30
このクエリを変更するには、まず次のクエリを使用して、プロパティが属しているテーブルを特定します。
search * | where CounterName == '% Free Space' | summarize by $table
このクエリの結果として、CounterName プロパティが Perf テーブルから取得されたことが示されます。
この結果を使用して、アラート ルールに使用する次のクエリを作成します。
Perf | where CounterName == '% Free Space' | where CounterValue < 30
例 2
search
を使ってパフォーマンス情報を取得する次のクエリを使って、ログ検索アラート ルールを作成するとします。
search ObjectName =="Memory" and CounterName=="% Committed Bytes In Use"
| summarize Avg_Memory_Usage =avg(CounterValue) by Computer
| where Avg_Memory_Usage between(90 .. 95)
このクエリを変更するには、まず次のクエリを使用して、プロパティが属しているテーブルを特定します。
search ObjectName=="Memory" and CounterName=="% Committed Bytes In Use" | summarize by $table
このクエリの結果として、ObjectName と CounterName プロパティが Perf テーブルから取得されたことが示されます。
この結果を使用して、アラート ルールに使用する次のクエリを作成します。
Perf | where ObjectName =="Memory" and CounterName=="% Committed Bytes In Use" | summarize Avg_Memory_Usage=avg(CounterValue) by Computer | where Avg_Memory_Usage between(90 .. 95)
例 3
search
と union
の両方を使ってパフォーマンス情報を取得する次のクエリを使って、ログ検索アラート ルールを作成するとします。
search (ObjectName == "Processor" and CounterName == "% Idle Time" and InstanceName == "_Total")
| where Computer !in (
union *
| where CounterName == "% Processor Utility"
| summarize by Computer)
| summarize Avg_Idle_Time = avg(CounterValue) by Computer
このクエリを変更するには、まず次のクエリを使用して、クエリの最初の部分のプロパティが属しているテーブルを特定します。
search (ObjectName == "Processor" and CounterName == "% Idle Time" and InstanceName == "_Total") | summarize by $table
このクエリの結果として、これらのすべてのプロパティが Perf テーブルから取得されたことが示されます。
withsource
コマンドでunion
を使って、各行の基になっているソース テーブルを特定します。union withsource=table * | where CounterName == "% Processor Utility" | summarize by table
このクエリの結果として、これらのプロパティも Perf テーブルから取得されたことが示されます。
これらの結果を使って、アラート ルールに使う次のクエリを作成します。
Perf | where ObjectName == "Processor" and CounterName == "% Idle Time" and InstanceName == "_Total" | where Computer !in ( (Perf | where CounterName == "% Processor Utility" | summarize by Computer)) | summarize Avg_Idle_Time = avg(CounterValue) by Computer
例 4
2 つの search
クエリの結果を結合する次のクエリを使って、ログ検索アラート ルールを作成するとします。
search Type == 'SecurityEvent' and EventID == '4625'
| summarize by Computer, Hour = bin(TimeGenerated, 1h)
| join kind = leftouter (
search in (Heartbeat) OSType == 'Windows'
| summarize arg_max(TimeGenerated, Computer) by Computer , Hour = bin(TimeGenerated, 1h)
| project Hour , Computer
) on Hour
このクエリを変更するには、まず次のクエリを使用して、結合の左側にあるプロパティが含まれているテーブルを特定します。
search Type == 'SecurityEvent' and EventID == '4625' | summarize by $table
結果は、結合の左側にあるプロパティが SecurityEvent テーブルに属していることを示しています。
次のクエリを使って、結合の右側にあるプロパティが含まれているテーブルを特定します。
search in (Heartbeat) OSType == 'Windows' | summarize by $table
結果は、結合の右側にあるプロパティが Heartbeat テーブルに属していることを示しています。
これらの結果を使って、アラート ルールに使う次のクエリを作成します。
SecurityEvent | where EventID == '4625' | summarize by Computer, Hour = bin(TimeGenerated, 1h) | join kind = leftouter ( Heartbeat | where OSType == 'Windows' | summarize arg_max(TimeGenerated, Computer) by Computer , Hour = bin(TimeGenerated, 1h) | project Hour , Computer ) on Hour