Azure Monitor에서 로그 쿼리 시작

참고 항목

하나 이상의 가상 머신에서 데이터를 수집하는 경우 사용자 환경에서 이 연습을 통해 작업할 수 있습니다. 다른 시나리오의 경우 많은 샘플 데이터가 포함된 데모 환경을 사용하세요.

KQL(Kusto 쿼리 언어)로 쿼리하는 방법을 이미 알고 있지만 리소스 종류에 따라 유용한 쿼리를 빠르게 만들어야 하는 경우 Azure Monitor Log Analytics에서 쿼리 사용에서 저장된 예제 쿼리 창을 참조하세요.

이 자습서에서는 Azure Monitor에서 로그 쿼리를 작성하는 방법을 알아봅니다. 이 문서에서는 다음 방법을 안내합니다.

  • 쿼리 구조 이해
  • 쿼리 결과 정렬
  • 쿼리 결과 필터링
  • 시간 범위 지정
  • 결과에 포함할 필드 선택
  • 사용자 지정 필드 정의 및 사용
  • 결과 집계 및 그룹화

Azure Portal에서 Log Analytics를 사용하는 방법에 대한 자습서는 Azure Monitor Log Analytics 시작을 참조하세요.

Azure Monitor의 로그 쿼리에 대한 자세한 내용은 Azure Monitor의 로그 쿼리 개요를 참조하세요.

다음은 이 자습서의 비디오 버전입니다.

필수 사용 권한

