GN⁺: HN 공개: FlowTracker – Java 프로그램에서 데이터 흐름 추적
(github.com/coekie)FlowTracker: Java 프로그램의 데이터 흐름 추적
FlowTracker는 Java 에이전트로, 프로그램이 데이터를 읽고, 조작하고, 쓰는 방식을 추적함. 이를 통해 파일 및 네트워크 I/O를 확인하고, 입력과 출력을 연결하여 출력이 어디에서 왔는지 보여줌. 이를 통해 Java 프로그램의 출력이 무엇을 의미하는지 이해할 수 있음.
데모
Spring PetClinic은 Spring 프레임워크의 데모 애플리케이션임. FlowTracker의 기능을 보여주기 위해 PetClinic이 HTTP 요청을 처리하고 템플릿과 데이터베이스에서 HTML 페이지를 생성하는 과정을 관찰함. 브라우저에서 데모를 실행하거나 비디오를 시청할 수 있음.
-
HTTP 처리: FlowTracker는 어떤 코드가 어떤 출력을 생성했는지 보여줌. 예를 들어, "HTTP/1.1" 또는 HTTP 헤더를 클릭하면, 이 부분이
org.apache.coyote
패키지의 클래스에 의해 생성되었음을 알 수 있음. -
Thymeleaf 템플릿: 프로그램이 읽은 입력(HTML 템플릿)이 출력과 어떻게 연결되는지 보여줌. HTML 태그 이름을 클릭하면 해당 부분이
layout.html
파일에서 왔음을 알 수 있음. -
데이터베이스: HTML 페이지의 테이블에 있는 정보가 데이터베이스에서 왔음을 보여줌. 예를 들어, 테이블의
George
를 클릭하면 해당 값이 데이터베이스에서 왔음을 알 수 있음.
이 데모는 인메모리 데이터베이스를 사용하여 SQL 스크립트까지 추적할 수 있음. MySQL 데이터베이스를 사용할 경우, 데이터베이스 연결까지 추적할 수 있음.
사용법
FlowTracker는 현재 개념 증명 단계에 있으며, 모든 프로그램에서 잘 작동하지 않을 수 있음. 또한 많은 오버헤드를 추가하여 프로그램 실행 속도를 느리게 만듦. FlowTracker 에이전트 jar 파일을 다운로드하고 Java 명령줄에 추가하여 사용함.
내부 작동 방식
간단한 설명
FlowTracker는 클래스 파일(bytecode)에 코드를 주입하여 메모리 내 데이터와 그 출처를 추적함. 주로 텍스트 및 바이너리 데이터(String, char 및 byte 배열)를 추적함.
- JDK 메서드 호출을 FlowTracker의 메서드 호출로 대체함.
- JDK의 주요 위치에 코드를 주입하여 입력과 출력을 추적함.
- 메서드 내에서 로컬 변수와 스택의 값을 추적하기 위해 데이터 흐름 분석과 더 깊은 계측을 수행함.
- 메서드 호출 전후 및 메서드 시작과 끝에 코드를 추가하여 메서드 인수와 반환 값을 추적함.
데이터 모델: Tracker
FlowTracker의 데이터 모델의 핵심 클래스와 개념:
-
Tracker: 추적 객체의 내용과 출처에 대한 정보를 보유함.
-
content: 데이터를 통과한 내용. 예:
InputStream
또는OutputStream
을 통과한 모든 바이트. - source: 다른 트래커의 소스 범위에 대한 내용의 범위를 연결함.
-
content: 데이터를 통과한 내용. 예:
- TrackerRepository: 흥미로운 객체와 그 트래커를 연결하는 글로벌 맵을 보유함.
- TrackerPoint: 단일 원시 값을 나타내는 트래커의 위치를 가리킴.
기본 계측
Trackers를 최신 상태로 유지하기 위해 특정 JDK 메서드 호출 시 FlowTracker의 hook 메서드 호출을 삽입함. 예를 들어, System.arraycopy
호출을 com.coekie.flowtracker.hook.SystemHook.arraycopy
호출로 대체함.
원시 값, 데이터 흐름 분석
원시 값을 추적하는 것은 더 큰 도전임. 예를 들어, byte
값을 추적하기 위해 메서드 내에서 로컬 변수에 트래커를 저장함.
메서드 호출
원시 값이 메서드 호출의 인수와 반환 값으로 다른 메서드로 흐르는 것을 모델링함. Invocation
을 사용하여 인수와 반환 값의 PointTracker
를 저장함.
코드 자체를 출처로 사용
코드 자체에서 오는 값(예: 원시 및 String 상수)을 추적함. 각 클래스에 대한 트래커를 생성하고, 상수가 참조될 때 해당 트래커를 참조함.
String 리터럴
String 리터럴을 새로 복사하고, String의 내용을 ClassOriginTracker
와 연결함. 예를 들어, String s = "abc";
는 String s = StringHook.constantString("abc", 1234, 81);
로 재작성됨.
추적되지 않은 값에 대한 대체 방법
프로그램의 모든 값을 추적하지 않음. 추적되지 않은 값이 추적해야 하는 위치에 도달하면, 이를 상수와 유사하게 처리함.
GN⁺의 정리
- FlowTracker는 Java 프로그램의 데이터 흐름을 추적하여 프로그램의 출력을 이해하는 데 도움을 줌.
- Spring PetClinic 데모를 통해 HTTP 요청 처리, 템플릿 사용, 데이터베이스 연동을 시각적으로 확인할 수 있음.
- 현재 개념 증명 단계로, 모든 프로그램에서 잘 작동하지 않을 수 있으며, 성능 오버헤드가 큼.
- 데이터 흐름 분석과 메서드 호출 추적을 통해 원시 값과 객체의 출처를 추적함.
- 유사한 기능을 가진 도구로는 Dynatrace, New Relic 등이 있음.
Hacker News 의견
-
Clojure용 FlowStorm이라는 도구를 소개함
- 공식 Clojure 컴파일러를 포크하여 추가 바이트코드를 삽입함
- 대부분의 값이 불변이므로 포인터를 유지하여 스냅샷을 찍을 수 있음
- 웹 앱 디버깅 데모 링크 제공: FlowStorm 데모
-
Java/JVM 생태계의 도구가 매우 훌륭함을 칭찬함
- jitwatch와 비슷한 수준으로 감명받음
- FlowTracker가 taint 분석을 연상시킴
- 관련 키워드: "dynamic taint tracking/analysis"
- 관련 프로젝트 링크:
-
HTML 요소를 SQL 문장까지 추적하는 데모에 감명받음
- 이런 도구가 버그 해결의 첫 번째 방어선이 될 수 있을 것임
-
Smalltalk 환경을 연상시킴
- 모든 객체와 메시지를 추적하고 상호작용할 수 있음
-
데모 비디오가 매우 유용함을 강조함
- 낯선 코드베이스를 탐색할 때 유용할 것임
-
HTML 소스 맵과 유사한 개념을 실험한 경험을 공유함
- 웹 개발 도구가 이러한 전체 스택 속성에서 큰 혜택을 받을 것임
- 기존 프레임워크에 통합하는 것이 큰 도전임
- 관련 프로젝트 링크: HTML Source Maps
-
Eve-lang 데모와 유사함을 언급함
- UI 요소가 왜 없는지 질문하는 방식의 디버깅
- 관련 링크: Eve-lang 데모, Eve-lang 웹사이트
-
SQL 인젝션을 동적으로 찾는 도구와 유사한 논문을 기억함
-
인터넷 상의 데이터를 추적하는 비전을 가졌던 경험을 공유함
- 이미지의 출처나 문자열의 경로를 추적하는 방향으로 나아가는 단계임
-
VSCode와 프로젝트에서 이 도구를 사용해 보려는 시도에 감사함
- 현재는 중단했지만, 다시 시도해 볼 계획임