LabHub
배우기 러닝패스 코스

관측성 · 사고 조사와 사후 분석 · 실습

세 가설 중 둘은 자료로 30분 만에 지울 수 있었다

LabHub 에서 이어서 보기

목표

파드의 Prometheus 12시간치에 들어 있는 한 번의 사고를 절차대로 조사합니다. 시각을 상대 시각으로 못박고, 영향을 세고, 가설 세 개와 예측을 먼저 적은 뒤 둘을 지우고, 남은 하나를 다른 지표로 확증하고, 연표와 사후 분석을 남기고, 마지막에 더 빨리 잡는 탐지기를 써서 같은 자료로 검증합니다.

왜 중요한가

장애 조사가 오래 걸리는 이유는 대개 자료가 없어서가 아니라 순서가 없어서다. 가설을 먼저 말하고 나중에 자료를 보면 해석이 가설에 끌려간다. 반대로 '이 가설이 참이라면 무엇이 보여야 하는가' 를 먼저 적어 두면 자료가 그 모양이 아닐 때 가설을 버릴 수 있고, 반증은 확증보다 훨씬 싸다. 그 앞에 반드시 와야 하는 것이 시각을 못박는 일이다 — 시작과 끝이 없으면 '사고 구간의 요청률' 같은 말이 아예 계산되지 않는다. 그리고 모든 시각은 상대 시각으로 적는다. 절대 시각은 시간대와 서머타임과 로그 서버의 시계를 타고 회고를 망친다. 마지막으로 남길 것은 원인만이 아니다 — 지운 가설과 지운 근거, 그리고 탐지가 몇 분 늦었는가가 다음 분기에 무엇을 고칠지를 정한다.

단계

