LabHub
배우기 러닝패스 코스

관측성 · 그래프를 잘못 읽는 자리 · 실습

같은 장애가 대시보드에서는 보이지 않았다

LabHub 에서 이어서 보기

목표

같은 12시간 자료에 같은 질문을 던지되 rate 창과 step 만 바꿔서 답이 어떻게 달라지는지 숫자로 재고, 운영 대시보드에서 베껴 온 망가진 패널 세 개를 고쳐 제출합니다.

왜 중요한가

대시보드를 믿는다는 것은 그 패널이 어떤 요약을 하고 있는지 안다는 뜻이어야 한다. 그런데 대부분의 패널은 누군가 한 번 만들어 둔 뒤로 아무도 쿼리를 열어 보지 않는다. 창이 한 시간이면 20분짜리 사고는 3분의 1 높이로 눌려 나타나고, 창이 스크레이프 간격보다 짧으면 자료가 있는데도 화면에 '데이터 없음' 이 뜬다. 비율을 평균하면 새벽 한 시간과 낮 한 시간이 같은 무게를 갖고, 분위수를 평균하면 아무 뜻도 없는 숫자가 나온다. 이 실습의 목적은 PromQL 을 더 배우는 것이 아니라, 패널 하나를 보고 '이 그림은 무엇을 지웠는가' 를 물을 수 있게 되는 것이다.

단계

