콘텐츠로 이동

AWS CloudWatch Logs Insights 쿼리 모음 (수정중)

등록일

수정일

애플리케이션 장애가 발생하거나 사용자 문의가 들어왔을 때 가장 먼저 확인해야 하는 것은 보통 로그다. 현재 운영 중인 서비스는 API Gateway + AWS Lambda + DynamoDB 기반의 Serverless 아키텍처를 사용하고 있고, 로그는 CloudWatch Logs + S3에 저장하고 있다.

CloudWatch Logs는 기본적으로 로그 그룹(Log Group)과 로그 스트림(Log Stream) 단위로 로그를 저장한다. 이 구조를 이해하고 있으면 왜 Logs Insights가 필요한지도 같이 이해하기 쉽다.

CloudWatch Logs는 로그를 로그 그룹(Log Group)로그 스트림(Log Stream) 단위로 저장한다.

Serverless Framework를 예로 들면, 아래처럼 서비스명 기준 로그 그룹이 생성되고 함수별 실행 로그가 로그 스트림으로 쌓인다.

service: example-service # Log Group Name: example-service-dev, example-service-prod, ...
provider:
name: aws
region: ap-northeast-2
functions:
exampleLambdaIndex: # Log Stream
handler: path
exampleLambdaStatistics: # Log Stream
handler: path

Log Insights를 사용해야 하는 이유

섹션 제목: “Log Insights를 사용해야 하는 이유”

문제는 원하는 로그를 로그 스트림 단위로 직접 찾아보기가 어렵다는 점이다.

AWS Lambda의 경우 로그 스트림은 함수 이름 기준이 아니라, 실행된 Lambda 인스턴스 기준으로 생성된다.

  1. Lambda가 실행되면 로그 스트림 하나를 만들고 로그를 기록한다.
  2. 같은 시점에 다른 요청이 들어오면 다른 Lambda 인스턴스가 실행되고, 별도 로그 스트림에 로그를 기록한다.
  3. 기존 인스턴스가 살아 있는 동안 다시 요청이 들어오면 같은 인스턴스가 재사용되고, 기존 로그 스트림에 이어서 기록한다.

이 구조 때문에 병렬 실행이 많은 환경에서는 로그 스트림 수가 빠르게 늘어난다. 예를 들어 같은 시간대에 Lambda 인스턴스가 1000개 실행되면, 사실상 1000개의 로그 스트림에 로그가 흩어져 있을 수 있다.

이런 상황에서 필요한 로그를 로그 스트림별로 직접 찾는 것은 비효율적이다. CloudWatch Logs Insights는 이 흩어진 로그를 쿼리로 검색할 수 있게 해 주는 도구다.

filter @message like /${SEARCH_KEYWORD}/
| sort @timestamp desc
filter @message like /Android/
| sort @timestamp desc

url path 등 특수 문자가 포함된 Keyword

섹션 제목: “url path 등 특수 문자가 포함된 Keyword”
  • ex) api/v1/display/

    filter @message like /api\/v1\/display\//
    | sort @timestamp desc

Keyword 가 있는 로그의 특정 필드값 만 검색

섹션 제목: “Keyword 가 있는 로그의 특정 필드값 만 검색”
  • ex) TransactionConflict 로그가 있는 RequestId

    fields @requestId
    | filter @message like /TransactionConflict/
    | sort @timestamp desc
  • ex) TransactionConflict 로그가 있는 timestamp, logStream

    fields @timestamp, @message, @logStream, @log
    | filter @message like /TransactionConflict/
    | sort @timestamp desc
    • 정규식 사용

      fields @timestamp, @message, @logStream, @log
      | filter @message like /TransactionConflict(?!.*(dup|Exception)).*$/
      | sort @timestamp desc
stats count(*) by @requestId
  • 결과: @requestId Count(*) 2323 5
FILTER response.code like /0001/
| stats count(*) by response.code
FieldDescExample
@ingestionTime-1729743338706
@logcloudwatch log group 명유저아이디:/aws/lambda/서비스명
@logStream로그스트림명-
@message로그 내용-
@requestId리퀘이스트 아이디-
@timestamp-1729743329689
  • 이 외에 JSON.stringify({name: 'onejay', region: 'asia'}) 로 출력한 로그의 경우 name, region 등의 이름으로도 검색이 가능하다.
FILTER region like /asia/

Logs Insights는 AWS가 제공하는 관리형 서비스이므로, 검색한 데이터 양에 따라 비용이 발생한다.

한 번의 검색으로 확인할 수 있는 로그 수에도 제한이 있다. 따라서 결과가 너무 많다면 기간을 줄이거나 쿼리를 더 좁혀서 확인하는 편이 좋다.