Search
moon
sun

[2편] Grafana 커스텀 패널로 10만 점 산점도 그리기 — 만들고 나서야 보인 함정 3가지

URL
생성 일시
2026/09/10 01:06
최종 편집 일시
2026/09/10 01:06
태그
여기어때
파일과 미디어
|| OpenTelemetry + ClickHouse 로 APM 스캐터 차트 만들기 (2) — Grafana 커스텀 패널 글. 박준희(Kuiper) / 숙박플랫폼개선TF팀 1. 들어가며 안녕하세요. 여기어때 숙박플랫폼개선TF팀 박준희(카이퍼)입니다. 1편에서 OpenTelemetry Collector 로 span 을 받아 ClickHouse 에 쌓는 데까지 다뤘습니다. 요약하면 이렇습니다. span 하나를 점 하나로 보고, X축은 종료 시각(timestamp + duration) 기존 트레이싱 경로는 건드리지 않고 별도 consumer group 으로 분기 적재 시점 필터로 화면에 쓰이지 않는 span 을 버림 범용 raw 테이블을 Materialized View 로 조회 전용 테이블로 변환 정렬 키는 (namespace, service, timestamp, trace_id) 이제 이 데이터를 화면으로 만들 차례입니다. 2편은 다음을 다룹니다. Grafana 기본 패널로는 왜 안 되는가 패널 플러그인이 어떻게 생겼고, 어떻게 개발 환경을 꾸리는가 컴포넌트를 어떻게 나눴는가 종료 시각으로 그리면서 시작 시각으로 찾아야 하는 조회 문제 만들고 나서야 보인 함정 3가지와 그 대응 — 서버 격자 집계, 사전 집계 롤업, 증분 조회 화면에 나타나는 패턴을 읽는 법 완성된 화면부터 보겠습니다. 시간대별 트래픽 변동 위에 URI 마다 다른 응답 대역이 층을 이루고, 오른쪽에 URI 별 전수 통계가 붙습니다. 검증 범위는 1편과 같습니다. 로컬 환경에서 구성·검증한 기록이며, 수치는 로컬 실측 / 공식 문서 로 출처를 구분해 표기했습니다.2. 왜 기본 패널로는 안 되는가 Grafana 에는 이미 여러 시각화가 있습니다. 처음에는 기본 제공 패널로 어떻게든 해보려 했습니다. 2.1 시도해 본 것들 Time series 패널 — 시계열 라인 차트입니다. 점 표시 모드로 원본 행을 그대로 찍을 수는 있지만, 점마다 카테고리별 모양·색을 주거나 영역을 드래그해 재조회하는 상호작용이 없습니다. 그리고 보통은 쿼리 단계에서 시간 버킷 집계를 물려 선으로 잇는 용법이라, 애초에 1편에서 피하려던 “접는” 시각화에 가깝습니다. Table 패널 — 개별 행은 보이지만 분포의 모양이 보이지 않습니다. 수만 건을 눈으로 훑을 수는 없습니다. Heatmap 패널 — 이쪽은 꽤 가깝습니다. 시간 × 값의 2차원 밀도를 보여주니까요. 실제로 밀도만 보면 되는 용도라면 heatmap 으로 충분할 수 있습니다. XY chart 패널 — 산점도를 그려주지만, 아래 요구를 채우지 못했습니다. 2.2 기본 패널로 채워지지 않은 요구 점 색으로 상태 구분 — 정상/느림/4xx/5xx 를 한눈에. 에러가 위쪽에 몰리는 패턴이 바로 보여야 합니다 점 모양으로 카테고리 구분 — HTTP In / Messaging Consumer / Scheduled 를 색과 독립적으로 구분 (색은 이미 상태에 씁니다) 드래그로 영역 선택 → 상세 조회 — 이상 구간을 끌어서 그 안의 요청 목록을 바로 보기 선택 영역만 별도 쿼리 — 화면에 그린 데이터가 아니라 서버에 다시 물어야 정확한 목록이 나옵니다 카테고리 필터 토글 — 하위 호출을 켜고 끄며 원인 층을 좁히기 트레이스·로그로 이동 — 점 하나에서 분산 트레이싱·로그로 연결 10만 점 규모 렌더링 — 기본 패널은 이 규모에서 버벅입니다 특히 드래그 선택 → 별도 쿼리 가 결정적이었습니다. 화면에 그려진 점은 이미 상한에 걸려 잘렸을 수 있으므로(8장), 선택 영역의 정확한 목록은 서버에 다시 물어야 합니다. 이건 시각화 패널의 일반적인 동작 범위를 벗어납니다. 그래서 커스텀 패널 플러그인을 만들기로 했습니다. 3. Grafana 패널 플러그인은 어떻게 생겼나3.1 플러그인의 최소 구성 공식 문서가 정의하는 필수 파일은 두 개입니다. plugin.json — "Stores metadata about your plugin, including information like its des