HN ra mắt: FlowTracker – Theo dõi luồng dữ liệu trong chương trình Java
(github.com/coekie)FlowTracker: Theo dõi luồng dữ liệu của chương trình Java
FlowTracker là một Java agent dùng để theo dõi cách chương trình đọc, xử lý và ghi dữ liệu. Nhờ đó có thể kiểm tra I/O tệp và mạng, đồng thời liên kết đầu vào với đầu ra để cho thấy đầu ra đến từ đâu. Qua đó, có thể hiểu được đầu ra của chương trình Java thực sự mang ý nghĩa gì.
Demo
Spring PetClinic là ứng dụng demo của framework Spring. Để minh họa khả năng của FlowTracker, có thể quan sát cách PetClinic xử lý yêu cầu HTTP và tạo trang HTML từ template và cơ sở dữ liệu. Bạn có thể chạy demo trong trình duyệt hoặc xem video.
- Xử lý HTTP: FlowTracker cho thấy đoạn mã nào đã tạo ra đầu ra nào. Ví dụ, khi nhấp vào
"HTTP/1.1"hoặc một header HTTP, có thể biết phần này được tạo bởi các lớp trong góiorg.apache.coyote. - Template Thymeleaf: Cho thấy đầu vào mà chương trình đã đọc (template HTML) được liên kết với đầu ra như thế nào. Khi nhấp vào tên thẻ HTML, có thể biết phần đó đến từ tệp
layout.html. - Cơ sở dữ liệu: Cho thấy thông tin trong bảng của trang HTML đến từ cơ sở dữ liệu. Ví dụ, khi nhấp vào
Georgetrong bảng, có thể biết giá trị đó đến từ cơ sở dữ liệu.
Demo này dùng cơ sở dữ liệu in-memory nên có thể truy vết tới cả script SQL. Nếu dùng cơ sở dữ liệu MySQL, còn có thể truy vết tới kết nối cơ sở dữ liệu.
Cách dùng
FlowTracker hiện vẫn ở giai đoạn proof of concept nên có thể không hoạt động tốt với mọi chương trình. Ngoài ra, nó cũng thêm nhiều overhead khiến chương trình chạy chậm hơn. Để sử dụng, hãy tải file jar của agent FlowTracker và thêm nó vào dòng lệnh Java.
Cách hoạt động bên trong
Giải thích ngắn gọn
FlowTracker chèn mã vào class file (bytecode) để theo dõi dữ liệu trong bộ nhớ và nguồn gốc của chúng. Nó chủ yếu theo dõi dữ liệu văn bản và nhị phân (String, mảng char và byte).
- Thay thế lời gọi phương thức JDK bằng lời gọi phương thức của FlowTracker.
- Chèn mã vào các vị trí quan trọng trong JDK để theo dõi đầu vào và đầu ra.
- Thực hiện phân tích luồng dữ liệu và instrumentation sâu hơn để theo dõi giá trị của biến cục bộ và stack trong phương thức.
- Thêm mã trước và sau khi gọi phương thức, cũng như ở đầu và cuối phương thức, để theo dõi đối số và giá trị trả về.
Mô hình dữ liệu: Tracker
Các lớp và khái niệm cốt lõi trong mô hình dữ liệu của FlowTracker:
- Tracker: Giữ thông tin về nội dung và nguồn gốc của đối tượng được theo dõi.
- content: Nội dung mà dữ liệu đã đi qua. Ví dụ: mọi byte đi qua
InputStreamhoặcOutputStream. - source: Liên kết một phạm vi của nội dung với phạm vi nguồn từ các tracker khác.
- content: Nội dung mà dữ liệu đã đi qua. Ví dụ: mọi byte đi qua
- TrackerRepository: Giữ một bản đồ toàn cục liên kết các đối tượng đáng quan tâm với tracker của chúng.
- TrackerPoint: Trỏ tới một vị trí trong tracker biểu diễn một giá trị nguyên thủy đơn lẻ.
Instrumentation cơ bản
Để giữ cho các tracker luôn được cập nhật, FlowTracker chèn lời gọi đến các phương thức hook của mình khi một số phương thức JDK nhất định được gọi. Ví dụ, lời gọi System.arraycopy được thay bằng lời gọi com.coekie.flowtracker.hook.SystemHook.arraycopy.
Giá trị nguyên thủy, phân tích luồng dữ liệu
Theo dõi giá trị nguyên thủy là thách thức lớn hơn. Ví dụ, để theo dõi một giá trị byte, tracker sẽ được lưu trong biến cục bộ bên trong phương thức.
Gọi phương thức
Mô hình hóa việc các giá trị nguyên thủy chảy sang phương thức khác dưới dạng đối số và giá trị trả về của lời gọi phương thức. Sử dụng Invocation để lưu PointTracker của đối số và giá trị trả về.
Dùng chính mã nguồn làm nguồn gốc
Theo dõi các giá trị đến từ chính mã nguồn, chẳng hạn hằng nguyên thủy và hằng String. Một tracker được tạo cho mỗi lớp, và khi một hằng được tham chiếu, tracker tương ứng sẽ được tham chiếu theo.
Literal String
Sao chép mới các literal String và liên kết nội dung của String với ClassOriginTracker. Ví dụ, String s = "abc"; sẽ được viết lại thành String s = StringHook.constantString("abc", 1234, 81);.
Cách thay thế cho giá trị không được theo dõi
Không phải mọi giá trị trong chương trình đều được theo dõi. Khi một giá trị không được theo dõi đi tới vị trí cần phải theo dõi, nó sẽ được xử lý tương tự như một hằng.
Tóm tắt của GN⁺
- FlowTracker theo dõi luồng dữ liệu trong chương trình Java để giúp hiểu đầu ra của chương trình.
- Thông qua demo Spring PetClinic, có thể trực quan quan sát việc xử lý yêu cầu HTTP, sử dụng template và tích hợp cơ sở dữ liệu.
- Hiện công cụ vẫn ở giai đoạn proof of concept, có thể không hoạt động tốt với mọi chương trình và có overhead hiệu năng lớn.
- Thông qua phân tích luồng dữ liệu và theo dõi lời gọi phương thức, công cụ truy vết nguồn gốc của giá trị nguyên thủy và đối tượng.
- Các công cụ có chức năng tương tự gồm có Dynatrace, New Relic, v.v.
1 bình luận
Ý kiến trên Hacker News
Giới thiệu một công cụ tên là FlowStorm cho Clojure
Khen ngợi bộ công cụ của hệ sinh thái Java/JVM là cực kỳ xuất sắc
Ấn tượng với bản demo theo dõi từ phần tử HTML đến câu lệnh SQL
Gợi nhớ đến môi trường Smalltalk
Nhấn mạnh rằng video demo rất hữu ích
Chia sẻ kinh nghiệm từng thử nghiệm một khái niệm tương tự source map cho HTML
Nhắc rằng nó giống với demo Eve-lang
Nhớ đến một bài báo tương tự về công cụ tìm SQL injection theo cách động
Chia sẻ rằng từng có tầm nhìn theo dõi dữ liệu trên Internet
Cảm ơn vì đã thử dùng công cụ này với VSCode và trong dự án