1. /root/obs-graph-traps/qr.py 를 만드세요. python3 qr.py '<PromQL>' <step초> [<범위 시간>] [<임계값>] 으로 부르면 /api/v1/query_rangestart=지금-범위·end=지금·step=step초 를 주어 한 번 던지고, points=<돌아온 값의 총 개수> max=<최댓값> over=<임계값보다 큰 값의 개수> 한 줄을 출력합니다. 범위 기본값은 12(시간), 임계값 기본값은 0.01 입니다. 값이 하나도 없으면 points=0 max=NA over=0 을 찍습니다. 최댓값은 소수 여섯 자리까지 적습니다.
2. 5xx 비율을 묻는 식 sum(rate(http_requests_total{job="shop-api",status="500"}[창])) / sum(rate(http_requests_total{job="shop-api"}[창])) 을 창만 바꿔 네 번 던지세요. 창은 15s·30s·1m·5m, step 은 60, 범위는 12시간입니다. /root/obs-graph-traps/window-points.tsv 에 머리글 없이 네 줄, 각 줄은 탭으로 나눈 두 칸 <창> <점 수> 입니다. 그리고 /root/obs-graph-traps/02-why.txtreason= 으로 시작하는 한 줄을 40자 이상으로 적어, 가장 짧은 창에서 점이 없는 이유를 설명하세요.
3. 같은 5xx 비율 식을 창 1m·5m·15m·30m·1h 로 다섯 번 던지세요(step 60, 범위 12시간, 임계값 0.01). /root/obs-graph-traps/window-shape.tsv 에 머리글 없이 다섯 줄, 각 줄은 탭으로 나눈 세 칸 <창> <최댓값> <0.01 을 넘은 점 수> 입니다. 최댓값은 소수 여섯 자리, 점 수는 정수입니다.
4. Grafana 는 $__rate_intervalmax($__interval + 스크레이프간격, 4 * 스크레이프간격) 으로 계산합니다. 이 파드의 스크레이프 간격은 15초입니다. step 이 15·108·600·3600 초일 때의 rate 창을 각각 계산한 뒤, 그 창으로 5xx 비율 식을 같은 step 으로 던지세요(범위 12시간). /root/obs-graph-traps/rate-interval.tsv 에 머리글 없이 네 줄, 각 줄은 탭으로 나눈 네 칸 <step초> <rate 창 초> <점 수> <최댓값> 입니다. 그리고 /root/obs-graph-traps/04-note.txtreason= 으로 시작하는 한 줄을 40자 이상으로 적어, step 3600 에서만 같은 쿼리를 다시 던질 때마다 최댓값이 달라지는 이유를 설명하세요.
5. 같은 12시간의 5xx 비율을 두 가지로 구하세요. 하나는 1분 간격 비율의 단순 평균 avg_over_time((sum(rate(http_requests_total{job="shop-api",status="500"}[5m])) / sum(rate(http_requests_total{job="shop-api"}[5m])))[12h:1m]), 다른 하나는 트래픽으로 가중된 전체 비율 sum(increase(http_requests_total{job="shop-api",status="500"}[12h])) / sum(increase(http_requests_total{job="shop-api"}[12h])) 입니다. /root/obs-graph-traps/weighted.txt 에 세 줄을 적으세요 — avg_of_ratio=<소수 여섯 자리>, weighted_ratio=<소수 여섯 자리>, gap_pct=<소수 두 자리>. gap_pct 는 (앞의 값 − 뒤의 값) ÷ 뒤의 값 × 100 입니다.
6. histogram_quantile(0.99, sum by (le) (rate(http_request_duration_seconds_bucket{job="shop-api"}[창]))) 을 창 5m·15m·12h 로 세 번 던지세요(step 60, 범위 12시간). /root/obs-graph-traps/p99-window.tsv 에 머리글 없이 세 줄, 각 줄은 탭으로 나눈 두 칸 <창> <12시간 최댓값> 입니다. 그리고 /root/obs-graph-traps/06-note.txtreason= 으로 시작하는 한 줄을 40자 이상으로 적어, 왜 긴 창의 분위수가 짧은 창 분위수들의 최댓값보다 작아지는지 설명하세요.
7. /opt/lab/graph/panels.yml 의 패널 p1 은 '지난 12시간 5xx 건수' 를 묻는데 소수점이 붙은 값을 냅니다. /root/obs-graph-traps/fix-count.promql 에 같은 12시간의 5xx 건수를 정수로 내는 PromQL 을 쓰세요(주석 # 은 남겨도 됩니다). 그리고 /root/obs-graph-traps/count-panel.txt 에 두 줄을 적으세요 — broken_value=<소수 세 자리> 는 p1 의 식이 지금 내는 값, fixed_value=<정수> 는 고친 쿼리가 내는 값입니다. 채점기는 고친 쿼리를 실제로 던져 값을 봅니다.
8. /opt/lab/graph/panels.yml 의 패널 p2(오류 비율)와 p3(p99 지연)는 각각 '가장 높았을 때 얼마였나' 에 답하지 못합니다. /root/obs-graph-traps/fix-ratio.promql/root/obs-graph-traps/fix-p99.promql 에 고친 쿼리를 쓰세요. 그리고 /root/obs-graph-traps/verdict.tsv 에 머리글 없이 두 줄, 각 줄은 탭으로 나눈 네 칸 <패널id> <고치기 전 12시간 최댓값> <고친 뒤 12시간 최댓값> <무엇이 틀렸었나> 입니다. 첫 줄은 p2, 둘째 줄은 p3 이고, 최댓값은 step 60·범위 12시간으로 재며 소수 여섯 자리입니다. 넷째 칸은 20자 이상이고 숫자를 하나 이상 포함해야 합니다.

참고

단계 8개

  1. 구간 쿼리를 숫자로 요약하는 도구를 만든다
  2. 빈 그래프는 트래픽이 없다는 뜻이 아니다
  3. 창을 넓히면 봉우리는 낮아지고 폭은 넓어진다
  4. 패널 폭이 창을 정한다 — $__rate_interval 을 손으로 계산한다
  5. 비율의 평균은 전체 비율이 아니다
  6. 긴 창의 p99 는 가장 나빴던 p99 가 아니다
  7. 응용 ① — 건수 패널이 소수점을 보여 준다
  8. 응용 ② — 오류 비율과 p99 패널을 고쳐 제출한다