로그 검색 경고 쿼리 최적화
이 문서에서는 최적의 성능을 달성하기 위해 로그 검색 경고를 작성하고 변환하는 방법을 설명합니다. 최적화된 쿼리는 자주 실행되는 경고의 대기 시간 및 부하를 줄입니다.
로그 검색 경고 쿼리 작성 시작
경고 쿼리는 Log Analytics에서 문제를 나타내는 로그 데이터를 쿼리하는 것부터 시작합니다. 검색할 수 있는 내용을 이해하려면 Azure Monitor Log Analytics에서 쿼리 사용을 참조하세요. 또한 사용자 고유의 쿼리를 작성하기 시작할 수도 있습니다.
쿼리가 경고 자체가 아닌 문제를 식별하는지 확인합니다.
경고 흐름은 경고에 대한 문제를 나타내는 결과를 변환하기 위해 빌드되었습니다. 예를 들어 다음과 같은 쿼리의 경우:
SecurityEvent
| where EventID == 4624
사용자가 의도가 경고하는 것이라면, 이러한 이벤트 유형이 발생할 때 경고 논리가 쿼리에 count
를 추가합니다. 실행되는 쿼리는 다음과 같습니다.
SecurityEvent
| where EventID == 4624
| count
쿼리에 경고 논리를 추가할 필요가 없으며, 오히려 그렇게 하면 문제가 발생할 수도 있습니다. 앞의 예에서 쿼리에 count
를 포함하면 경고 서비스가 count
의 count
를 수행하기 때문에 항상 값 1이 됩니다.
제한 방지 및 연산자 사용
쿼리에서 limit
및 take
를 사용하면 시간이 지남에 따라 결과가 일관되지 않으므로 대기 시간 및 경고 로드가 증가할 수 있습니다. 필요한 경우에만 사용합니다.
로그 쿼리 제약 조건
Azure Monitor 로그 쿼리는 테이블, search
또는 union
연산자에서 시작합니다.
명확한 범위를 정의하려면 Azure의 로그 검색 경고 규칙에 대한 쿼리는 항상 테이블로 시작되어야 합니다. 이를 통해 쿼리 성능과 결과의 관련성을 개선할 수 있습니다. 경고 규칙의 쿼리는 자주 실행됩니다. 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
참고 항목
로그 경고의 상호 리소스 쿼리는 새로운 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
다음 쿼리를 사용하여 두 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
결과에는 조인 오른쪽의 속성이 하트비트 테이블에 속한다는 내용이 표시됩니다.
이러한 결과를 사용하여 경고 규칙에 사용할 다음 쿼리를 작성할 수 있습니다.
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