PCA — 프로메테우스 인증 어소시에이트 · 규칙 회귀 시험: 초록불의 판별력 · 이론
없는 측정과 늦게 울리는 경보
한 줄 요약
값이 0인 것, 지금 선택할 표본이 없는 것, 새 표본이 오지 않은 것은 서로 다릅니다.
경보가 조건을 처음 만족한 pending 상태와 실제 firing 상태도 구분해야 합니다.
이번 실습은 그 차이가 경보의 대기 시간을 어떻게 바꾸는지 가상 시간의 실제 규칙 시험으로
검증합니다. 경보가 firing이라는 사실을 알림 메일이 전달됐다는 주장으로 넓히지 않습니다.
왜 이게 필요했나
“데이터가 없으면 0으로 채우면 그래프가 깔끔해진다”는 수정은 보고서를 보기 좋게 만들 수
있지만, 사라진 측정을 실제 무요청으로 바꿔 말할 위험도 있습니다. 결제 서비스에 요청이
없었던 것과 익스포터가 결제 counter를 더 이상 제공하지 않는 것은 대응 방법부터 다릅니다.
앞의 경우에는 수요를 분석하고, 뒤의 경우에는 계측과 수집 경로를 확인해야 합니다.
경보도 숫자 하나의 비교만으로 끝나지 않습니다. 조건이 잠시 충족됐다가 사라졌는데 이전
대기 시간을 계속 합산하면 너무 일찍 울릴 수 있습니다. 반대로 데이터를 빠뜨린 시험에서
조건이 사라졌다고 가정했지만 실제 엔진은 이전 표본을 선택한다면, 예상과 달리 경보 대기가
계속될 수 있습니다. 시간 축이 들어가는 동작은 설명을 읽는 것만으로 확신하지 말고 사건을
앞뒤로 배치한 시험에서 확인해야 합니다.
어떻게 동작하나
이 실습에는 route마다 두 개의 입력 시계열이 있어야 한다는 한정된 약속이 있습니다.
기본 rate 규칙에 현재 선택되는 시계열 수가 2인 route만 남기는 보호 조건을 붙입니다.
모든 서비스에 인스턴스를 반드시 두 개만 두라는 권장 사항이 아닙니다. 이 실습에서는
현재 시계열 수와 표본의 존재를 비교하는 작은 장치로 사용합니다.
명시적인 stale 표식을 넣은 시나리오에서는 /checkout의 b가 현재 선택 결과에서 사라집니다.
6분 시점의 count는 1입니다. 보호 조건을 제거하면 오래된 범위 표본으로 계산한 요청률이
계속 나올 수 있지만, 보호된 rate에는 /checkout 표본이 없습니다. /status의 두 인스턴스와
값 2는 그대로 남습니다. 이것은 전역 빈 벡터가 아니라 한 경로의 정보 부족입니다.
반면 실제 무요청 사례에서는 a와 b의 counter가 계속 0으로 관측됩니다. 현재 시계열 수는
2이고 보호된 요청률은 0입니다. 기대 표본을 빈 목록으로 적으면 이 정상 상태를 잘못
거절하게 됩니다. 시험에서 없음을 검사할 때는 해당 라벨 집합이 결과에 없음을, 0을
검사할 때는 해당 라벨 집합이 존재하며 값이 0임을 각각 적어야 합니다.
누락 표본과 stale 표식은 같은 입력이 아니다
시험의 values에서 _는 그 위치에 표본이 없다는 표시이고 stale은 시계열의 낡음을
명시하는 표식입니다. 실험에서 b의 6분 표본만 _로 두면 엔진은 5분의 직전 표본을
선택했습니다. 6분의 표본 나이는 60초, 현재 시계열 수는 여전히 2, 보호된 rate는 11입니다.
같은 위치를 stale로 바꾸면 보호된 /checkout 결과가 사라집니다.
이 차이는 최신값 선택이 매 평가 시각에 반드시 새 표본을 요구하지 않기 때문에 생깁니다.
lookback 안의 직전 표본이 선택될 수 있습니다. 따라서 count가 2라는 사실은 두 입력의
현재 신선도가 충분하다거나 실제 scrape가 방금 성공했다는 보증이 아닙니다. 인스턴스의
신원도 count만으로 확인할 수 없습니다. 운영 판정이라면 기대 대상 목록과 수집 상태,
표본 나이에 대한 별도 약속을 설계해야 합니다. 이번 단원은 그 약속까지 구현했다고
주장하지 않고, 단순 count 보호 조건의 한계를 학생이 보고하게 합니다.
또한 실제 HTTP scrape 실패가 항상 단위 시험의 _와 똑같이 처리된다고 일반화하면
안 됩니다. 실제 수집기는 상황에 따라 stale 표식을 생성하며 대상 제거와 타임스탬프
설정에도 별도 의미가 있습니다. 여기서는 이미 준비한 시계열을 규칙 엔진에 넣습니다.
실제 네트워크 수집의 검증은 앞 단원의 독립 Prometheus 실험과 구분합니다.
경보 대기 시간을 앞뒤에서 검사한다
경보 PcaHighRequestRate는 보호된 rate가 10.5보다 큰 상태가 for: 2m 동안
이어져야 firing이 되도록 설계합니다. 평가 간격은 1분입니다. 정상 입력의 실제 결과는
5분 pending, 6분 pending, 7분 firing입니다. 임계값을 처음 넘은 시각과 발화 시각을
같이 검사해야 for를 지운 규칙도 알아낼 수 있습니다. 7분의 firing만 검사하면 더 일찍
울린 규칙도 그 시각에는 firing이므로 잘못된 구현을 통과시킬 수 있습니다.
경보 대기 도중인 6분에 stale을 넣으면 조건이 사라집니다. 7분에 입력이 복귀해도 곧바로
firing이 되지 않고 다시 pending이 시작됩니다. 8분에도 pending이며 9분에 firing입니다.
반대로 6분에 표본 하나만 누락시킨 사례는 직전 표본의 선택으로 조건이 계속 유지되어
7분에 firing입니다. 학생 시험에는 두 시나리오가 모두 있어야 합니다.
alert_rule_test는 지정한 시각의 firing 경보를 비교합니다. firing이 없다는 기대만으로는
pending과 완전한 비활성 상태를 구별할 수 없습니다. 그래서 promql_expr_test에서
ALERTS의 alertstate 라벨도 함께 검사합니다. 6분의 stale 사례는 ALERTS 표본이 없고,
단순 표본 누락 사례는 pending 표본이 있습니다. “아직 안 울렸다”는 한 문장보다
훨씬 강한 시간 축의 계약이 됩니다.
현장에서 만나는 모습
경보 리뷰에서는 발화 이후의 한 장면만 캡처하지 않습니다. 임계값을 넘기 직전, 처음
넘긴 때, 대기 중, 발화 경계, 데이터 결손과 복귀를 따로 시험합니다. for를 1분으로
줄이거나 3분으로 늘린 변이도 각각 너무 이른 발화와 너무 늦은 발화로 검출되어야 합니다.
경보가 너무 시끄러워서 무작정 대기 시간을 늘리는 변경 역시 요구사항을 바꾸는 결정입니다.
어떤 장애를 얼마나 늦게 알아도 되는지 팀의 대응 예산과 함께 논의해야 합니다.
마지막으로 firing의 의미를 좁고 정확하게 보고합니다. 이번 시험에서 확인하는 것은
규칙 엔진이 생성한 상태입니다. Alertmanager의 그룹화·침묵·라우팅이나 메일 전송은
별도 단계이고 이 VM 실험에서 외부 알림을 발송하지 않습니다. 확인하지 않은 전달까지
“알림 정상”이라고 적지 않는 습관은 시험의 품질만큼 중요한 운영 기술입니다.
다음 실습에서 할 것
coverage-rules.yml에서 없는 값을 0으로 채우는 잘못된 처리를 없애고, 실제 0은 보존합니다.
coverage-tests.yml에서 누락된 경로에 대한 틀린 기대 표본을 고칩니다. 이후 alert-rules.yml의
대기 시간을 설정하고 alert-tests.yml에서 복귀 직후 발화를 기대한 오답을 수정합니다.
관측에는 실제 엔진 출력이 남습니다. 마지막 보고서에는 count의 신선도 한계와 이 시험이
확인하지 않은 외부 전달 범위를 명시합니다.
공식 문서
- [최신 표본 선택과 staleness](https://prometheus.io/docs/prometheus/latest/querying/basics/#staleness)
- [경보 규칙과 상태](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/)
- [규칙 시험의 입력과 기대 결과](https://prometheus.io/docs/prometheus/latest/configuration/unit_testing_rules/)