Hotpath
단일 패스
설계
없음
외부 파서 의존성
4가지
분석 항목
단일 HTML
출력
TL;DR
JVM .jfr 파일을 단일 패스로 파싱해 CPU·GC·메모리·스레드 경합을 분석하고, Plotly.js 인터랙티브 차트가 내장된 단일 HTML 리포트로 출력하는 CLI 도구. JMC 없이 브라우저에서 바로 열어볼 수 있어 성능 분석 결과를 빠르게 공유할 수 있습니다.
📊 핵심 아키텍처
개요
JMC는 훌륭한 도구지만 리포트 형태로 공유하기 어렵고, 벤치마크 도구 리포트는 방대해서 한눈에 보기 어렵다는 문제에서 출발했습니다. Hotpath는 .jfr 파일을 처음부터 끝까지 한 번만 읽는 단일 패스 구조로, 이벤트를 전부 메모리에 올리지 않고 각 핸들러가 집계 상태만 유지합니다. EventRouter가 이벤트 타입 이름을 키로 핸들러를 분기하고, 4개의 Analyzer가 임계값 기반 이상 탐지를 수행합니다. Java 코드는 JSON 직렬화까지만 담당하고 차트 렌더링은 Plotly.js가 처리하는 데이터·뷰 분리 원칙으로 설계되어, HTML 템플릿 수정 시 Java 코드를 건드릴 필요가 없습니다. JDK 내장 jdk.jfr.consumer API만 사용하므로 별도 파서 라이브러리 없이 동작합니다.
핵심 성과
- ✓JDK 내장 jdk.jfr.consumer API 활용으로 외부 파서 라이브러리 없는 JFR 파싱
- ✓단일 패스 스트리밍으로 수백 MB JFR 파일도 메모리 고갈 없이 처리
- ✓EventRouter + 핸들러 패턴으로 이벤트 타입별 분기 처리 (멀티 구독 지원)
- ✓gcId를 키로 GCHeapSummary + GarbageCollection 이벤트를 조합해 GC 전후 힙 크기 추적
- ✓CPU·GC·메모리·스레드 4개 Analyzer의 임계값 기반 이상 탐지 및 Finding(CRITICAL / WARNING / INFO) 생성
- ✓raw 샘플을 1초 단위 TimeBucket으로 집계하여 Plotly.js 차트 x축 데이터 구성
- ✓AnalysisResult → Jackson JSON 직렬화 후 HTML 템플릿 플레이스홀더 치환으로 단일 HTML 리포트 생성
- ✓데이터·뷰 분리 원칙 — 렌더링 로직을 Java에서 완전히 제거하여 차트 UI 수정 시 Java 코드 변경 불필요
회고
JMC나 벤치마크 리포트와 달리 '대표 수치만 빠르게 훑을 수 있는 단일 파일'이 필요했고, 단일 패스 파싱과 데이터·뷰 분리라는 두 원칙으로 그것을 만들었다. 나중에 쓸 분석 리포트를 미리 만들어두는 발상이 이 프로젝트의 시작점이었다.
- —JFR API는 타입 지정 accessor(getString, getClass 등)를 써야 내부 캐스팅 실패 없이 안전하게 필드를 읽을 수 있다. getValue()가 자연스러워 보이지만 RecordedClass 같은 타입에서는 예외가 발생한다.
- —단일 패스 설계는 핸들러가 집계 상태만 유지하게 강제한다. 이 제약이 오히려 설계를 단순하게 만들었다. 전체를 메모리에 올리는 대신 각 핸들러가 필요한 것만 기억하면 됐다.
- —JSON을 HTML에 주입하는 방식은 렌더링 로직을 Java에서 완전히 분리한다. 백엔드와 프론트엔드 사이에 명확한 계약(JSON 스키마)을 두면 양쪽이 독립적으로 발전할 수 있다는 것을 체감했다.
기술 스택
Java 21JDK JFR API (jdk.jfr.consumer)PicocliJacksonPlotly.js