학습 목표

시나리오

실습 2의 웹 티어를 감시합니다. 알리고 싶은 상황은 셋입니다.

마지막 조건이 복합 알람의 이유입니다. 개별 알람은 기록을 남기고, 사람을 부르는 것은 복합 알람만 하게 만듭니다.

아키텍처 개요

구성 요소와 역할
구성 요소 역할
SNS 주제(운영) 기록용 알림. 채팅이나 티켓 시스템으로 보낸다
SNS 주제(호출) 사람을 부르는 알림. 복합 알람만 연결한다
지표 알람 지표가 임계값을 넘는지 평가
로그 지표 필터 로그 패턴 발생 횟수를 지표로 변환
복합 알람 여러 알람의 조합을 하나의 조건으로 평가

구성 단계

1 · SNS 주제와 구독

create-topics.sh — 기록용과 호출용 주제를 나눠 생성 (주소는 예시입니다)
OPS_TOPIC=$(aws sns create-topic --name lab12-ops \
  --query 'TopicArn' --output text)

PAGE_TOPIC=$(aws sns create-topic --name lab12-page \
  --query 'TopicArn' --output text)

aws sns subscribe \
  --topic-arn "$OPS_TOPIC" \
  --protocol email \
  --notification-endpoint ops@example.com

aws sns subscribe \
  --topic-arn "$PAGE_TOPIC" \
  --protocol email \
  --notification-endpoint oncall@example.com

# 구독은 확인 절차를 거쳐야 활성화됩니다.
aws sns list-subscriptions-by-topic \
  --topic-arn "$OPS_TOPIC" \
  --query 'Subscriptions[].[Protocol,Endpoint,SubscriptionArn]' \
  --output table

2 · 지표 알람

create-target-alarm.sh — 정상 대상 수 알람 (차원 값은 실습 2의 리소스에서 가져옵니다)
aws cloudwatch put-metric-alarm \
  --alarm-name lab12-healthy-hosts-low \
  --alarm-description "정상 대상 수가 기준 아래로 떨어졌습니다" \
  --namespace AWS/ApplicationELB \
  --metric-name HealthyHostCount \
  --dimensions Name=TargetGroup,Value=targetgroup/lab02-tg/0123456789abcdef \
               Name=LoadBalancer,Value=app/lab02-alb/0123456789abcdef \
  --statistic Minimum \
  --period 60 \
  --evaluation-periods 3 \
  --datapoints-to-alarm 2 \
  --threshold 2 \
  --comparison-operator LessThanThreshold \
  --treat-missing-data breaching \
  --alarm-actions "$OPS_TOPIC" \
  --ok-actions "$OPS_TOPIC"
알람 평가를 결정하는 설정
설정 의미 정하는 기준
--period 데이터 포인트 하나의 시간 폭 지표가 실제로 게시되는 주기보다 짧게 잡지 않는다
--evaluation-periods 평가에 사용할 데이터 포인트 수 순간적인 튐에 반응하지 않을 만큼
--datapoints-to-alarm 그중 몇 개가 위반이면 경보로 갈지 "3개 중 2개"처럼 완화된 조건을 만들 때 쓴다
--statistic 기간 안의 값을 어떻게 요약할지 가용성 지표는 Minimum, 부하 지표는 Average가 흔하다
--treat-missing-data 데이터가 없을 때의 취급 아래 표 참조
누락 데이터 처리 방식
값 동작 쓰는 상황
missing (기본) 해당 데이터 포인트를 평가에서 제외 지표가 간헐적으로만 게시되는 경우
notBreaching 정상으로 간주 데이터가 없는 것이 곧 무부하인 경우
breaching 위반으로 간주 지표가 끊긴 것 자체가 이상인 경우
ignore 현재 상태를 유지 상태가 흔들리는 것을 피하고 싶을 때

위 예시에서 breaching을 고른 이유는, 정상 대상 수 지표가 사라지는 상황이 대상 그룹 자체의 문제일 수 있기 때문입니다. 데이터가 없다고 안심하면 장애를 놓칩니다.

3 · 로그 지표 필터

create-metric-filter.sh — 오류 로그를 지표로 변환
aws logs put-metric-filter \
  --log-group-name /app/lab12 \
  --filter-name lab12-error-count \
  --filter-pattern '?ERROR ?Exception' \
  --metric-transformations \
      metricName=AppErrorCount,metricNamespace=Lab12/App,metricValue=1,defaultValue=0

aws cloudwatch put-metric-alarm \
  --alarm-name lab12-error-spike \
  --alarm-description "애플리케이션 오류 로그가 급증했습니다" \
  --namespace Lab12/App \
  --metric-name AppErrorCount \
  --statistic Sum \
  --period 60 \
  --evaluation-periods 5 \
  --datapoints-to-alarm 3 \
  --threshold 20 \
  --comparison-operator GreaterThanThreshold \
  --treat-missing-data notBreaching \
  --alarm-actions "$OPS_TOPIC"

4 · 복합 알람

create-composite-alarm.sh — 두 조건이 모두 성립할 때만 호출
aws cloudwatch put-composite-alarm \
  --alarm-name lab12-service-degraded \
  --alarm-description "용량 부족과 오류 급증이 동시에 발생했습니다" \
  --alarm-rule "ALARM(lab12-healthy-hosts-low) AND ALARM(lab12-error-spike)" \
  --alarm-actions "$PAGE_TOPIC" \
  --ok-actions "$PAGE_TOPIC"

