ADR 0007. Bộ thu Windows dùng API trực tiếp trước, PDH để sau
- Trạng thái: Đã chấp nhận (thay thế một phần ADR 0004)
- Ngày: 2026-10-02
Bối cảnh
ADR 0004 chọn PDH với PdhAddEnglishCounter cho mọi chỉ số Windows, kèm API trực tiếp cho RAM, đĩa, uptime, cổng và dịch vụ. Khi bắt tay làm AGT-7 có ba điều đáng cân nhắc lại:
- Không có máy Windows để chạy thử trong môi trường phát triển. Mọi mã gọi hệ thống chỉ biên dịch chéo được, nên bề mặt nhỏ và cấu trúc dữ liệu kiểm tra được lúc biên dịch là lợi thế lớn.
- Mọi chỉ số trong danh mục có đường dẫn không cần PDH:
GetSystemTimes(CPU),GetIfTable2(mạng, bộ đếm 64 bit, có cả gói, lỗi, rơi),GlobalMemoryStatusEx,GetDiskFreeSpaceEx,GetTickCount64. - Các API này không phụ thuộc ngôn ngữ giao diện và không cần quyền
Performance Monitor Users, nên bỏ được hai rủi ro chính của ADR 0004 (bộ đếm bị hỏng,lodctr /R).
Quyết định
- Bộ thu Windows (
internal/collector/windows) chỉ dùng API trực tiếp, gọi bằngsyscall.NewLazyDLLcủa thư viện chuẩn. Mọi DLL (kernel32,advapi32,iphlpapi,ntdll) nằm trong danh sách Go chỉ nạp từ System32. Không thêm phụ thuộcgolang.org/x/sys. - Logic bộ thu chỉ thấy cấu trúc
API(hàm thay được). Lớp gọi hệ thống nằm riêng trongapi_windows.go, các cấu trúc nhị phân (MIB_IF_ROW2,MEMORYSTATUSEX,OSVERSIONINFOEXW) có kiểm tra kích thước lúc biên dịch. - Chỉ số lấy từ PDH (tải CPU kiểu hàng đợi, I/O đĩa,
disk_*_per_sec) chưa làm. Khi cần sẽ thêm bộ thu PDH riêng theo đúng ADR 0004 (PdhAddEnglishCounter, hai mẫu, quản lý handle), không phải viết lại bộ thu hiện có. - Windows không có tải trung bình:
cpu_load1,cpu_load5,cpu_load15,load_per_core_5mchuyển thành chỉ Linux trong danh mục. Không giả lập từ chiều dài hàng đợi vì ý nghĩa khác. - Page file (
swap_*) là ước lượng từMEMORYSTATUSEX: kích thước là giới hạn commit trừ RAM, mức dùng là commit vượt phần RAM đang dùng, cả hai bị chặn vào[0, kích thước]. Giá trị chính xác cần PDHPaging File, sẽ làm cùng bộ thu PDH. - Kiểm tra
servicedùng Service Control Manager với quyền tối thiểu (kết nối SCM, truy vấn trạng thái một dịch vụ), dịch vụ không tồn tại coi là không chạy. Kiểm traportđọc bảng TCP listener và UDP của hệ điều hành (GetExtendedTcpTable,GetExtendedUdpTable), phân tích bằng hàm thuần có giới hạn đọc. Không chạy chương trình nào (ADR 0005). - Tên giao diện mạng là tên kết nối (
Ethernet), bỏ loopback, tunnel và giao diện khôngUp. Ổ đĩa chỉ tính ổ có ký tự (C:), ổ quang bị bỏ, ổ mạng chỉ khiinclude_network_fs. Volume gắn vào thư mục chưa được báo.
Hệ quả
- Mã Windows nhỏ, kiểm thử logic trên mọi máy (xem
docs/08-testing.md), phần gọi hệ thống chỉ kiểm tra được bằng biên dịch chéo ở môi trường này. Việc chạy thật trên Windows 10, 11, Server 2016 đến 2022 (gồm bản không phải tiếng Anh) vẫn là điều kiện đóng AGT-7. - Không còn rủi ro bộ đếm PDH hỏng làm mất chỉ số CPU và mạng.
- Spike S1 của ADR 0004 thu hẹp lại: chỉ còn cần cho I/O đĩa và page file chính xác.
Phương án đã cân nhắc
| Phương án | Lý do không chọn |
|---|---|
| Toàn bộ PDH như ADR 0004 | Nhiều trạng thái (handle, hai mẫu), phụ thuộc bộ đếm có thể hỏng, không chạy thử được ở đây |
Thêm golang.org/x/sys/windows | Thêm phụ thuộc cần duyệt, thư viện chuẩn đủ cho các lệnh gọi cần thiết |
| WMI | Nặng và chậm (xem ADR 0004) |