Grafana — 대시보드는 질문이다 · 단위와 축 · 이론
단위를 적지 않은 숫자는 읽는 사람이 지어낸다
한 줄 요약
단위를 적지 않은 숫자는 읽는 사람이 단위를 지어낸다. 그리고 지어낸 단위는 대개 그 사람에게 유리한 쪽이다.
왜 이게 필요했나
장애 회의에서 누군가 대시보드를 띄우고 말한다. "지연이 0.42 입니다." 회의실의 절반은 420밀리초로 알아들었고 절반은 0.42밀리초로 알아들었다. 두 숫자는 천 배 차이고, 하나는 사고이고 하나는 자랑이다. 대화는 20분쯤 더 이어지다가 누가 쿼리를 열어 보고 나서야 끝났다.
이런 어긋남은 사람이 부주의해서 생기는 것이 아니다. 화면이 숫자만 보여 주기 때문에 생긴다. Grafana 는 값에 단위를 붙여 주는 기능을 갖고 있는데, 그 기능은 우리가 무엇인지 말해 줄 때만 동작한다. 아무 말도 하지 않으면 Grafana 는 숫자를 그대로 그리고, 해석은 보는 사람의 몫으로 남는다.
더 나쁜 경우는 단위를 적었는데 틀리게 적은 것이다. 단위가 없으면 사람들은 최소한 의심이라도 한다. 단위가 붙어 있으면 아무도 의심하지 않는다. 초 단위로 나오는 쿼리에 밀리초 단위를 붙여 놓으면 화면은 "0.42 ms" 라고 자신 있게 말하고, 그걸 본 사람은 서비스가 아주 빠르다고 믿는다.
어떻게 동작하나
Grafana 의 단위는 표시 규칙이지 변환 규칙이 아니다. 패널의 fieldConfig.defaults.unit 에 식별자를 적으면 Grafana 는 그 식별자에 묶인 형식 함수로 숫자를 문자열로 바꾼다. 값 자체는 손대지 않는다. 그래서 초로 나오는 값을 밀리초로 보이게 하려면 단위만 바꾸는 것이 아니라 쿼리에 1000 을 곱해야 한다.
식별자는 화면에 보이는 이름과 다르다. 드롭다운에는 "Percent (0.0-1.0)" 이라고 적혀 있지만 JSON 에 들어가는 값은 percentunit 이다. "bytes(IEC)" 는 bytes 이고 "bytes(SI)" 는 decbytes 다. 앞의 것은 1024 로 나누며 GiB 로 줄이고 뒤의 것은 1000 으로 나누며 GB 로 줄인다. 같은 4294967296 이 4 GiB 로도 4.29 GB 로도 보인다. 어느 쪽이 맞는지는 그 숫자를 만들어 낸 쪽이 무엇을 세었는지에 달려 있다.
비율도 두 벌이다. 0 과 1 사이로 나오는 값에는 percentunit 을, 0 과 100 사이로 나오는 값에는 percent 를 쓴다. PromQL 로 만든 오류 비율은 거의 언제나 앞쪽인데 패널에는 뒤쪽이 붙어 있는 일이 흔하다. 그러면 1.6% 인 오류율이 화면에서 0.016% 로 보인다. 경보는 울리는데 대시보드는 평온해 보이는 상태가 이렇게 만들어진다.
축은 단위 다음에 오는 두 번째 거짓말의 자리다. Grafana 는 기본적으로 데이터에 맞춰 y축을 자동으로 잡는다. 초당 요청 수가 34 에서 75 사이를 오가면 축도 34 에서 75 로 잡히고, 그 안에서 선은 화면 높이를 가득 채우며 출렁인다. 실제로는 두 배 남짓 차이인데 화면은 절벽처럼 보인다. 그래서 양을 세는 패널의 최솟값은 0 으로 고정하는 편이 정직하다. [표준 옵션 문서](https://grafana.com/docs/grafana/latest/visualizations/panels-visualizations/configure-standard-options/)의 Min·Max 가 그 자리다.
반대로 최댓값은 함부로 고정하면 안 된다. 최댓값을 20 으로 박아 둔 요청 수 패널은 트래픽이 75 까지 올라간 날에도 20 에서 잘린 평평한 천장을 보여 준다. 사고는 언제나 그 천장 위에서 일어나는데 화면에는 남지 않는다. 변동이 작아 선이 납작해 보이는 것이 싫다면, 하드 최댓값 대신 [시계열 패널의 Soft min·Soft max](https://grafana.com/docs/grafana/latest/visualizations/panels-visualizations/visualizations/time-series/)를 쓴다. 데이터가 그 범위를 넘어서면 축이 따라 넓어져서 잘리지 않는다.
한 패널에 단위가 다른 둘을 같이 그려야 할 때도 있다. 지연과 오류 비율을 겹쳐 놓고 "느려진 시각과 실패가 늘어난 시각이 같은가" 를 묻는 패널이 그렇다. 이때는 패널 전체의 단위를 하나로 두고, 나머지 계열에만 [오버라이드](https://grafana.com/docs/grafana/latest/visualizations/panels-visualizations/configure-overrides/)로 단위와 축 위치를 따로 준다. 시계열 패널 문서는 단위가 둘 이상이면 첫 단위가 왼쪽 축을, 그 뒤의 단위가 오른쪽 축을 쓴다고 적고 있다. 오버라이드 없이 그냥 겹치면 두 계열이 한 축을 나눠 쓰게 되고, 0.004 짜리 비율은 0.3 짜리 지연 옆에서 바닥에 붙은 직선이 된다.
로그 축은 크기가 크게 다른 계열들을 한 화면에 놓을 때 쓴다. 초당 42건인 핸들러와 6건인 핸들러를 선형 축에 같이 그리면 작은 쪽의 변화는 보이지 않는다. 로그 축에서는 같은 세로 거리가 같은 배수를 뜻하므로 둘 다 읽을 수 있게 된다. 대신 잃는 것이 있다. 눈금 사이의 거리가 더 이상 양의 차이가 아니라서 넓이를 눈으로 더할 수 없고, 0 과 음수는 아예 그릴 수 없으며, 두 배로 뛴 사건과 열 배로 뛴 사건이 비슷한 높이 차이로 보인다. 그래서 "얼마나 늘었나" 를 묻는 패널에는 어울리지 않는다.
이 실습이 판정할 수 없는 것이 하나 있다 — 실제로 그려진 그림이다. 이 파드의 Grafana 에는 이미지 렌더러 플러그인이 없어서 패널을 이미지로 뽑을 수 없다. 그래서 채점기는 대시보드 JSON 모델과 쿼리 결과만 본다. 단위 식별자가 무엇인지, 축의 최솟값이 얼마인지, 쿼리가 실제로 어떤 값을 내는지는 전부 확인할 수 있지만, 그 조합이 화면에서 읽을 만한지는 확인할 수 없다. 축 이름이 겹쳐 잘리거나 범례가 그래프를 덮는 종류의 문제는 웹 미리보기로 3000번 포트를 직접 열어 눈으로 봐야 한다. 모델이 맞다는 것과 화면이 읽힌다는 것은 다른 이야기다.
현장에서 만나는 모습
한 팀은 메모리 사용량 패널에 SI 단위를 붙여 두고 있었다. 컨테이너 한도는 4 GiB 인데 화면에는 4.29 GB 로 보였고, 사람들은 "아직 여유가 있다" 고 읽었다. 그날 밤 그 파드는 한도에 걸려 죽었다. 값은 한 번도 틀린 적이 없었고 이름만 틀려 있었다.
다른 팀에서는 오류율 패널이 몇 달 동안 percent 로 붙어 있었다. 실제 오류율이 2% 까지 올라간 날에도 화면은 0.02% 를 보여 줬다. 경보는 정상적으로 울렸지만 담당자는 대시보드를 보고 "경보가 잘못 울린 것 같다" 고 판단해 무시했다. 사고 회고에서 가장 오래 이야기한 것은 경보 규칙이 아니라 그 단위 한 글자였다.
다음 실습에서 할 것
진짜 Grafana 를 띄우고 단위 없는 패널을 하나 올려, 그 숫자가 몇 가지로 읽히는지 직접 적어 본다. 그다음 초·비율·바이트 패널에 Grafana 의 단위 식별자를 넣고, 쿼리를 던져 값의 크기와 단위가 맞는지 확인하고, 밀리초로 보이려면 무엇을 곱해야 하는지 손으로 확인한다. 축의 최솟값을 0 으로 고정해야 하는 자리와 최댓값을 고정하면 안 되는 자리를 가르고, 단위가 다른 두 계열을 한 패널에 오버라이드로 올리고, 로그 축을 쓴 뒤 무엇을 잃었는지 적는다. 마지막에는 운영에서 걷어 온 대시보드 하나를 받아 단위·축 결함 네 개를 전부 고쳐 제출한다 — 채점기는 고친 대시보드를 Grafana 에게 물어보고, 패널의 쿼리를 실제로 던져 값과 단위가 맞는지 본다.