Grafana — 대시보드는 질문이다 · 주석 — 사건을 그래프 위에 올린다 · 실습
세로줄 하나가 조사 30분을 없앤다
목표
오류율 패널 하나짜리 대시보드에 배포와 장애를 주석으로 올려, 그래프가 '언제' 뿐 아니라 '그 때 무슨 일이 있었나' 까지 답하게 만듭니다. 주석은 API 로 남기고 다시 읽어 확인하며, 배포 파이프라인이 자동으로 남기는 기록기도 만듭니다.
왜 중요한가
지표는 값이 변한 시각까지만 답한다. 그 시각에 사람이 무엇을 했는지는 지표 바깥의 사건이라 같은 화면에 없고, 그래서 새벽에 호출받은 사람은 배포 기록과 채팅과 설정 저장소를 오가며 시계를 맞춘다. 조사 시간의 상당 부분이 그 왕복이다. 주석은 그 사건을 같은 시간축 위에 올려 왕복을 없앤다. 다만 주석은 사후에 만들 수 없는 기록이라 그때 남겨야 하고, 그러려면 사람의 손이 아니라 파이프라인이 남겨야 한다. 무엇을 적을지도 미리 정해 두어야 한다 — 다음 사람이 그 자리에서 되돌릴 수 있으려면 버전과 사람과 되돌리는 명령이 주석 안에 있어야 한다.
단계
1. lab-start-grafana 로 Grafana 를 띄우고, uid 가 gfd-annot 인 대시보드를 만드세요. 패널은 shop-api 의 5xx 비율을 그리는 timeseries 한 장입니다. 그리고 /root/gfd-annotations/01-blind.txt 에 세 줄을 적으세요 — question= 뒤에 이 패널이 답하는 질문, unanswerable= 뒤에 이 패널만으로는 답할 수 없는 질문, reason= 뒤에 왜 답할 수 없는지를 40자 이상으로 적습니다.
2. POST /api/annotations 로 이 대시보드(dashboardUID 가 gfd-annot)에 배포 주석 하나를 남기세요. 태그에 deploy 가 있어야 하고, 본문에는 version=vX.Y.Z 형태의 버전이 들어가야 합니다. 시각은 지금부터 30분 전으로 둡니다(밀리초 에포크). 응답에 돌아온 id 로 GET /api/annotations 를 다시 읽어 확인한 뒤, /root/gfd-annotations/02-annot.txt 에 두 줄 id=<그 id> 와 version=<적은 버전> 을 적으세요.
3. 시작과 끝이 있는 구간 주석을 하나 남기세요. 태그는 incident 이고, 시작은 지금부터 25분 전, 끝은 지금부터 5분 전입니다(따라서 길이는 20분). 본문에는 무엇이 있었는지 한 줄로 적습니다. 그리고 /root/gfd-annotations/03-region.txt 에 두 줄 id=<그 id> 와 duration_min=<구간 길이(분)> 를 적으세요.
4. 대시보드의 annotations.list 에 주석 질의 두 개를 선언하세요. 하나는 deploy 태그를, 다른 하나는 incident 태그를 가져옵니다. 두 항목 모두 켜져 있어야 하고(enable), 서로 다른 색(iconColor)을 가지며, 대상은 태그로 거르는 형태(target.type 이 tags)여야 합니다. 두 태그를 모두 가진 주석만 가져오는 일이 없도록 한 항목에는 태그를 하나씩만 둡니다.
5. /root/gfd-annotations/annotate-deploy.sh 를 만드세요. 첫 인자로 버전을 받아 gfd-annot 대시보드에 주석을 남기고, 태그는 deploy 와 auto 두 개, 본문에는 version=, by=, rollback= 세 값이 들어갑니다. 환경변수 DRY_RUN=1 이 주어지면 쏘지 않고 보낼 JSON 본문만 표준출력에 찍고 끝나야 합니다(그때 출력은 JSON 하나뿐이어야 합니다). 그리고 그 스크립트로 서로 다른 두 버전을 실제로 기록하세요.
6. /root/gfd-annotations/annotation-fields.txt 에 배포 주석에 반드시 적을 필드 이름을 한 줄에 하나씩 적으세요 — version, by, rollback 셋은 반드시 들어가야 합니다. 그리고 그 형식을 지키는 주석 하나를 gfd-annot 대시보드에 남기세요. 태그는 deploy 와 runbook 두 개이고, 본문에는 적어 둔 모든 필드가 필드이름=값 형태로 들어가야 합니다. rollback 의 값은 그대로 칠 수 있는 명령이어야 하므로 10자 이상입니다. runbook 태그가 붙은 주석은 이 하나뿐이어야 합니다.
7. /root/gfd-annotations/07-timeline.tsv 를 만드세요. gfd-annot 대시보드에 달린 모든 주석을 시각 오름차순(같으면 id 오름차순)으로 한 줄씩, 탭으로 나눈 세 칸 <id> <태그 하나> <요약> 으로 적습니다. 둘째 칸은 그 주석에 실제로 붙어 있는 태그 중 하나여야 하고, 셋째 칸은 4자 이상의 요약입니다.
8. /root/gfd-annotations/08-finding.txt 에 네 줄을 적으세요 — deploy_id= 는 2단계에서 남긴 배포 주석의 id, incident_id= 는 3단계에서 남긴 구간 주석의 id, gap_min= 은 배포 시각과 장애 시작 시각의 차이를 분으로 반올림한 정수(0 이상), verdict= 는 이 두 사건을 이어 내린 결론을 60자 이상으로 적은 문장입니다. 두 시각은 API 에서 다시 읽어 계산하세요.
참고
- 작업 디렉터리는
/root/gfd-annotations입니다. 배포 이력 재료는/opt/lab/gfd/gfd-annotations/releases.tsv이고, 그 파일을 만든 스크립트는/opt/lab/gfd/gfd-annotations/make.sh입니다. - Grafana 는
lab-start-grafana로 켭니다(20~40초). 익명 Admin 이라 토큰 없이 API 를 쓸 수 있고, 터미널 위쪽 웹 미리보기의 3000번 포트로 화면을 열 수 있습니다. - 주석의 시각은 밀리초 에포크 정수입니다. 초 단위로 넣으면 1970년대 어딘가에 찍혀 화면에서 사라집니다.
- 이 환경에서 판정할 수 없는 것: 주석이 화면에 정말 세로줄로 그려지는가. 패널은 브라우저가 그리고 이미지 렌더러 플러그인이 없습니다. 채점은 전부 API 응답과 대시보드 모델로만 합니다 — 질의가 선언돼 있고 그 태그로 주석이 조회된다면 그려질 조건은 갖춘 것이지만, 그것과 '그려졌다' 는 같은 말이 아닙니다.
- 흔한 실수:
dashboardUID없이 만들어 조직 전체 주석이 된 것. 만든 직후에GET으로 다시 읽어 확인하는 습관이 이 실수를 그 자리에서 잡아 줍니다. - [Annotate visualizations](https://grafana.com/docs/grafana/latest/visualizations/dashboards/build-dashboards/annotate-visualizations/) · [Annotations HTTP API](https://grafana.com/docs/grafana/latest/developer-resources/api-reference/http-api/api-legacy/annotations/) · [Dashboard HTTP API](https://grafana.com/docs/grafana/latest/developer-resources/api-reference/http-api/dashboard/) · [Dashboard JSON model](https://grafana.com/docs/grafana/latest/visualizations/dashboards/build-dashboards/view-dashboard-json-model/)
단계 8개
- 그래프는 '언제' 까지만 답한다
- 배포를 주석으로 남기고 다시 읽어 확인한다
- 구간 주석으로 장애 시간을 표시한다
- 태그로 갈라 대시보드가 가져오게 한다
- 파이프라인이 자동으로 남기게 만든다
- 다음 사람이 그 자리에서 행동할 수 있는가
- 주석을 시간순으로 다시 읽어 조사 기록을 만든다
- 배포와 장애를 이어 결론을 적는다