🔥 Alarm: 임계값을 걸고 알림을 받는 법
강의 목차

임계값 하나만 잘 걸면 알람은 자기 일을 한다고 생각했다. 콘솔에서 알람을 만들 때 그 가정이 한 화면에서 어긋난다. 임계값 입력란은 폼 가운데에 한 줄이고, 그 아래에 'Configure actions' 두 묶음과 'Additional configuration: Treat missing data as' 한 줄이 따로 적혀 있다. 셋을 다 고르고 나야 알람은 한 결심이 된다.
CloudWatch란 무엇인가: AWS 모니터링의 중심 도구에서 알람의 세 상태(OK / ALARM / INSUFFICIENT_DATA)와 M-of-N 윈도를 한 줄로 정의했고, Metric: 숫자 하나가 찍히는 과정에서는 알람의 입력이 되는 좌표 키(namespace × MetricName × Dimensions)와 자동 다운샘플을 풀어 썼다. 그 한 줄들은 새벽 3시에 알람이 울거나 울지 않는 결과로 직결한다.
ComparisonOperator + M/N: 7종 비교와 윈도
알람의 입력은 PutMetricAlarm 한 호출이다. 이 호출이 받는 ComparisonOperator는 일곱 가지인데, 임계값 비교 네 가지와 동적 밴드 비교 세 가지로 나눈다.
임계값 네 가지는 직관적이다. GreaterThanThreshold, GreaterThanOrEqualToThreshold, LessThanThreshold, LessThanOrEqualToThreshold. 한 숫자(threshold)와 메트릭 값을 비교한다. 동적 밴드 세 가지는 정적 임계값이 아니라 모델이 그어 둔 신뢰밴드와 비교한다. LessThanLowerThreshold, GreaterThanUpperThreshold, LessThanLowerOrGreaterThanUpperThreshold. 이 셋은 Anomaly Detection 알람에서만 의미가 있고, 뒤에서 다시 본다.
비교가 한 번 일어나는 단위가 period다. period 안의 점들은 Metric: 숫자 하나가 찍히는 과정에서 본 통계(SampleCount/Sum/Min/Max/Average/Percentile)로 모이고, 그 모인 한 숫자를 임계값과 비교해 한 데이터포인트의 상태(breaching / not breaching)를 정한다. 그 데이터포인트들은 가장 최근 evaluation periods(N) 만큼 누적되고, 그중 datapoints to alarm(M) 개 이상이 breach면 알람은 ALARM으로 간다. M의 위치는 N 안 어디든 좋고, 연속이 아니어도 된다.
5분 period × 5 evaluation periods × 3 datapoints to alarm이라는 알람은 한 마디로 이렇다. 최근 25분 윈도 안에 breach 점이 3개 이상이면 ALARM, 그 밑이면 OK. 1분 period × 1 × 1로 쓰면 가장 즉각적이지만 한 점만 흔들려도 알람이 운다. M < N으로 쓰는 이유다. false alarm을 줄이려고 비례 다수결 방식을 쓴다.

상태 전이는 단순하다. M개가 breach면 OK → ALARM, M개 미만이면 ALARM → OK. 데이터가 부족할 때 어느 쪽으로 가는지는 단순하지 않고, 다음 절의 TreatMissingData 모드가 그 결정을 한다. 알람의 결심이 보는 윈도는 period × evaluation periods 길이만큼이라, 위 5분 period × 5 evaluation periods 알람 기준으로 25분이 그 입구다. 그보다 더 오래된 점은 결심의 입력이 아니다.

TreatMissingData: 메트릭이 빠지면 어떻게 되는가
여기까지는 데이터가 있을 때의 그림이다. 실제 운영에서는 데이터가 빠지는 상황이 더 자주 등장한다. 메트릭을 푸시하는 서비스가 잠깐 죽거나, 트래픽 자체가 0이라 PutMetricData 호출이 일어나지 않거나. 이 상황을 결정하는 옵션이 TreatMissingData다. 네 가지 모드가 있고 기본값은 missing이다.
missing(기본): 빠진 점은 평가에서 빼고, 결과적으로 점이 충분히 모자라면 INSUFFICIENT_DATA로 간다.notBreaching: 빠진 점은 OK 쪽으로 친다. 에러가 났을 때만 점이 찍히는 커스텀 에러 카운터처럼, 점이 없다는 게 좋은 신호인 메트릭에 맞다.breaching: 빠진 점은 ALARM 쪽으로 친다. 항상 데이터가 와야 하는 메트릭에 맞는 결심이다. 점이 멈춘 게 곧 사고인 경우.ignore: 알람의 현재 상태를 유지한다. OK였으면 OK로, ALARM이었으면 ALARM으로 머문다.
기본값이 missing이라 알람을 만들고 따로 설정 안 하면 트래픽이 잠깐 멈춘 구간에서 알람이 INSUFFICIENT_DATA로 머문다. CloudWatch란 무엇인가: AWS 모니터링의 중심 도구에서 짚은 그 사례, period가 메트릭 푸시 간격보다 짧아도 같은 정체가 생긴다. 새벽 3시에 알람이 한 번도 안 운 흔한 사고의 절반이 이 단계에서 시작한다. 임계값을 잘 잡았다고 안심하면 안 된다.
한 가지 주의가 있다. 모드 설정이 어떤 점에든 적용되는 게 아니다. CloudWatch는 평가 윈도보다 조금 더 많은 점을 끌어와 보고, 실제 점이 N개 이상이면 missing data 처리 자체를 호출하지 않는다. 모드는 점이 모자랄 때만 일을 한다.

