ダッシュボードを書き、それを検査する道具を作る
한국어 원문으로 표시합니다.
목표
질문 넷을 먼저 적고, 그 질문에 답하는 상태 대시보드를 JSON 으로 직접 씁니다. 그다음 그 대시보드를 검사하는 도구를 만들어, 패널마다 답하는 질문이 적혀 있는지·패널이 여섯을 넘지 않는지·5xx 를 비율로 보고 있는지·지연을 백분위로 보고 있는지를 기계가 대신 물어보게 만듭니다.
왜 중요한가
대시보드는 한 방향으로만 자랍니다. "이것도 보이면 좋겠다" 며 붙일 근거는 누구나 댈 수 있지만, 지우려면 "이건 아무도 안 본다" 를 증명해야 하는데 그럴 방법이 없기 때문입니다. 패널마다 답하는 질문을 적어 두면 그 질문이 없는 패널을 지울 근거가 생기고, 검사기를 CI 에 걸면 그 규칙이 사람 손을 떠납니다.
대시보드 JSON 의 diff 는 사람이 읽기 어렵습니다. 좌표와 필드가 잔뜩 움직여서 리뷰가 그냥 통과하기 쉽습니다. 기계가 대신 물어봐 주는 자리를 만드는 것이 이 실습의 진짜 목적입니다.
이 실습에서 Grafana 는 띄우지 않습니다
여기서 다루는 것은 대시보드 JSON 그 자체입니다. Grafana 를 띄워 화면으로 만드는 일은 이 코스의 뒤쪽 실습에서 합니다. 여기서는 파일과 검사기만 씁니다.
단계
- 이 대시보드가 답할 질문 넷을
/root/gfq/01-questions.md에 적으세요. 질문은 물음표로 끝나는 한 문장이고, 질문마다metric:으로 시작하는 줄에 어떤 지표로 답하는지 적습니다. 네 가지 골든 시그널(지연·트래픽·오류·포화)을 덮어야 합니다. /root/gfq/dashboard.json에 상태 대시보드를 쓰세요.uid가 있어야 하고, 제목은 물음표로 끝나며, 패널은 4~6개입니다. 패널마다description에 그 패널이 답하는 질문을 물음표로 끝나게 적습니다. 제목에5xx가 든 패널과지연(또는latency)이 든 패널이 하나씩 있어야 합니다./root/gfq/lint.py를 만드세요.python3 lint.py <JSON 경로>가 위반마다VIOLATION <규칙id> <패널 제목>한 줄을 내고 마지막에violations=<개수>를 냅니다. 첫 규칙은no-description입니다. 내 대시보드에 돌린 결과를/root/gfq/03-lint-basic.txt에 저장하세요.- 규칙 셋을 더하세요.
too-many-panels(패널이 6개를 넘음),error-count-not-ratio(제목에5xx가 있는데 쿼리에 나눗셈이 없음),latency-not-quantile(제목에지연이나latency가 있는데 쿼리에histogram_quantile이 없음). 각 규칙을 일부러 어긴 파일로 시험한 결과를/root/gfq/04-lint-full.txt에 담으세요. - 네 규칙을 모두 어기는 대시보드를
/root/gfq/bad-dashboard.json에 일부러 만들고, 검사기를 돌린 결과를/root/gfq/05-bad.txt에 저장하세요. - 진단용 패널을
/root/gfq/diagnosis.json(패널 셋 이상, 다른uid)으로 빼고, 상태 대시보드의links가 그uid를 가리키게 하세요. 패널 수와 링크를 확인한 결과를/root/gfq/06-split.txt에 담습니다. - 규칙 하나를 더합니다.
description-not-question— 설명이 있는데 물음표로 끝나지 않으면 위반입니다. 서술문 설명을 가진 파일로 시험한 결과를/root/gfq/07-lint-e.txt에 담으세요. /root/gfq/08-review.md에 리뷰를 쓰세요.## 30초 시험,## 지운 패널,## CI 에 거는 이유세 절이 필요하고, 상태·진단·용량 세 종류의 구분이 들어가야 합니다.
참고
- 표준 라이브러리의
json만 씁니다. 이 파드는 밖으로 못 나가서pip install이 되지 않습니다. - 패널의 쿼리는
panel["targets"][i]["expr"]에 있습니다. 한 패널에 target 이 여럿일 수 있으니 이어 붙여 보는 편이 안전합니다. - Grafana API 로 올릴 때는
{"dashboard": {…}}껍데기를 씌우므로, 검사기가doc.get("dashboard", doc)로 양쪽을 다 받아 주면 나중에 그대로 쓸 수 있습니다. - 5xx 비율은
sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))꼴입니다. 개수는 트래픽이 늘면 같이 늘지만 사용자가 겪는 확률은 비율입니다. - p95 는
histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))입니다.le는 버킷 경계라 그것만 남기고 합칩니다. - 채점기는 여러분의 검사기를 일부러 어긴 파일에 돌려 봅니다. 무조건
violations=0을 내는 검사기는 없는 것보다 나쁘고, 그 자리에서 떨어집니다.
질문을 먼저 적는다
질문 → 패널 순서로 갑니다. 반대로 하면 '이 지표가 있으니 그려 보자' 가 되고, 그렇게 붙은 패널은 나중에 아무도 해석하지 못합니다.
네 가지 골든 시그널이 그대로 네 질문이 됩니다.
- 오류: 지금 사용자에게 실패를 돌려주고 있나
- 지연: 느려졌나
- 트래픽: 얼마나 들어오고 있나
- 포화: 자원이 곧 바닥나나
질문 줄은 물음표로 끝내고, 바로 아래 metric: 으로 시작하는 줄에 어떤 지표로 답하는지 적으세요. 오류는 개수가 아니라 비율이라는 것이 지표 줄에 드러나야 합니다.
상태 대시보드를 JSON 으로 쓴다
상태 대시보드의 패널은 4~6개입니다. 여섯을 넘으면 대개 진단용이 섞인 것이고, 그러면 30초 안에 답을 못 줍니다.
패널마다 description 에 그 패널이 답하는 질문을 적으세요. 한 문장으로 적히지 않는 패널은 스스로도 무엇을 보는지 모르는 것이라 지울 후보입니다.
제목도 질문으로 답니다. 제목이 질문이면 그 질문에 답하지 않는 패널이 눈에 띕니다.
채점기는 제목에 5xx 가 든 패널의 쿼리에 나눗셈이 있는지, 지연이나 latency 가 든 패널이 histogram_quantile 을 쓰는지를 봅니다.
검사기를 만들고 규칙 하나를 넣는다
출력 형식이 계약입니다. 위반마다 VIOLATION <규칙id> <패널 제목> 한 줄, 마지막에 violations=<개수> 한 줄입니다. 채점기가 이 두 형식을 그대로 찾습니다.
첫 규칙 no-description 은 패널의 description 이 없거나 비어 있으면 위반입니다.
json.load() 로 읽고, doc.get("dashboard", doc) 로 Grafana API 껍데기까지 받아 주면 나중에 그대로 쓸 수 있습니다.
내 대시보드에 돌리면 위반이 없어야 합니다. 나오면 2단계로 돌아가 설명을 채우세요.
규칙 셋을 더하고 잡히는지 시험한다
검사기는 통과시키는 것만 확인하면 절반입니다. 일부러 어긴 파일을 넣어 잡히는지 까지 봐야 합니다. 무조건 통과하는 검사기는 없는 것보다 나쁩니다 — 배우지 않았는데 배웠다고 알려 주고, 아무도 신고하지 않습니다.
규칙 셋은 이렇습니다.
too-many-panels— 패널이 6개를 넘는다. 대시보드 단위로 한 번만 셉니다.error-count-not-ratio— 제목에5xx가 있는데 쿼리에/가 없다.latency-not-quantile— 제목에지연이나latency가 있는데 쿼리에histogram_quantile이 없다.
시험용 파일은 /root/gfq/fixtures/ 같은 자리에 만들어 두고 검사기를 돌리세요. 그 출력을 결과 파일에 담아야 규칙 이름이 남습니다.
네 규칙을 모두 어긴 대시보드를 만든다
흔히 보는 '그래프 벽' 이 정확히 이 모양입니다. 사용자가 겪는 것 대신 프로세스 내부 지표가 줄줄이 붙어 있고, 5xx 는 개수로 그려져 있고, 지연은 평균이며, 설명은 비어 있습니다.
네 가지를 한 편에 모두 담으세요.
- 패널 일곱 개 이상
- 제목에
5xx가 있는데 쿼리에 나눗셈이 없는 패널 - 제목에
지연이 있는데histogram_quantile이 없는 패널 description이 빈 패널
일부러 만드는 이 파일이 검사기의 회귀 시험이 됩니다. 규칙을 고칠 때마다 여기에 돌려 보면 됩니다.
진단용 패널을 다른 대시보드로 뺀다
상태 대시보드에 진단용 패널을 섞는 순간 그 화면은 30초 안에 답을 못 줍니다. 지우는 것이 아니라 옮기는 것입니다 — 옮기고 링크로 이으면 필요할 때 한 번에 건너갈 수 있습니다.
진단 대시보드에는 원인을 찾는 패널을 담습니다. CPU·GC·커넥션 풀 대기·핸들러별 오류율 같은 것들입니다. uid 는 상태 대시보드와 달라야 합니다.
상태 대시보드의 links 는 이런 모양입니다.
"links": [{"type": "dashboards", "title": "왜 아픈가 — 진단", "url": "/d/<진단 uid>"}]
결과 파일에는 두 대시보드의 패널 수와 링크를 확인한 출력을 담으세요.
설명이 질문인지까지 본다
설명이 서술문이면 '무엇을 그렸는지' 만 남고 '왜 보는지' 가 사라집니다. "5xx 요청의 비율을 보여 준다" 는 패널을 보면 알 수 있는 말이라 아무것도 더해 주지 않습니다.
물음표를 강제하면 질문을 못 쓰는 패널이 드러나고, 그 패널이 지울 후보가 됩니다.
규칙 이름은 description-not-question 입니다. 설명이 아예 없으면 그것은 no-description 이니, 두 규칙이 겹쳐 두 번 세지 않도록 나눠 쓰세요.
내 대시보드는 여전히 위반이 없어야 합니다.
인시던트 리뷰를 쓴다
대시보드를 만들고 나면 인시던트 테스트를 해 봅니다. 새벽 3시에 호출을 받았다고 치고, 이 대시보드를 열어 30초 안에 정상인지 아닌지 말할 수 있는가. 말할 수 없으면 패널이 모자란 것이 아니라 많은 것입니다.
세 절을 씁니다.
## 30초 시험— 어떤 순서로 보고 무엇으로 판단하는가## 지운 패널— 무엇을 왜 뺐는가. 상태·진단·용량 세 종류의 구분이 여기서 드러납니다## CI 에 거는 이유— 검사기가 무엇을 막아 주는가
제목이 질문이면 그 질문에 답하지 않는 패널이 눈에 띈다는 것도 함께 적어 두면 좋습니다.