본문 바로가기

DevOps

[AWS] CloudWatch Log Insights Query

CloudWatch Log Insights Query

 

 

벌써 이주 전의 일이지만, 처음 클라우드 워치 로그 인사이트를 이용해보았다. 많은 로그 중에 찾고자 하는 error log 를 필터링해 검색하니 빠른 원인 파악에 도움이 되었다. aws 사이트에 나온 쿼리 사용설명서를 정독해보니 집계 함수도 있었고  우선 내가 잘 써먹어봄직한 몇 가지만 골라 공부해본다. 

 

 

우선, 

CloudWatch Log Insights Query 구문은 | (파이프 문자)  구분지어 명령을 이상 포함할 있다. 

 

기본적인 명령어는 다음과 같다.

  • fields – 하나 이상의 로그 필드를 검색. (abs, sqrt, strlen, trim 등의 기능도 활용할 수 있다.)
  • display – 쿼리 결과에 표시할 필드를 지정. 
  • filter – Boolean 연산자, 비교 연산자 및 정규 표현식에서 구축된 하나 이상의 조건을 기반으로 로그 필드를 검색.
  • stats – 특정 시간 간격동안 로그 필드의 합계, 평균, 카운트, 최소, 최대값 및 백분위수와 같은 집계 통계량을 계산.
  • sort – 로그 이벤트를 오름차순 또는 내림차순으로 정렬.
  • limit – 쿼리가 반환하는 로그 이벤트 수 제한.
  • parse – 로그 필드에서 데이터를 추출하여 쿼리에 의해 추가로 처리될 수 있는 하나 이상의 ephemeral  필드를 생성.

찬찬히 읽어보고 사용하다보면, DB Query 와 비슷한 면이 있다. 

fields -> field, filter -> where, sort  -> order by , limit ->  limit .

첫 날 사용할 땐 이렇게 감 잡아 사용했지만, 오늘은 좀 더 구체적으로 알아보았다.

 

 

📌 Display : 쿼리 결과에 표시할 필드를 지정한다. 

  • 로그 타입이 error인 필드(filter 명령어 이용) 만 에러 메세지(display 명령어 이용)와 함께 서치하는 예제.
  • ex ) @message 필드를 사용하고 쿼리에서 사용하기 위한 임시 필드 loggingType과 loggingMessage를 생성한다. 
fields @message
      | parse @message “[*] *” as loggingType, loggingMessage
      | filter loggingType = “ERROR”
      | display loggingMessage

 

📌 Fields : 로그 이벤트에서 지정된 필드를 검색한다

  • 함수와 연산을 사용해 필드 값을 수정할 수 있으며 새 필드를 만들 수 있다. 
  • ex ) 임시필드 opStatus 를 만들고 opStatus의 값은 Operation 와 StatusCode 필드의 값을 하이픈으로 연결한 것.
fields concat(Operation, '-', StatusCode) as opStatus

 

📌 Filter : 하나 이상의 조건을 기반으로 쿼리 결과를 필터링한다.

  • Filter 명령에서 다양한 연산자와 표현식을 사용할 수 있다.  
  • ex ) statusCode가 300,400,500인 로그 이벤트를 반환한다. 
fields @timestamp, @message 
      | filter statusCode in [300, 400, 500]


f1에 Exception 이 포함된 모든 이벤트를 반환하는 3가지 쿼리 (모두 대/소문자 구별)
* fields f1, f2, f3 | filter f1 like /Exception/
* fields f1, f2, f3 | filter f1 =~ /Exception/ 
* fields f1, f2, f3 | filter f1 like "Exception" (부문 문자열 일치)

대/ 소문자 구분하지 않는 쿼리
fields f1, f2, f3 | filter f1 like /(?i)Exception/

f1에 정확하게 단어 Exception이 포함된 모든 이벤트 반환 (대/소문자 구분하지 않음)
fields f1, f2, f3 | filter f1 =~ /^(?i)Exception$/

 

 

📌 Stats : 로그 필드의 값을 기반으로 집계를 계산한다. 

    • by와 함께 사용하면 통계를 계산할 때 데이터를 그룹화 하는데 사용할 기준을 하나 이상 지정할 수 있다. 
    • sum(), avg(), count(), min(), max()  여러 연산자가 지원된다. 
    • ex ) f1의 값 평균을 myAvgF1으로 계산하여 해당 값을 기준으로 내림차순으로 반환한다.
stats avg(f1) as myAvgF1 | sort myAvgF1 desc

| 참고 | 별칭 사용 'as' 

 

📌 Sort : 검색된 로그 이벤트를 정렬한다. 

  • 오름차순 asc, 내림차순 desc 
  • ex ) f1 필드를 내림차순으로 정렬하여 
Fileds f1, f2, f3 
      | sort f1 desc

 

 

📌  Limit : 쿼리에서 반환되는 로그 이벤트 수를 지정한다.

    • 제한을 지정하지 않으면 쿼리의 기본값을 최대 1,000 행을 표시한다. 
    • ex ) @timestamp 값을 기준으로 이벤트를 내림차순으로 정렬하고 정렬 순서에 따라 처음 25 이벤트에 대해 f1, f2 필드를 표시한다. 정렬 순서는 타임 스탬프를 기준으로 최신 타임프부터 표시되므로 최근 25 이벤트가 반환된다
Sort @timestamp desc
      | limit 25
      | display f1, f2 

 

 

📌  Parse :  로그 필드에서 데이터를 추출하고, 쿼리에서 추가로 처리할 수 있는 임시 필드가 하나 이상 생성된다.

단일 로그 라인을 예로 사용하면,

25 May 2019 10:24:39,474 [ERROR] {foo=2, bar=data} The error was: DataIntegrityException

 

아래의 두 가지 parse 표현식이 각각 수행하는 작업: 휘발성 필드 level, config  exception이 생성된다. 

level ERROR, config {foo=2, bar=data}, exception DataIntegrityException이라는 값을 갖는다.

첫 번째 예제는 glob 표현식을 사용하고, 두 번째는 정규식을 사용한다.

1. glob
parse @message "[*] * The error was: *" as level, config, exception

2. 정규식
parse @message /\[(?<level>\S+)\]\s+(?<config>\{.*\})\s+The error was: (?<exception>\S+)/

|참고|

glob 표현식의 경우, 문자의 각 변수가 별표(*)로 대체될 수 있는 상수 문자열로 parse 명령을 제공한다. 이 때, 큰따옴표 또는 작은따옴표로 문자를 묶는다. as 다음의 별칭을 키워드로 하여 위치 순서로 임시 필드로 추출됩니다.

 

 

 

📍 주석

  • # 로 달 수 있으며 쿼리에서 # 문자로 시작되는 행은 무시된다. 
fields @timestamp, @message
        # | filter @message like /delay/
           | limit 20