Datadog 서버리스 Lambda 모니터링
- 서버리스 장점과 단점(Lambda)

장점
모든 것을 클라우드 밴더에서 매니지드 해주기 때문에 사용자는 개발에만 집중할 수 있다. (NoOps)
사용한만큼 과금되는 방식으로 합리적이다. (메모리만 설정 가능하며 메모리에 비례해서 CPU 할당)
강제(?)로 마이크로서비스가 구성된다.
힙(?) 하다.
단점
서버리스의 CPU/Memory 등 리소스의 한계가 존재한다.
아직은 콜드스타트로 인한 지연이 발생된다.
기존 개발과 테스트 그리고 배포 방식을 사용할 수 없다.
지원하는 개발 언어 및 버전 한계가 존재. (Node.js, Python, Java, .Net, Ruby)
과금 방식은 합리적이지만 저렴하지 않으며, 과금 모니터링이 쉽지 않다.
서버리스 제공사에 Lock-in이 발생된다.
하드하게 사용 시에는 Sereverless Framework와 같은 프레임워크를 학습을 권장.
모니터링이 어렵다.
그러나 수 많은 단점에도 운영이 필요 없다는 점은 모든 단점을 상쇄 시킬 수 있으며, 서버리스의 지속적인 발전으로 인해 단점들을 조금씩 해소하고 있다. 가령 서버리스 초창기 가용할 수 있는 리소스가 메모리 1GiB 정도 수준이었다면 현재는 10GiB 이상을 사용할 수 있으며, 콜드스타트도 점차 안정화 되고 있는 듯 하다.
- 일반적인 서버리스 유즈케이스는?
1. 보통은 이벤트 트리거(EventBridge, S3, SQS 등) 형태로 Lambda를 많이 구성한다.
1-1) EventBridge - Lambda(CronJob 등)
1-2) S3 - Lambda(썸네일 혹은 데이터전처리 등)
1-3) SNS/SQS - Lambda(데이터 전처리, 프로세싱 등)
2. 하지만 웹 서비스/Rest API 서비스도 가능하다.
https://blogs.itemis.com/en/creating-serverless-applications-on-aws
2-1) S3에 있는 정적페이지에 접근하고,
2-2) Cognito를 통해 인증을 받은 뒤,
2-3) API Gateway로 HTTP(GET/POST 등) 요청을 보내고,
2-4) Lambda를 통해 사용자 요청을 처리하고,
2-5) DynamoDB 데이터를 저장한다.
- 모니터링 방안은?
CloudWatch Lambda Insight를 통해 Lambda 리소스 모니터링이 가능하다. Invocation, Duration 등 다양한 정보를 확인할 수 있다.
개별 Lambda Function에 대한 성능 모니터링
(Invocation&Error, Duration, Throttles, Memory, CPU, Network, Incvocation 별 리소스 사용률)


전체 Lambda Function에 대한 성능 모니터링
(Function Cost: ms 기준 메모리 사용량, Duration, Invocations, Error, Memory, Network 등)

개별 펑션에 대한 전반 리소스 사용 정보(Cold starts, memory, cpu, network)

기존 Lambda Stdout 로그와 별개로 인프라 레벨의 모니터링을 로깅해준다.

이를 통해 쿼리를 만들고, 각 Lambda 함수 별 콜드스타트를 확인할 수도 있다.

APM의 경우 약간은 불편하지만 AWS X-Ray를 이용하면 가능하다. 각 API Gateway 호출에 따른 Lambda 수행 및 DB 경로까지 알 수 있으며 Latency도 확인할 수 있다.
Lambda Insight & X-Ray 비용은? (매월 100만 번 호출 기준)
CloudWatch Lambda Insight: $2.4(지표) + $0.52(로그) = $2.92
CloudWatch Logs($0.5/1GB) = $2(4KB 로그 100만개 기준)
X-Ray Insight: $1
X-Ray 트레이스: $5
월 예상 비용 $11
추가 비용
X-Ray 스캔/검색: $0.5 + $0.5 (스캔/검색 수행마다 달라짐)
대시보드: $3(1개당)
그 외 알람 체계를 구축(SNS 등) 추가 비용이 발생
Datadog Serverless 비용은? (매월 100만 번 호출 기준)
Datadog 서비스 워크로드 모니터링: $5
Datadog 로그: $1.7
Datadog 서버리스 APM: $10
월 예상 비용 = $17
기본적으로는 Datadog의 비용이 더 높지만, 추가 비용 및 로그양에 따라 차이가 있을 것으로 예상된다.
- 그럼에도 Datadog이 서버리스 모니터링에 대한 강점은 무엇일까?
1. 태그를 이용하여 Lambda Function을 서비스 단위로 직관적인 뷰
2. Datadog의 쉽고 빠른 Log 매니지먼트 기능
3. 불친절한 AWS의 X-Ray 보다 편리한 UI, 특히 서비스 단위로 Lambda이 가능하고, 예상 비용과 콜드스타트까지 쉽게 모니터링 가능
4. Infra, APM, Log 3필라를 통해 서버리스 서비스 이슈를 더 편리하고, 빠르게 확인할 수 있다.
(X-Ray의 경우에도 APM과 LOG는 연계 되어 있음)

