ログ検索アラート クエリを最適化する

この記事では、最適なパフォーマンスを実現するためにログ検索アラートを記述して変換する方法について説明します。 最適化されたクエリを使用すると、頻繁に実行されるアラートの待機時間と負荷が軽減されます。

アラート ログ クエリの記述を始める

アラート クエリは、問題を示すログ分析のログ データを照会することから開始します。 検出できる内容については、「Azure Monitor Log Analytics でのクエリの使用」をご覧ください。 また、独自のクエリの記述を始めることもできます。

アラートでなく問題を示すクエリ

アラート フローは、問題を示す結果をアラートに変換するために構築されました。 たとえば、次のようなクエリについて考えます。

SecurityEvent
| where EventID == 4624

ユーザーの意図がアラートを発することの場合は、この種類のイベントが発生すると、アラート ロジックによってクエリに count が追加されます。 実行されるクエリは次のようになります。

SecurityEvent
| where EventID == 4624
| count

クエリにアラート ロジックを追加する必要はなく、それを行うと問題を起こす可能性さえあります。 前の例では、クエリに count を含めると、アラート サービスは countcount を行うため、結果は常に値 1 になります。

limit と take 演算子を使わない

クエリで limittake を使うと、結果が時間の経過とともに一貫しないため、アラートの待機時間と負荷が増加する可能性があります。 必要な場合にのみ使うようにしてください。

ログ クエリの制約

Azure Monitor のログ クエリは、テーブルか、search 演算子または union 演算子のいずれかで始まります。

ログ検索アラート ルールのクエリは、明確な範囲を定義するテーブルから常に始める必要があります。これにより、クエリのパフォーマンスと結果の関連性が向上します。 アラート ルールのクエリは頻繁に実行されます。 searchunion を使うと、複数のテーブルのスキャンが必要になるため、アラートの待機時間が増加するオーバーヘッドが過剰に生じる可能性があります。 また、これらの演算子は、アラート サービスがクエリを最適化する機能を低下させます。

リソース間のクエリを除き、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 にアップグレードする」を参照してください。

次の例には、searchunion を使うログ クエリが含まれます。 この手順を使うと、これらのクエリを変更してアラート ルールで使用できます。

例 1

search を使ってパフォーマンス情報を取得する次のクエリを使って、ログ検索アラート ルールを作成するとします。

search *
| where Type == 'Perf' and CounterName == '% Free Space'
| where CounterValue < 30
  1. このクエリを変更するには、まず次のクエリを使用して、プロパティが属しているテーブルを特定します。

    search *
    | where CounterName == '% Free Space'
    | summarize by $table
    

    このクエリの結果として、CounterName プロパティが Perf テーブルから取得されたことが示されます。

  2. この結果を使用して、アラート ルールに使用する次のクエリを作成します。

    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)  
  1. このクエリを変更するには、まず次のクエリを使用して、プロパティが属しているテーブルを特定します。

    search ObjectName=="Memory" and CounterName=="% Committed Bytes In Use"
    | summarize by $table
    

    このクエリの結果として、ObjectNameCounterName プロパティが Perf テーブルから取得されたことが示されます。

  2. この結果を使用して、アラート ルールに使用する次のクエリを作成します。

    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

searchunion の両方を使ってパフォーマンス情報を取得する次のクエリを使って、ログ検索アラート ルールを作成するとします。

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
  1. このクエリを変更するには、まず次のクエリを使用して、クエリの最初の部分のプロパティが属しているテーブルを特定します。

    search (ObjectName == "Processor" and CounterName == "% Idle Time" and InstanceName == "_Total")
    | summarize by $table
    

    このクエリの結果として、これらのすべてのプロパティが Perf テーブルから取得されたことが示されます。

  2. withsource コマンドで union を使って、各行の基になっているソース テーブルを特定します。

    union withsource=table *
    | where CounterName == "% Processor Utility"
    | summarize by table
    

    このクエリの結果として、これらのプロパティも Perf テーブルから取得されたことが示されます。

  3. これらの結果を使って、アラート ルールに使う次のクエリを作成します。

    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
  1. このクエリを変更するには、まず次のクエリを使用して、結合の左側にあるプロパティが含まれているテーブルを特定します。

    search Type == 'SecurityEvent' and EventID == '4625'
    | summarize by $table
    

    結果は、結合の左側にあるプロパティが SecurityEvent テーブルに属していることを示しています。

  2. 次のクエリを使って、結合の右側にあるプロパティが含まれているテーブルを特定します。

    search in (Heartbeat) OSType == 'Windows'
    | summarize by $table
    

    結果は、結合の右側にあるプロパティが Heartbeat テーブルに属していることを示しています。

  3. これらの結果を使って、アラート ルールに使う次のクエリを作成します。

    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
    

次のステップ