1. 탐지 조건을 /root/obs-incident-triage/onset.promql 에 쓰세요 — 5분 창에서 5xx 가 차지하는 비율입니다(임계값 비교는 넣어도 되고 빼도 됩니다). 그다음 최근 12시간을 1분 간격 범위 조회로 훑어 이 비율이 0.05 를 넘은 구간을 찾아 /root/obs-incident-triage/01-onset.txt 에 네 줄을 적으세요 — start_minutes_ago=(처음 넘은 시각이 지금으로부터 몇 분 전인지 정수), end_minutes_ago=(마지막으로 넘은 시각), duration_min=(넘은 분의 개수), peak_ratio=(그 구간의 최대 비율, 소수 넷째 자리). 절대 시각은 적지 마세요.
2. 조건이 참이었던 분들만 골라 그 분의 increase(...[1m]) 값을 더하세요. /root/obs-incident-triage/02-impact.txt 에 세 줄 failed_requests=(5xx 건수, 정수), total_requests=(전체 요청 수, 정수), failed_share=(둘의 비, 소수 넷째 자리)를 적고, /root/obs-incident-triage/02-handlers.tsv 에 핸들러 네 개를 한 줄씩 탭으로 나눈 세 칸 <handler><탭><5xx 건수><탭><전체 5xx 중 비중> 으로 적으세요(비중은 소수 넷째 자리). 창을 시각으로 잘라 세면 경계에서 건수가 통째로 빠집니다 — 분을 골라 더하세요.
3. /root/obs-incident-triage/03-hypotheses.tsv 에 세 줄을 적으세요. 각 줄은 탭으로 나눈 네 칸 <id><탭><가설><탭><예측><탭><검증에 쓸 PromQL> 이고 id 는 h1·h2·h3 입니다. 가설은 h1 = 특정 핸들러의 코드 결함, h2 = 트래픽 급증에 의한 과부하, h3 = 주문 큐 하류 의존성 정체입니다. 예측 칸에는 '이 가설이 참이라면 자료에 무엇이 보여야 하는가' 를 25자 이상으로 적고, 마지막 칸에는 그것을 확인할 수 있는 쿼리를 적습니다. h1 의 쿼리는 handler 로 나눠야 하고, h2 는 http_requests_totalrate, h3 는 queue_depth 를 봐야 합니다.
4. 세 가설 중 자료로 지울 수 있는 둘을 골라 /root/obs-incident-triage/04-refuted.tsv 에 두 줄로 적으세요. 각 줄은 탭으로 나눈 네 칸 <id><탭><측정값><탭><판정><탭><근거> 이고 판정은 refuted 입니다. 측정값은 id 마다 정해져 있습니다 — 핸들러 가설은 핸들러별 5xx 비율(5분 창)의 12시간 최댓값들 사이의 최대−최소(소수 넷째 자리), 트래픽 가설은 사고 구간 평균 초당 요청 수 ÷ 사고 시작 직전 한 시간(마지막 5분은 빼고)의 평균(소수 넷째 자리)입니다. 근거는 25자 이상이고 숫자를 포함해야 합니다.
5. /root/obs-incident-triage/05-confirm.txt 에 다섯 줄을 적으세요 — hypothesis=(남은 가설의 id), queue_peak=(12시간 동안 queue_depth 의 최댓값, 정수), queue_baseline=(같은 12시간의 중앙값, 정수), overlap_min=(큐 깊이가 100 을 넘은 분 중 오류 조건도 참이었던 분의 개수, 정수), evidence=(40자 이상이고 숫자를 포함하는 한 줄). 확증은 처음 조건식과 다른 지표로 해야 합니다.
6. /root/obs-incident-triage/06-timeline.tsv 에 네 줄을 적으세요. 각 줄은 탭으로 나눈 세 칸 <event><탭><minutes_ago><탭><근거> 이고 event 는 impact_start·detect·impact_end·latency_tail_start 네 가지입니다. detect지금 쓰고 있는 경보(5분 창 5xx 비율이 0.10 을 넘는 상태가 10분 지속)가 울렸을 시각이고, latency_tail_start 는 p99 지연이 1초를 넘기 시작한 시각입니다(오류 사고와는 다른 사건입니다). minutes_ago 는 정수이고 근거 칸에는 그 값을 낸 지표나 쿼리 이름을 10자 이상 적습니다.
7. /root/obs-incident-triage/07-postmortem.txt 에 다섯 줄을 적으세요 — time_to_detect_min=(영향 시작부터 경보까지 몇 분, 정수), time_to_recover_min=(영향 시작부터 영향 종료까지 몇 분, 정수), impact=(40자 이상, 숫자 포함), why_late=(탐지가 늦은 이유, 60자 이상), next_change=(다음에 바꿀 것, 60자 이상). 두 숫자는 6단계 연표에서 그대로 나옵니다.
8. /root/obs-incident-triage/rules/faster.ymlfaster 그룹과 FastErrorRatio 경보를 쓰세요 — expr·for·labels.severity·annotations.runbook_url 이 있어야 하고 for<정수>m 형식입니다. 이 규칙은 지금 경보(5분 창·0.10·10분 지속)보다 3분 이상 일찍 울려야 하고, 같은 12시간 안에서 사고 구간 밖으로 울린 분이 10분을 넘지 않아야 합니다. 그리고 /root/obs-incident-triage/08-gain.txt 에 세 줄 baseline_detect_min_ago=, new_detect_min_ago=, gain_min=(두 값의 차) 을 정수로 적으세요.

참고

단계 8개

  1. 시작 시각을 자료로 못박는다
  2. 영향 범위를 센다 — 몇 건이 실패했고 어디에 몰렸나
  3. 가설보다 예측을 먼저 적는다
  4. 두 가설을 자료로 지운다
  5. 남은 가설을 다른 신호로 확증한다
  6. 기계가 읽을 수 있는 사고 연표
  7. 사후 분석 — 탐지가 왜 늦었나
  8. 더 빨리 잡는 탐지기를 쓰고 같은 자료로 검증한다