5. 머신러닝을 활용한 다양한 모니터링 임계치 설정 및 손쉬운 알람 설정

6. 모니터링의 통합
사실 서버리스만으로 대규모 서비스를 운영하는 것은 불가능하다. 따라서 모니터링 통합을 위해서도 Datadog 사용을 권장한다.
- 서버리스 데이터독 모니터링 기본적인 구성 매커니즘
기존 데이터독 모니터링 매커니즘과 비슷한데, 서버리스의 경우 Agent 프로세스를 실행할 수 없으므로 별도의 서버리스 Lambda Layer를 사용한다. 서버리스 개발팀도 별개로 존재한다고 한다.
Lambda Layers에 Datadog Layer를 추가
Lambda Handler를 Datadog hendler로 변경

환경변수에 Datadog 관련 환경변수 설정
기본적인 Datadog 구성은 위와 같고 서버리스 프레임워크 등 사용자 환경에 따라 다양한 방법을 지원한다.
(서버리스계의 테라폼이 되고 있는 서버리스 프레임워크를 추천)

기존 Datadog APM의 경우 널리 쓰이는 framework 혹은 lib들을 통합하여 Trace를 생성했다면, 서버리스의 경우 Lambda의 boto 등 lib와 event를 기준으로 Trace를 생성한다.
- DataDog Serverless compatibility(Lambda 기준)
Amazon API Gateway, SNS, SQS, DynamoDB, S3, EventBridge, Kinesis
- 별첨. 서버리스 Datadog lib를 확인해보자.
Q. EventBridge에서 SQS를 거치고 Lambda에서 해당 SQS를 폴링하는데, 이것도 모니터링이 가능할까?
A. EventBridge의 경우 EventBridge → Lambda 의 형태만 지원한다. 따라서 불가능하다.
따라서 위 경우는 한 번에 아래 프레임그래프를 확인 불가능하고 아래와 같이 프레임그래프가 나눠진다.
API G/W - EventBridge 구간 1
EventBridge - DynamoDB 구간 2
(X-Ray도 해당 구성을 하나의 프레임그래프로는 지원하지 않는다ㅜㅜ)
그럼 실제 원인을 찾기 위해 소스코드를 확인해보자.
https://github.com/DataDog/datadog-lambda-python
Lamda 레이어에서는 아래와 같은 명령어를 통해 Pulbic Lambda 레이어를 확인할 수 있다.
$URL=$(aws lambda get-layer-version-by-arn --arn arn:aws:lambda:ap-northeast-2:464622532012:layer:Datadog-Python39:52 --query Content.Location --output text)
$curl $URL
코드를 보면 Event Bridge의 경우 현재 EventBridge에서 바로 Lambda로 Input 할 경우만 트레이스를 확인할 수 있다. Event의 detail-type 어튜리뷰트가 있을 경우에만 Datadog 서버리스 APM이 트리거 된다.
EventBridge -> SQS -> Lambda 방식으로 Input이 전달된다면 Lambda는 SQS의 이벤트만을 인식하기 때문에 EventBridge는 끊기게 되는 것이다.
실제로 테스트 해보면 아래와 같이 프레임그래프가 나눠지게 된다.

EventBridge에서 바로 Lambda로 보내는 Event를 보면 아래와 같다. 아래와 같이 detail-type이나 detail 어티리뷰트가 있는 것을 알 수 있다.

그러나 EventBridge -> SQS -> Lambda의 경우 아래와 같은 Event가 발생된다. 따라서 Datadog은 해당 Event를 제대로 인식하지 못하고, EventBridge와 SQS 각각의 인풋으로 인식한다.

하지만 위 프레임그래프를 보면 SNS -> SQS -> Lambda의 형태는 Datadog에서 지원한다.
그럼 어쩌면.... EventBridge -> SQS -> Lambda 형태도 가능하지 않을까?
그럼 다시 소스코드를 확인해보자.
tracing.py 200번 라인에 SQS Event 발생 시 어트리뷰트에서 SNS을 확인하고 Trace, Span, Parent ID 등 프레임그래프를 위한 정보를 넣어주는 펑션을 확인할 수 있다.

그럼 어쩌면... 해당 펑션을 수정하면 가능하지 않을까?
해당 펑션에 EventBridge 관련 어트리뷰트를 서칭하는 조건문을 추가했다.
위와 같이 tracing.py 내의 몇 가지 펑션들을 수정한다.
(extract_context_from_sqs_or_sns_event_or_context, create_inferred_span_from_sqs_event, create_inferred_span_from_eventbridge_event)
성공....
완벽하게 events. put command와 eventbridge 생성을 바로 엮기에는 boto를 후킹하는 부분까지 수정이 필요해보이지만, 해당 방법을 통해 하나의 트레이스 내에서 Lambda -> EventBrdige 요청까지 확인할 수 있다.