Composite Alarm + Anomaly Detection: 임계값 하나로 못 잡는 경우
임계값 하나로 못 잡는 경우가 두 갈래로 나뉜다. 하나는 알람이 너무 많이 우는 경우. CPU 알람 1개, 메모리 알람 1개, 네트워크 알람 1개를 다 걸어두면 한 호스트가 흔들릴 때 셋이 동시에 운다. 두 번째는 임계값을 정하기 어려운 경우. 트래픽이 시간대에 따라 자연스럽게 출렁이는 메트릭은 한 숫자로 끊을 수 없다.
첫 번째 경우에 Composite Alarm이 있다. 2020년 3월 GA. 일반 알람 여러 개를 AlarmRule 표현식으로 묶어 하나의 알람으로 본다 (PutCompositeAlarm). 표현식이 받는 함수는 ALARM("이름") (그 알람이 ALARM일 때 TRUE), OK(...) (OK일 때 TRUE), INSUFFICIENT_DATA(...) (데이터 부족일 때 TRUE), 상수 TRUE / FALSE까지 다섯 가지가 기본이다. 자식 알람 N개 중 M개 이상이 한 상태일 때 TRUE를 만드는 AT_LEAST(M, <state-condition>, (alarm1, alarm2, ...)) 함수도 따로 받는다. 이걸 AND, OR, NOT과 괄호로 묶고, 한 표현식 안 요소는 500개까지.
ALARM("api-high-errors") AND (ALARM("api-high-cpu") OR ALARM("api-high-memory"))ALARM("api-high-errors") AND (ALARM("api-high-cpu") OR ALARM("api-high-memory"))이 한 줄이 구분하는 결정은 명확하다. 에러율이 같이 튀어야 ALARM이 되고, CPU나 메모리만 흔들리면 운영팀이 한 번 더 보고 결심하면 된다. 알람 fatigue가 줄어든다.
두 번째 경우에 Anomaly Detection이 있다. 2019년 10월 GA. 정적 임계값 대신 모델이 메트릭의 시간 패턴을 학습해 동적 신뢰밴드를 계산한다. 이 밴드 위에서 알람을 걸면 위 세 가지 동적 비교가 의미를 갖는다. GreaterThanUpperThreshold(밴드 위로 튐), LessThanLowerThreshold(밴드 아래로 빠짐), LessThanLowerOrGreaterThanUpperThreshold(양쪽 어느 쪽이든 벗어남). 임계값 입력에 들어가는 숫자는 몇 표준편차의 밴드를 그릴지의 폭이다. 큰 숫자는 밴드를 넓혀 알람을 덜 울리게, 작은 숫자는 밴드를 좁혀 더 예민하게 만든다.

SNS fan-out + Subscription Filter Policy
알람이 ALARM 상태로 가면 PutMetricAlarm 시 받아둔 세 종 액션 리스트(AlarmActions, OKActions, InsufficientDataActions)에 등록된 ARN을 발화한다. 이 ARN으로 가장 흔한 대상이 Amazon SNS Topic이다. SNS Topic에 한 번 publish하면 거기 붙은 모든 subscription으로 fan-out한다.
SNS subscription protocol은 9가지다. 운영에서 자주 닿는 종류가 다섯이다. Email(주소), SMS(번호), Lambda(함수 ARN), HTTP/HTTPS(웹훅 URL), SQS(큐 ARN). 그 외에 email-json, application(모바일 푸시), firehose까지 받는다. 가격은 endpoint마다 다르다. SQS와 Lambda는 메시지당 별도 전달 요금이 없고(SNS publish 호출 비용과 data transfer 요금은 별개로 계산한다), HTTP/HTTPS와 Email은 건수에 따라 과금한다. SMS는 국가와 통신사에 따라 단가가 다르고 자주 바뀌니, 알람의 SMS endpoint를 띄울 때는 공식 SMS 가격 페이지를 그날 한 번 보고 들어가는 게 깔끔하다.
CloudWatch 알람은 SNS의 Standard topic과 FIFO topic을 모두 액션 대상으로 받는다. FIFO topic은 메시지 순서를 보장하지만 공식 문서는 드물게 알람 알림이 순서가 어긋날 수 있다고 분명히 적어 두었다. 알람 자체가 1초 단위 정밀 순서를 요구하는 경우는 적기 때문에 대개는 Standard로 충분하다.
한 Topic을 여러 알람이 공유할 때 받는 쪽에서 분기가 필요하다. SNS의 Subscription Filter Policy가 그 역할이다. 각 subscription에 JSON 정책을 붙여 메시지 attribute나 메시지 body로 거른다. CloudWatch 알람 알림의 AlarmName은 메시지 body에 들어 있어서, 알람 이름 prefix(prod-, dev-)로 분기하려면 FilterPolicyScope를 MessageBody로 두는 한 줄이 더 필요하다. 이 한 줄까지 적어 두면 한 Topic을 환경별, 서비스별로 쪼개지 않고 정책 하나로 분기할 수 있다.