규칙에는 ALARM(), OK(), INSUFFICIENT_DATA()와 AND, OR, NOT을 쓸 수 있습니다. 배포 중에는 알림을 억제하는 동작 억제기도 지정할 수 있어, 계획된 작업 때문에 사람이 불려 나가는 일을 막을 수 있습니다.

검증 방법

verify.sh — 알람 상태와 이력 확인
aws cloudwatch describe-alarms \
  --alarm-names lab12-healthy-hosts-low lab12-error-spike \
  --query 'MetricAlarms[].[AlarmName,StateValue,StateReason]' \
  --output table

aws cloudwatch describe-alarms \
  --alarm-types CompositeAlarm \
  --query 'CompositeAlarms[].[AlarmName,StateValue,AlarmRule]' \
  --output table

aws cloudwatch describe-alarm-history \
  --alarm-name lab12-healthy-hosts-low \
  --max-records 5 \
  --query 'AlarmHistoryItems[].[Timestamp,HistoryItemType,HistorySummary]' \
  --output table

알람을 일부러 울려 본다

알림 경로가 실제로 동작하는지는 울려 봐야 압니다. 상태를 강제로 바꾸면 지표를 건드리지 않고도 경로를 확인할 수 있습니다.

test-alarm.sh — 상태를 강제로 바꿔 알림 전달 확인
aws cloudwatch set-alarm-state \
  --alarm-name lab12-error-spike \
  --state-value ALARM \
  --state-reason "알림 경로 점검"

# 사용자 지정 지표에 값을 직접 넣어 실제 평가를 확인할 수도 있습니다.
aws cloudwatch put-metric-data \
  --namespace Lab12/App \
  --metric-name AppErrorCount \
  --value 50

# 확인이 끝나면 되돌립니다. 다음 평가 주기에 실제 상태로 복귀합니다.
aws cloudwatch set-alarm-state \
  --alarm-name lab12-error-spike \
  --state-value OK \
  --state-reason "점검 완료"
검증 항목과 통과 기준
항목 통과 기준
구독 확인 구독 ARN이 PendingConfirmation이 아니다
알림 전달 상태를 ALARM으로 바꾸면 메일이 온다
복구 알림 OK로 돌아올 때도 알림이 온다
복합 알람 한쪽만 경보일 때는 호출 주제로 알림이 가지 않는다
로그 지표 패턴이 없을 때도 0이 게시된다

비용 고려

요금이 발생하는 항목
항목 성격
알람 알람 개수. 고해상도 알람은 별도로 계산된다
사용자 지정 지표 지표 개수. 차원 조합마다 별도의 지표가 된다
로그 수집과 저장 수집량과 보존 기간
SNS 게시와 전달 수
대시보드 대시보드 개수

비용이 예상보다 커지는 원인은 대개 차원 조합입니다. 사용자 지정 지표에 인스턴스 ID나 요청 ID처럼 값이 많은 차원을 넣으면 지표 수가 폭증합니다. 그리고 로그 보존 기간을 지정하지 않으면 무기한 쌓입니다.

프로덕션 고려사항

정리 — 리소스 삭제

cleanup.sh — 복합 알람부터 순서대로 삭제
aws cloudwatch delete-alarms --alarm-names lab12-service-degraded
aws cloudwatch delete-alarms --alarm-names lab12-healthy-hosts-low lab12-error-spike

aws logs delete-metric-filter \
  --log-group-name /app/lab12 \
  --filter-name lab12-error-count

aws sns delete-topic --topic-arn "$OPS_TOPIC"
aws sns delete-topic --topic-arn "$PAGE_TOPIC"

# 실습용 로그 그룹도 정리합니다.
aws logs delete-log-group --log-group-name /app/lab12

자주 하는 실수

자주 나오는 실수와 증상
실수 증상 고치는 법
구독을 확인하지 않음 알람은 울리는데 메일이 오지 않는다 수신함에서 확인 링크를 누른다
차원을 빠뜨리거나 잘못 지정 알람이 계속 INSUFFICIENT_DATA다 지표의 실제 차원 이름과 값을 조회해 맞춘다
평가 기간이 지표 게시 주기보다 짧음 데이터가 없어 평가되지 않는다 게시 주기에 맞춰 --period를 정한다
누락 데이터 처리를 기본값으로 방치 지표가 끊긴 장애를 놓친다 지표 성격에 맞게 breaching 등을 지정한다
EC2 메모리 지표를 기본으로 기대 지표가 존재하지 않는다 CloudWatch 에이전트를 설치한다
평가 기간을 1로 두고 민감하게 설정 순간적인 튐마다 알림이 온다 평가 기간과 데이터 포인트 조건을 조정한다
모든 알람을 호출 주제에 연결 알림 피로로 아무도 보지 않게 된다 복합 알람으로 호출 조건을 좁힌다
로그 보존 기간 미설정 로그가 무기한 쌓인다 로그 그룹마다 보존 기간을 지정한다

이어서 볼 곳

공식 문서 출처