Grafana — 대시보드는 질문이다 · 질문부터 정한다 · 실습
대시보드를 쓰고 그것을 검사하는 도구를 만든다
목표
질문 넷을 먼저 적고, 그 질문에 답하는 상태 대시보드를 JSON 으로 직접 씁니다.
그다음 그 대시보드를 검사하는 도구를 만들어, 패널마다 답하는 질문이 적혀
있는지·패널이 여섯을 넘지 않는지·5xx 를 비율로 보고 있는지·지연을 백분위로
보고 있는지를 기계가 대신 물어보게 만듭니다.
왜 중요한가
대시보드는 한 방향으로만 자랍니다. "이것도 보이면 좋겠다" 며 붙일 근거는
누구나 댈 수 있지만, 지우려면 "이건 아무도 안 본다" 를 증명해야 하는데 그럴
방법이 없기 때문입니다. 패널마다 답하는 질문을 적어 두면 그 질문이 없는
패널을 지울 근거가 생기고, 검사기를 CI 에 걸면 그 규칙이 사람 손을 떠납니다.
대시보드 JSON 의 diff 는 사람이 읽기 어렵습니다. 좌표와 필드가 잔뜩 움직여서
리뷰가 그냥 통과하기 쉽습니다. 기계가 대신 물어봐 주는 자리를 만드는 것이
이 실습의 진짜 목적입니다.
이 실습에서 Grafana 는 띄우지 않습니다
여기서 다루는 것은 대시보드 JSON 그 자체입니다. Grafana 를 띄워 화면으로
만드는 일은 이 코스의 뒤쪽 실습에서 합니다. 여기서는 파일과 검사기만 씁니다.
단계
1. 이 대시보드가 답할 질문 넷을 /root/gfq/01-questions.md 에 적으세요. 질문은 물음표로 끝나는 한 문장이고, 질문마다 metric: 으로 시작하는 줄에 어떤 지표로 답하는지 적습니다. 네 가지 골든 시그널(지연·트래픽·오류·포화)을 덮어야 합니다.
2. /root/gfq/dashboard.json 에 상태 대시보드를 쓰세요. uid 가 있어야 하고, 제목은 물음표로 끝나며, 패널은 4~6개입니다. 패널마다 description 에 그 패널이 답하는 질문을 물음표로 끝나게 적습니다. 제목에 5xx 가 든 패널과 지연(또는 latency)이 든 패널이 하나씩 있어야 합니다.
3. /root/gfq/lint.py 를 만드세요. python3 lint.py <JSON 경로> 가 위반마다 VIOLATION <규칙id> <패널 제목> 한 줄을 내고 마지막에 violations=<개수> 를 냅니다. 첫 규칙은 no-description 입니다. 내 대시보드에 돌린 결과를 /root/gfq/03-lint-basic.txt 에 저장하세요.
4. 규칙 셋을 더하세요. too-many-panels(패널이 6개를 넘음), error-count-not-ratio(제목에 5xx 가 있는데 쿼리에 나눗셈이 없음), latency-not-quantile(제목에 지연이나 latency 가 있는데 쿼리에 histogram_quantile 이 없음). 각 규칙을 일부러 어긴 파일로 시험한 결과를 /root/gfq/04-lint-full.txt 에 담으세요.
5. 네 규칙을 모두 어기는 대시보드를 /root/gfq/bad-dashboard.json 에 일부러 만들고, 검사기를 돌린 결과를 /root/gfq/05-bad.txt 에 저장하세요.
6. 진단용 패널을 /root/gfq/diagnosis.json(패널 셋 이상, 다른 uid)으로 빼고, 상태 대시보드의 links 가 그 uid 를 가리키게 하세요. 패널 수와 링크를 확인한 결과를 /root/gfq/06-split.txt 에 담습니다.
7. 규칙 하나를 더합니다. description-not-question — 설명이 있는데 물음표로 끝나지 않으면 위반입니다. 서술문 설명을 가진 파일로 시험한 결과를 /root/gfq/07-lint-e.txt 에 담으세요.
8. /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을 내는 검사기는 없는 것보다 나쁘고, 그 자리에서 떨어집니다.
단계 8개
- 질문을 먼저 적는다
- 상태 대시보드를 JSON 으로 쓴다
- 검사기를 만들고 규칙 하나를 넣는다
- 규칙 셋을 더하고 잡히는지 시험한다
- 네 규칙을 모두 어긴 대시보드를 만든다
- 진단용 패널을 다른 대시보드로 뺀다
- 설명이 질문인지까지 본다
- 인시던트 리뷰를 쓴다