예를 들어, Log Analytics 읽기 권한자 기본 제공 역할에서 제공하는 대로 쿼리하는 Log Analytics 작업 영역에 대한 Microsoft.OperationalInsights/workspaces/query/*/read 권한이 있어야 합니다.

새 쿼리 작성

쿼리는 테이블 이름 또는 search 명령을 사용하여 시작할 수 있습니다. 쿼리에 대한 명확한 범위를 정의하므로 테이블 이름으로 시작하는 것이 좋습니다. 또한 쿼리 성능과 결과의 관련성을 개선시킵니다.

참고 항목

Azure Monitor에서 사용하는 KQL은 대/소문자를 구분합니다. 언어 키워드는 일반적으로 소문자로 작성됩니다. 쿼리에서 테이블 또는 열 이름을 사용하는 경우 스키마 창에 표시된 대로 정확한 대/소문자를 사용해야 합니다.

테이블 기반 쿼리

Azure Monitor는 테이블에 각각 여러 열로 구성된 로그 데이터를 구성합니다. 모든 테이블 및 열은 Analytics 포털에서 Log Analytics의 스키마 창에 표시됩니다. 관심 있는 테이블을 식별한 다음, 약간의 데이터를 살펴봅니다.

SecurityEvent
| take 10

앞의 쿼리는 SecurityEvent 테이블에서 10개의 결과를 특정 순서 없이 반환합니다. 테이블을 한눈에 볼 수 있는 이 일반적인 방법은 테이블의 구조와 콘텐츠를 이해하는 데 도움이 됩니다. 빌드되는 방식을 살펴보겠습니다.

  • 쿼리는 쿼리의 범위를 정의하는 테이블 이름 SecurityEvent로 시작합니다.

  • 파이프(|) 문자는 명령을 구분하므로 첫 번째 명령의 출력은 다음 명령의 입력입니다. 임의의 수의 파이프된 요소를 추가할 수 있습니다.

  • 파이프 다음에 take 연산자가 옵니다.

    | take 10을 추가하지 않고도 쿼리를 실행할 수 있습니다. 명령은 여전히 유효하지만 최대 30,000개의 결과를 반환할 수 있습니다.

Take

take 연산자를 통해 지정된 레코드 수까지 반환하여 소수의 레코드 샘플을 확인합니다. 선택한 결과는 임의이며 특정 순서로 표시되지 않습니다. 결과를 특정 순서로 반환해야 하는 경우 sorttop 연산자를 사용합니다.

검색 쿼리

쿼리는 덜 구조화되어 있습니다. 열에 특정 값이 포함된 레코드를 찾는 데 더 적합합니다.

search in (SecurityEvent) "Cryptographic"
| take 10

이 쿼리는 구문 "Cryptographic"을 포함하는 레코드를 SecurityEvent 테이블에서 검색합니다. 이러한 레코드 중 10개의 레코드가 반환되고 표시됩니다. in (SecurityEvent) 부분을 생략하고 search "Cryptographic"만 실행하면 검색이 모든 테이블을 대상으로 합니다. 그러면 프로세스가 더 오래 걸리고 덜 효율적입니다.

Important

검색 쿼리는 더 많은 데이터를 처리해야 하기 때문에 일반적으로 테이블 기반 쿼리보다 느립니다.

정렬 및 위쪽

이 섹션에서는 sorttop 연산자 해당 descasc 인수에 대해 설명합니다. take는 몇 가지 레코드를 가져오는 데 유용하지만 특정 순서로 결과를 선택하거나 정렬할 수는 없습니다. 순서가 지정된 보기를 얻으려면 sorttop을 사용합니다.

Desc 및 asc

Desc

desc 인수를 사용하여 레코드를 내림차순으로 정렬합니다. 내림차순이 sorttop의 기본 정렬 순서이므로 일반적으로 desc 인수는 생략해도 됩니다.

예를 들어 다음 두 쿼리에서 반환되는 데이터는 TimeGenerated 열을 기준으로 내림차순으로 정렬됩니다.

  • SecurityEvent	
    | sort by TimeGenerated desc
    
  • SecurityEvent	
    | sort by TimeGenerated
    

Asc

오름차순으로 정렬하려면 asc를 지정합니다.

정렬

sort 연산자를 사용할 수 있습니다. sort는 지정한 열을 기준으로 쿼리 결과를 정렬합니다. 그러나 sort는 쿼리에서 반환되는 레코드 수를 제한하지 않습니다.

예를 들어 다음 쿼리는 최대 30,000개의 레코드까지 SecurityEvent 테이블의 사용 가능한 모든 레코드를 반환하고 TimeGenerated 열을 기준으로 정렬합니다.

SecurityEvent	
| sort by TimeGenerated

위의 쿼리는 너무 많은 결과를 반환할 수 있습니다. 또한 결과를 반환하는 데 다소 시간이 걸릴 수도 있습니다. 쿼리는 TimeGenerated 열을 기준으로 전체 SecurityEvent 테이블을 정렬합니다. 그런 다음, Analytics 포털은 표시를 30,000개의 레코드로만 제한합니다. 이 방식은 최적이 아닙니다. 최신 레코드만 가져오는 가장 좋은 방법은 top 연산자를 사용하는 것입니다.

상단

top 연산자를 사용하여 서버 쪽에서 전체 테이블을 정렬한 다음, 상위 레코드만 반환합니다.

예를 들어 다음 쿼리는 최신 10개의 레코드를 반환합니다.

SecurityEvent
| top 10 by TimeGenerated

출력은 다음 예제와 같이 표시됩니다.

Screenshot that shows the top 10 records sorted in descending order.

where 연산자: 조건에 따라 필터링

해당 이름으로 표시된 대로 Filters, 특정 조건에 따라 데이터를 필터링합니다. 필터링은 쿼리 결과를 관련 정보로 제한하는 가장 일반적인 방법입니다.

쿼리에 필터를 추가하려면 where 연산자를 입력한 후 하나 이상의 조건을 지정합니다. 예를 들어, 다음 쿼리는 Level equals _8SecurityEvent 레코드만 반환합니다.

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

참고 항목

값은 여러 형식을 가질 수 있으므로 올바른 형식에서 비교를 수행하도록 캐스트해야 할 수 있습니다. 예를 들어, SecurityEvent Level 열은 문자열 형식이므로 다음과 같이 숫자 연산자를 사용하기 전에 int 또는 long과 같은 숫자 형식으로 변환해야 합니다. SecurityEvent | where toint(Level) >= 10

시간 범위 지정

시간 선택기 또는 시간 필터를 사용하여 시간 범위를 지정할 수 있습니다.

시간 선택기 사용

시간 선택기는 실행 단추 옆에 표시되며 지난 24시간 동안의 레코드만 쿼리하고 있음을 나타냅니다. 이 기본 시간 범위는 모든 쿼리에 적용됩니다. 지난 1시간의 레코드만을 가져오려면 지난 1시간을 선택한 다음, 쿼리를 다시 실행합니다.

Screenshot that shows the time picker and its list of time-range commands.

쿼리에 시간 필터 추가

쿼리에 시간 필터를 추가하여 고유한 시간 범위를 정의할 수도 있습니다. 시간 필터를 추가하면 시간 선택기에서 선택한 시간 범위가 재정의됩니다.

시간 필터를 테이블 이름 바로 뒤에 배치하는 것이 좋습니다.

SecurityEvent
| where TimeGenerated > ago(30m) 
| where toint(Level) >= 10

이전 시간 필터에서 ago(30m)는 "30분 전"을 의미합니다. 이 쿼리는 예를 들어, 30m으로 표현되는 마지막 30분의 레코드만 반환합니다. 다른 시간 단위에는 일(예: 2d) 및 초(예: 10s)가 있습니다.

project 및 extend를 사용하여 열 선택 및 컴퓨팅

project를 사용하여 결과에 포함할 특정 열을 선택합니다.

SecurityEvent 
| top 10 by TimeGenerated 
| project TimeGenerated, Computer, Activity

앞의 예는 다음 출력을 생성합니다.

Screenshot that shows the query 'project' results list.

project를 사용하여 열 이름을 바꾸고 새 열을 정의할 수도 있습니다. 다음 예제에서는 project를 사용하여 다음을 수행합니다.

  • 원래 열 ComputerTimeGenerated만 선택합니다.
  • Activity 열을 EventDetails로 표시합니다.
  • EventCode라는 새 열을 만듭니다. substring() 함수는 Activity 필드에서 처음 4자만 가져오는 데 사용됩니다.
SecurityEvent
| top 10 by TimeGenerated 
| project Computer, TimeGenerated, EventDetails=Activity, EventCode=substring(Activity, 0, 4)

extend를 사용하여 결과 집합의 모든 원래 열을 유지하고 다른 열을 정의할 수 있습니다. 다음 쿼리는 EventCode 열을 추가하는 데 extend를 사용합니다. 이 열은 테이블 결과 끝에 표시되지 않을 수 있습니다. 레코드를 보려면 레코드의 세부 정보를 확장해야 합니다.

SecurityEvent
| top 10 by TimeGenerated
| extend EventCode=substring(Activity, 0, 4)

summarize를 사용하여 행 그룹 집계

summarize를 사용하여 하나 이상의 열에 따라 레코드 그룹을 식별하고, 집계를 적용합니다. summarize의 가장 일반적인 사용은 count이며 각 그룹의 결과 수를 반환합니다.

다음 쿼리는 지난 시간에서 모든 Perf 레코드를 검토하고, ObjectName으로 그룹화하고, 각 그룹의 레코드 수를 계산합니다.

Perf
| where TimeGenerated > ago(1h)
| summarize count() by ObjectName

경우에 따라 여러 차원에서 그룹을 정의하는 것일 수 있습니다. 이러한 값의 각 고유한 조합은 별도 그룹을 정의합니다.

Perf
| where TimeGenerated > ago(1h)
| summarize count() by ObjectName, CounterName

또 다른 일반적인 사용은 각 그룹에 대해 수치 연산 또는 통계 계산을 수행하는 것입니다. 다음 예에서는 각 컴퓨터에 대한 평균 CounterValue를 계산합니다.

Perf
| where TimeGenerated > ago(1h)
| summarize avg(CounterValue) by Computer

안타깝게도 이 쿼리의 결과는 서로 다른 성능 카운터를 혼합했기 때문에 의미가 없습니다. 결과를 더 의미 있게 만들려면 CounterNameComputer의 각 조합에 대해 개별적으로 평균을 계산합니다.

Perf
| where TimeGenerated > ago(1h)
| summarize avg(CounterValue) by Computer, CounterName

시간 열별 요약

결과 그룹화는 time 열 또는 다른 연속 값을 기준으로 할 수도 있습니다. 그러나 간단히 by TimeGenerated를 요약하면 이는 고유한 값이므로 시간 범위 동안 모든 단일 밀리초에 대한 그룹을 만듭니다.

연속 값을 기반으로 그룹을 만들려면 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)

출력을 명확히 하려면 시간에 따른 사용 가능한 메모리를 보여주는 시간 차트로 표시하도록 선택할 수 있습니다.

Screenshot that shows the values of a query memory over time.

자주 묻는 질문

이 섹션에서는 일반적인 질문에 대한 답변을 제공합니다.

Azure Monitor 로그에 중복 레코드가 표시되는 이유는 무엇인가요?

경우에 따라 Azure Monitor 로그에서 중복 레코드를 확인할 수 있습니다. 이 중복은 일반적으로 다음 두 조건 중 하나에 해당합니다.

  • 파이프라인의 구성 요소는 대상에 안정적으로 배달되도록 다시 시도합니다. 경우에 따라 이 기능으로 인해 일부 원격 분석 항목에 대해 중복이 발생할 수 있습니다.
  • 중복 레코드가 가상 컴퓨터에서 제공되는 경우 Log Analytics 에이전트와 Azure Monitor 에이전트가 모두 설치되어 있을 수 있습니다. Log Analytics 에이전트가 여전히 설치되야 하는 경우 Azure Monitor 에이전트에서 사용하는 데이터 수집 규칙에 의해 수집되는 데이터를 더 이상 수집하지 않도록 Log Analytics 작업 영역을 구성합니다.

다음 단계