Slack 직결 두 경로: Chatbot vs Lambda webhook
운영팀이 받는 채널은 점점 이메일이 아니라 Slack이다. SNS에서 Slack으로 가는 길은 두 갈래다.
첫째, AWS Chatbot. 2025년 2월 19일에 'Amazon Q Developer in chat applications'로 이름이 바뀌었지만 서비스 endpoint, IAM 권한, API, Region 가용성은 그대로다. SNS Topic 하나를 Slack 워크스페이스의 채널 하나에 매핑하면 끝. 메시지 포맷, OAuth 흐름, AWS CLI 호출 같은 인터랙티브 동작까지 AWS가 관리한다. 코드를 한 줄도 안 짜고 Slack에서 알람을 받고 싶을 때의 기본값이다.
둘째, Lambda를 SNS subscription으로 붙이고 그 Lambda가 Slack의 Incoming Webhook URL로 POST하는 길. AWS-managed가 아닌 만큼 SNS 메시지 형태를 원하는 형식으로 바꿀 수 있고, 알람 메시지에 부가 정보(서비스 메트릭 링크, 런북 URL, 담당자 멘션 <@U1234>)를 한 줄씩 더 붙일 수 있다. Chatbot이 안 잡아주는 메시지 가공이 필요할 때의 길.
두 길은 서로를 대체하지 않는다. 빠르게 띄울 때는 Chatbot, 우리 팀 워크플로우에 맞춰 메시지 형식을 매번 바꿀 때는 Lambda webhook.

결정은 임계값이 아니라 한 묶음의 결심에서 나뉜다
알람의 가격은 한 줄로 깔리지 않는다. 공식 가격 페이지 US East 예시로, 표준 해상도 알람 메트릭 한 개가 월 $0.10, Composite Alarm은 $0.50. 고해상도(10초, 30초 period) 알람은 표준의 세 배 단가다. Anomaly Detection 알람은 본 메트릭과 상하 밴드 두 개를 같이 평가해 한 알람이 알람 메트릭 3개 분량을 차지하고, 결과적으로 표준 한 개의 세 배인 $0.30이다. 여기에 SNS publish 요청 비용과 endpoint 전달 비용을 더한다. CloudWatch란 무엇인가: AWS 모니터링의 중심 도구에서 짚은 무료 한도 표준 해상도 알람 10개를 넘으면 청구서가 자란다 (서울 region은 calculator로 따로 본다).
마지막으로 알람이 하지 않는 일을 하나 짚는다. 알람은 한 상태 변화의 emit이지 incident routing이 아니다. 누구를 깨울지, 응답이 안 오면 누구를 다음 차례로 깨울지, 알람이 정상으로 돌아오면 어떻게 ack를 닫을지는 PagerDuty, Opsgenie, SSM Incident Manager가 맡는다. SNS Topic을 그쪽으로 한 번 더 라우팅해 두는 게 깔끔한 배치. 알람 자체가 다 해 줄 거라 기대하면 새벽 3시에 한 번 운 알람이 4시까지도 그대로 떠 있는 사례를 만난다. 관리형이라는 단어 한 줄에 깔린 한계 중 하나다.
참고 자료
- Amazon CloudWatch Alarms User Guide: 알람 모델과 콘솔 사용법
- PutMetricAlarm: API Reference: ComparisonOperator, EvaluationPeriods, DatapointsToAlarm 정의
- Configuring how CloudWatch alarms treat missing data: TreatMissingData 4 모드 정의
- Combining alarms (Composite Alarm): AlarmRule 표현식 문법과 GA 시점
- Using CloudWatch anomaly detection: 동적 밴드 모델과 표준편차 폭
- SNS Subscribe API: protocol values: 9 protocol 정의와 endpoint 형식
- AWS Chatbot rename announcement: Amazon Q Developer in chat applications 호환성 안내
- Amazon CloudWatch Pricing: 알람 단가, Composite, Anomaly, 고해상도 단가












