AWS CloudWatch Logs Insights 쿼리 모음 (수정중)
애플리케이션 장애가 발생하거나 사용자 문의가 들어왔을 때 가장 먼저 확인해야 하는 것은 보통 로그다. 현재 운영 중인 서비스는 API Gateway + AWS Lambda + DynamoDB 기반의 Serverless 아키텍처를 사용하고 있고, 로그는 CloudWatch Logs + S3에 저장하고 있다.
CloudWatch Logs는 기본적으로 로그 그룹(Log Group)과 로그 스트림(Log Stream) 단위로 로그를 저장한다. 이 구조를 이해하고 있으면 왜 Logs Insights가 필요한지도 같이 이해하기 쉽다.
CloudWatch 로그 구조
섹션 제목: “CloudWatch 로그 구조”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: pathLog Insights를 사용해야 하는 이유
섹션 제목: “Log Insights를 사용해야 하는 이유”문제는 원하는 로그를 로그 스트림 단위로 직접 찾아보기가 어렵다는 점이다.
AWS Lambda의 경우 로그 스트림은 함수 이름 기준이 아니라, 실행된 Lambda 인스턴스 기준으로 생성된다.
- Lambda가 실행되면 로그 스트림 하나를 만들고 로그를 기록한다.
- 같은 시점에 다른 요청이 들어오면 다른 Lambda 인스턴스가 실행되고, 별도 로그 스트림에 로그를 기록한다.
- 기존 인스턴스가 살아 있는 동안 다시 요청이 들어오면 같은 인스턴스가 재사용되고, 기존 로그 스트림에 이어서 기록한다.
이 구조 때문에 병렬 실행이 많은 환경에서는 로그 스트림 수가 빠르게 늘어난다. 예를 들어 같은 시간대에 Lambda 인스턴스가 1000개 실행되면, 사실상 1000개의 로그 스트림에 로그가 흩어져 있을 수 있다.
이런 상황에서 필요한 로그를 로그 스트림별로 직접 찾는 것은 비효율적이다. CloudWatch Logs Insights는 이 흩어진 로그를 쿼리로 검색할 수 있게 해 주는 도구다.
Log Insights Query
섹션 제목: “Log Insights Query”Filter
섹션 제목: “Filter”단순 Keyword 검색
섹션 제목: “단순 Keyword 검색” filter @message like /${SEARCH_KEYWORD}/ | sort @timestamp desc filter @message like /Android/ | sort @timestamp descurl path 등 특수 문자가 포함된 Keyword
섹션 제목: “url path 등 특수 문자가 포함된 Keyword”-
ex)
api/v1/display/filter @message like /api\/v1\/display\//| sort @timestamp desc
Keyword 가 있는 로그의 특정 필드값 만 검색
섹션 제목: “Keyword 가 있는 로그의 특정 필드값 만 검색”-
ex)
TransactionConflict로그가 있는 RequestIdfields @requestId| filter @message like /TransactionConflict/| sort @timestamp desc -
ex)
TransactionConflict로그가 있는 timestamp, logStreamfields @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
섹션 제목: “Stats”RequestId 별로 로그 갯수 집계
섹션 제목: “RequestId 별로 로그 갯수 집계”stats count(*) by @requestId- 결과:
@requestId Count(*) 2323 5
FILTER response.code like /0001/| stats count(*) by response.codeFields
섹션 제목: “Fields”기본적인 Field 들
섹션 제목: “기본적인 Field 들”| Field | Desc | Example |
|---|---|---|
| @ingestionTime | - | 1729743338706 |
| @log | cloudwatch log group 명 | 유저아이디:/aws/lambda/서비스명 |
| @logStream | 로그스트림명 | - |
| @message | 로그 내용 | - |
| @requestId | 리퀘이스트 아이디 | - |
| @timestamp | - | 1729743329689 |
그 외
섹션 제목: “그 외”- 이 외에
JSON.stringify({name: 'onejay', region: 'asia'})로 출력한 로그의 경우 name, region 등의 이름으로도 검색이 가능하다.
FILTER region like /asia/주의점
섹션 제목: “주의점”Logs Insights는 AWS가 제공하는 관리형 서비스이므로, 검색한 데이터 양에 따라 비용이 발생한다.
검색 결과 제한
섹션 제목: “검색 결과 제한”한 번의 검색으로 확인할 수 있는 로그 수에도 제한이 있다. 따라서 결과가 너무 많다면 기간을 줄이거나 쿼리를 더 좁혀서 확인하는 편이 좋다.
- Refs
- Analyzing log data with CloudWatch Logs Insights
- CloudWatch Logs Insights query syntax
- CloudWatch Logs Insightsでログを調査する前に読む記事
- Understanding AWS CloudWatch Pricing: A Comprehensive Guide
- “Breaking the Barrier: Resolving the 10K Log Insights Limit in CloudWatch and Consolidating Records into a CSV”
- AWS初心者がCloudWatch Logs Insightsを使ってみた
- CloudWatch Logs Insights 集計クエリ入門