docs(agent): 统一中文注释并补充部署文档
将代码与测试注释改为中文以符合仓库规范;新增中文部署指南、 示例配置,并完善构建脚本对 VERSION 注入的说明。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -7,23 +7,23 @@ import (
|
||||
"mfd-monitor-agent/internal/status"
|
||||
)
|
||||
|
||||
// namedCollector binds a stable collector name to a collection function.
|
||||
// namedCollector 将稳定的采集器名称与采集函数绑定。
|
||||
type namedCollector struct {
|
||||
name string
|
||||
fn func(context.Context, *status.HostStatus) error
|
||||
}
|
||||
|
||||
// Name returns the collector name used in snapshot error records.
|
||||
// Name 返回用于快照错误记录的采集器名称。
|
||||
func (c namedCollector) Name() string {
|
||||
return c.name
|
||||
}
|
||||
|
||||
// Collect runs the wrapped collection function.
|
||||
// Collect 执行绑定的采集函数。
|
||||
func (c namedCollector) Collect(ctx context.Context, out *status.HostStatus) error {
|
||||
return c.fn(ctx, out)
|
||||
}
|
||||
|
||||
// New returns the default collector set for the current platform.
|
||||
// New 返回当前平台的默认采集器集合。
|
||||
func New(hostID string) []snapshot.Collector {
|
||||
return []snapshot.Collector{
|
||||
namedCollector{name: "system", fn: func(ctx context.Context, out *status.HostStatus) error {
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
var socketInodesFunc = socketInodes
|
||||
var readTCPListenersFunc = readTCPListeners
|
||||
|
||||
// collectSystem fills Linux host identity, OS, architecture, and uptime fields.
|
||||
// collectSystem 从 Linux 填充主机标识、操作系统、架构与运行时长字段。
|
||||
func collectSystem(_ context.Context, hostID string, out *status.HostStatus) error {
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
@@ -44,7 +44,7 @@ func collectSystem(_ context.Context, hostID string, out *status.HostStatus) err
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectNetwork fills Linux network interface, address, and MAC data.
|
||||
// collectNetwork 填充 Linux 网卡、地址与 MAC 数据。
|
||||
func collectNetwork(_ context.Context, out *status.HostStatus) error {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
@@ -75,7 +75,7 @@ func collectNetwork(_ context.Context, out *status.HostStatus) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectResource fills CPU, memory, and disk resource data from Linux proc files.
|
||||
// collectResource 从 Linux /proc 文件填充 CPU、内存与磁盘资源数据。
|
||||
func collectResource(ctx context.Context, out *status.HostStatus) error {
|
||||
out.CPU.LogicalCores = runtime.NumCPU()
|
||||
out.CPU.PhysicalCores, out.CPU.ModelName = readCPUInfo()
|
||||
@@ -90,7 +90,7 @@ func collectResource(ctx context.Context, out *status.HostStatus) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectProcesses reads /proc process directories and degrades to partial when some entries fail.
|
||||
// collectProcesses 读取 /proc 进程目录;部分条目失败时降级为 partial。
|
||||
func collectProcesses(_ context.Context, out *status.HostStatus) error {
|
||||
entries, err := os.ReadDir("/proc")
|
||||
if err != nil {
|
||||
@@ -124,7 +124,7 @@ func collectProcesses(_ context.Context, out *status.HostStatus) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectSockets reads Linux TCP listener tables and maps socket inodes to owning processes.
|
||||
// collectSockets 读取 Linux TCP 监听表,并将 socket inode 映射到所属进程。
|
||||
func collectSockets(_ context.Context, out *status.HostStatus) error {
|
||||
inodes, inodeErr := socketInodesFunc()
|
||||
var listeners []status.TCPListenerInfo
|
||||
@@ -161,7 +161,7 @@ func collectSockets(_ context.Context, out *status.HostStatus) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// readOSRelease returns the Linux PRETTY_NAME value when /etc/os-release is readable.
|
||||
// readOSRelease 在可读时从 /etc/os-release 返回 PRETTY_NAME。
|
||||
func readOSRelease() string {
|
||||
file, err := os.Open("/etc/os-release")
|
||||
if err != nil {
|
||||
@@ -178,7 +178,7 @@ func readOSRelease() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// readUptime returns host uptime in seconds from /proc/uptime.
|
||||
// readUptime 从 /proc/uptime 返回主机运行时长(秒)。
|
||||
func readUptime() uint64 {
|
||||
data, err := os.ReadFile("/proc/uptime")
|
||||
if err != nil {
|
||||
@@ -192,7 +192,7 @@ func readUptime() uint64 {
|
||||
return uint64(value)
|
||||
}
|
||||
|
||||
// readCPUInfo returns physical CPU package count and the first model name from /proc/cpuinfo.
|
||||
// readCPUInfo 从 /proc/cpuinfo 返回物理 CPU 封装数与首个型号名称。
|
||||
func readCPUInfo() (int, string) {
|
||||
file, err := os.Open("/proc/cpuinfo")
|
||||
if err != nil {
|
||||
@@ -222,7 +222,7 @@ func readCPUInfo() (int, string) {
|
||||
return len(physical), model
|
||||
}
|
||||
|
||||
// readLoadAvg returns the 1, 5, and 15 minute Linux load averages when available.
|
||||
// readLoadAvg 在可用时返回 Linux 1/5/15 分钟负载均值。
|
||||
func readLoadAvg() []float64 {
|
||||
data, err := os.ReadFile("/proc/loadavg")
|
||||
if err != nil {
|
||||
@@ -239,7 +239,7 @@ func readLoadAvg() []float64 {
|
||||
return values
|
||||
}
|
||||
|
||||
// readMemory returns Linux memory counters in bytes from /proc/meminfo.
|
||||
// readMemory 从 /proc/meminfo 返回以字节为单位的 Linux 内存计数。
|
||||
func readMemory() status.MemoryInfo {
|
||||
values := map[string]uint64{}
|
||||
file, err := os.Open("/proc/meminfo")
|
||||
@@ -254,8 +254,8 @@ func readMemory() status.MemoryInfo {
|
||||
continue
|
||||
}
|
||||
value, _ := strconv.ParseUint(fields[1], 10, 64)
|
||||
// /proc/meminfo reports memory in KiB; the API exposes bytes and
|
||||
// includes memory.unit so clients can render the values explicitly.
|
||||
// /proc/meminfo 以 KiB 报告内存;API 对外暴露字节,
|
||||
// 并通过 memory.unit 让客户端可明确展示单位。
|
||||
values[strings.TrimSuffix(fields[0], ":")] = value * 1024
|
||||
}
|
||||
total := values["MemTotal"]
|
||||
@@ -269,7 +269,7 @@ func readMemory() status.MemoryInfo {
|
||||
return status.MemoryInfo{Unit: "byte", Total: total, Used: used, Free: free, Available: available, UsedPercent: percent}
|
||||
}
|
||||
|
||||
// readDisks returns physical and network mounted filesystem usage from /proc/mounts and statfs.
|
||||
// readDisks 从 /proc/mounts 与 statfs 返回物理盘与网络挂载文件系统用量。
|
||||
func readDisks() ([]status.DiskInfo, error) {
|
||||
file, err := os.Open("/proc/mounts")
|
||||
if err != nil {
|
||||
@@ -305,7 +305,7 @@ func readDisks() ([]status.DiskInfo, error) {
|
||||
return disks, scanner.Err()
|
||||
}
|
||||
|
||||
// shouldIncludeDiskMount reports whether a mount represents a user-relevant disk.
|
||||
// shouldIncludeDiskMount 判断挂载点是否代表用户关心的磁盘。
|
||||
func shouldIncludeDiskMount(device string, fsType string, total uint64) bool {
|
||||
if total == 0 {
|
||||
return false
|
||||
@@ -319,7 +319,7 @@ func shouldIncludeDiskMount(device string, fsType string, total uint64) bool {
|
||||
return strings.HasPrefix(device, "/dev/")
|
||||
}
|
||||
|
||||
// readProcess returns one Linux process entry from /proc/<pid>.
|
||||
// readProcess 从 /proc/<pid> 返回一条 Linux 进程记录。
|
||||
func readProcess(pid int) (status.ProcessInfo, error) {
|
||||
base := filepath.Join("/proc", strconv.Itoa(pid))
|
||||
statusValues, err := readProcessStatus(filepath.Join(base, "status"))
|
||||
@@ -348,12 +348,12 @@ func readProcess(pid int) (status.ProcessInfo, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// processStat contains process counters parsed from /proc/<pid>/stat.
|
||||
// processStat 包含从 /proc/<pid>/stat 解析的进程计数。
|
||||
type processStat struct {
|
||||
StartTime int64
|
||||
}
|
||||
|
||||
// readProcessStat parses Linux process stat counters from path.
|
||||
// readProcessStat 从路径解析 Linux 进程 stat 计数。
|
||||
func readProcessStat(path string) (processStat, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
@@ -366,7 +366,7 @@ func readProcessStat(path string) (processStat, error) {
|
||||
return processStat{StartTime: startTime}, nil
|
||||
}
|
||||
|
||||
// readProcessStatus parses key-value fields from /proc/<pid>/status.
|
||||
// readProcessStatus 从 /proc/<pid>/status 解析键值字段。
|
||||
func readProcessStatus(path string) (map[string]string, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
@@ -384,7 +384,7 @@ func readProcessStatus(path string) (map[string]string, error) {
|
||||
return values, scanner.Err()
|
||||
}
|
||||
|
||||
// socketInodes maps Linux socket inode numbers to best-effort owning process data.
|
||||
// socketInodes 将 Linux socket inode 映射到尽力获取的所属进程数据。
|
||||
func socketInodes() (map[string]status.ProcessInfo, error) {
|
||||
out := map[string]status.ProcessInfo{}
|
||||
var readErrors int
|
||||
@@ -419,7 +419,7 @@ func socketInodes() (map[string]status.ProcessInfo, error) {
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// readTCPListeners parses a Linux TCP table and returns sockets in LISTEN state.
|
||||
// readTCPListeners 解析 Linux TCP 表并返回处于 LISTEN 状态的套接字。
|
||||
func readTCPListeners(path string, family string, inodes map[string]status.ProcessInfo) ([]status.TCPListenerInfo, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
@@ -429,7 +429,7 @@ func readTCPListeners(path string, family string, inodes map[string]status.Proce
|
||||
var items []status.TCPListenerInfo
|
||||
scanner := bufio.NewScanner(file)
|
||||
if scanner.Scan() {
|
||||
// Skip header.
|
||||
// 跳过表头行。
|
||||
}
|
||||
for scanner.Scan() {
|
||||
fields := strings.Fields(scanner.Text())
|
||||
@@ -449,7 +449,7 @@ func readTCPListeners(path string, family string, inodes map[string]status.Proce
|
||||
return items, scanner.Err()
|
||||
}
|
||||
|
||||
// readCPUUsagePercent samples /proc/stat over a short interval and returns best-effort usage.
|
||||
// readCPUUsagePercent 在短间隔内采样 /proc/stat 并返回尽力估算的 CPU 使用率。
|
||||
func readCPUUsagePercent(ctx context.Context) float64 {
|
||||
prevData, err := os.ReadFile("/proc/stat")
|
||||
if err != nil {
|
||||
@@ -475,7 +475,7 @@ func readCPUUsagePercent(ctx context.Context) float64 {
|
||||
return cpuUsagePercent(prevIdle, prevTotal, nextIdle, nextTotal)
|
||||
}
|
||||
|
||||
// parseAddress decodes a Linux /proc/net/tcp address into IP and port values.
|
||||
// parseAddress 将 Linux /proc/net/tcp 地址解码为 IP 与端口。
|
||||
func parseAddress(raw string, family string) (string, int, error) {
|
||||
parts := strings.Split(raw, ":")
|
||||
if len(parts) != 2 {
|
||||
@@ -502,7 +502,7 @@ func parseAddress(raw string, family string) (string, int, error) {
|
||||
return "", 0, fmt.Errorf("invalid %s address", family)
|
||||
}
|
||||
|
||||
// parseProcessStatStartTime extracts field 22 from Linux /proc/<pid>/stat content.
|
||||
// parseProcessStatStartTime 从 Linux /proc/<pid>/stat 内容提取第 22 字段。
|
||||
func parseProcessStatStartTime(raw string) (int64, error) {
|
||||
end := strings.LastIndex(raw, ")")
|
||||
if end < 0 || end+2 >= len(raw) {
|
||||
@@ -515,7 +515,7 @@ func parseProcessStatStartTime(raw string) (int64, error) {
|
||||
return strconv.ParseInt(fields[19], 10, 64)
|
||||
}
|
||||
|
||||
// parseCPUTimes extracts idle and total jiffy counters from the first cpu line in /proc/stat.
|
||||
// parseCPUTimes 从 /proc/stat 首行 cpu 提取空闲与总 jiffies 计数。
|
||||
func parseCPUTimes(raw string) (idle uint64, total uint64, err error) {
|
||||
scanner := bufio.NewScanner(strings.NewReader(raw))
|
||||
for scanner.Scan() {
|
||||
@@ -544,7 +544,7 @@ func parseCPUTimes(raw string) (idle uint64, total uint64, err error) {
|
||||
return 0, 0, fmt.Errorf("cpu line not found")
|
||||
}
|
||||
|
||||
// cpuUsagePercent calculates non-idle CPU percentage between two /proc/stat samples.
|
||||
// cpuUsagePercent 根据两次 /proc/stat 采样计算非空闲 CPU 百分比。
|
||||
func cpuUsagePercent(prevIdle, prevTotal, nextIdle, nextTotal uint64) float64 {
|
||||
totalDelta := nextTotal - prevTotal
|
||||
if totalDelta == 0 {
|
||||
@@ -557,13 +557,13 @@ func cpuUsagePercent(prevIdle, prevTotal, nextIdle, nextTotal uint64) float64 {
|
||||
return float64(totalDelta-idleDelta) / float64(totalDelta) * 100
|
||||
}
|
||||
|
||||
// parseKB converts the first numeric kilobyte value in raw to bytes.
|
||||
// parseKB 将 raw 中首个以 KiB 表示的数值转换为字节。
|
||||
func parseKB(raw string) uint64 {
|
||||
value, _ := strconv.ParseUint(firstField(raw), 10, 64)
|
||||
return value * 1024
|
||||
}
|
||||
|
||||
// firstField returns the first whitespace-separated token in raw.
|
||||
// firstField 返回 raw 中首个以空白分隔的字段。
|
||||
func firstField(raw string) string {
|
||||
fields := strings.Fields(raw)
|
||||
if len(fields) == 0 {
|
||||
@@ -572,7 +572,7 @@ func firstField(raw string) string {
|
||||
return fields[0]
|
||||
}
|
||||
|
||||
// sortedKeys returns deterministic sorted keys from a string set.
|
||||
// sortedKeys 从字符串集合返回确定顺序的排序键列表。
|
||||
func sortedKeys(values map[string]struct{}) []string {
|
||||
keys := make([]string, 0, len(values))
|
||||
for key := range values {
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"mfd-monitor-agent/internal/status"
|
||||
)
|
||||
|
||||
// TestParseAddressIPv4 verifies Linux IPv4 socket addresses are decoded.
|
||||
// TestParseAddressIPv4 验证 Linux IPv4 套接字地址解码。
|
||||
func TestParseAddressIPv4(t *testing.T) {
|
||||
ip, port, err := parseAddress("0100007F:1F90", "ipv4")
|
||||
if err != nil {
|
||||
@@ -25,7 +25,7 @@ func TestParseAddressIPv4(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestParseAddressIPv6 verifies Linux IPv6 socket addresses are decoded.
|
||||
// TestParseAddressIPv6 验证 Linux IPv6 套接字地址解码。
|
||||
func TestParseAddressIPv6(t *testing.T) {
|
||||
ip, port, err := parseAddress("00000000000000000000000001000000:1F90", "ipv6")
|
||||
if err != nil {
|
||||
@@ -36,7 +36,7 @@ func TestParseAddressIPv6(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestParseProcessStatStartTime verifies field 22 parsing from /proc/<pid>/stat.
|
||||
// TestParseProcessStatStartTime 验证从 /proc/<pid>/stat 解析第 22 字段。
|
||||
func TestParseProcessStatStartTime(t *testing.T) {
|
||||
raw := "1234 (agent worker) S 1 2 3 4 5 0 0 0 0 0 11 22 0 0 20 0 1 0 987654 0 0"
|
||||
|
||||
@@ -49,7 +49,7 @@ func TestParseProcessStatStartTime(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestCPUUsageFromProcStatSamples verifies CPU usage from two /proc/stat samples.
|
||||
// TestCPUUsageFromProcStatSamples 验证由两次 /proc/stat 采样计算 CPU 使用率。
|
||||
func TestCPUUsageFromProcStatSamples(t *testing.T) {
|
||||
prevIdle, prevTotal, err := parseCPUTimes("cpu 100 0 100 800 0 0 0 0 0 0\n")
|
||||
if err != nil {
|
||||
@@ -66,7 +66,7 @@ func TestCPUUsageFromProcStatSamples(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestReadProcessStatReturnsStartTime verifies process start time is exposed.
|
||||
// TestReadProcessStatReturnsStartTime 验证进程启动时间被暴露。
|
||||
func TestReadProcessStatReturnsStartTime(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "stat")
|
||||
raw := "1234 (agent worker) S 1 2 3 4 5 0 0 0 0 0 11 22 0 0 20 0 1 0 987654 0 0"
|
||||
@@ -83,7 +83,7 @@ func TestReadProcessStatReturnsStartTime(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestReadMemoryReturnsBytesWithUnit verifies memory capacity fields are exposed in bytes.
|
||||
// TestReadMemoryReturnsBytesWithUnit 验证内存容量字段以字节暴露。
|
||||
func TestReadMemoryReturnsBytesWithUnit(t *testing.T) {
|
||||
meminfo, err := os.ReadFile("/proc/meminfo")
|
||||
if err != nil {
|
||||
@@ -114,7 +114,7 @@ func TestReadMemoryReturnsBytesWithUnit(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestShouldIncludeDiskMount keeps physical and network disks while dropping pseudo mounts.
|
||||
// TestShouldIncludeDiskMount 保留物理盘与网络盘并排除伪挂载。
|
||||
func TestShouldIncludeDiskMount(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -140,7 +140,7 @@ func TestShouldIncludeDiskMount(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestCollectSocketsMarksPartialWhenProcessFDsUnreadable verifies socket mapping degradation.
|
||||
// TestCollectSocketsMarksPartialWhenProcessFDsUnreadable 验证进程 fd 不可读时套接字映射降级。
|
||||
func TestCollectSocketsMarksPartialWhenProcessFDsUnreadable(t *testing.T) {
|
||||
oldSocketInodes := socketInodesFunc
|
||||
oldReadTCPListeners := readTCPListenersFunc
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"mfd-monitor-agent/internal/status"
|
||||
)
|
||||
|
||||
// collectSystem fills portable host identity fields for non-Linux platforms.
|
||||
// collectSystem 为非 Linux/Windows 平台填充可移植的主机标识字段。
|
||||
func collectSystem(_ context.Context, hostID string, out *status.HostStatus) error {
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
@@ -29,7 +29,7 @@ func collectSystem(_ context.Context, hostID string, out *status.HostStatus) err
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectNetwork fills interface, address, and MAC data using the portable net package.
|
||||
// collectNetwork 使用可移植的 net 包填充网卡、地址与 MAC 数据。
|
||||
func collectNetwork(_ context.Context, out *status.HostStatus) error {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
@@ -56,19 +56,19 @@ func collectNetwork(_ context.Context, out *status.HostStatus) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectResource fills portable resource fields available without platform-specific APIs.
|
||||
// collectResource 填充无需平台专用 API 的可移植资源字段。
|
||||
func collectResource(_ context.Context, out *status.HostStatus) error {
|
||||
out.CPU.LogicalCores = runtime.NumCPU()
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectProcesses reports partial process collection until platform-specific support is added.
|
||||
// collectProcesses 在尚未实现平台专用支持时,将进程采集标记为 partial。
|
||||
func collectProcesses(_ context.Context, out *status.HostStatus) error {
|
||||
out.Processes.Status = "partial"
|
||||
return fmt.Errorf("process collection is not implemented for %s without platform-specific support", runtime.GOOS)
|
||||
}
|
||||
|
||||
// collectSockets reports partial TCP listener collection until platform-specific support is added.
|
||||
// collectSockets 在尚未实现平台专用支持时,将 TCP 监听采集标记为 partial。
|
||||
func collectSockets(_ context.Context, out *status.HostStatus) error {
|
||||
out.TCPListeners.Status = "partial"
|
||||
return fmt.Errorf("tcp listener process mapping is not implemented for %s without platform-specific support", runtime.GOOS)
|
||||
|
||||
@@ -62,7 +62,7 @@ var (
|
||||
windowsLookupAccountSidWProc = windowsAdvapi32.NewProc("LookupAccountSidW")
|
||||
)
|
||||
|
||||
// windowsMemoryStatus mirrors the Windows MEMORYSTATUSEX structure used by GlobalMemoryStatusEx.
|
||||
// windowsMemoryStatus 镜像 GlobalMemoryStatusEx 使用的 Windows MEMORYSTATUSEX 结构。
|
||||
type windowsMemoryStatus struct {
|
||||
Length uint32
|
||||
MemoryLoad uint32
|
||||
@@ -75,7 +75,7 @@ type windowsMemoryStatus struct {
|
||||
AvailExtendedVirtual uint64
|
||||
}
|
||||
|
||||
// windowsMIBTCPRowOwnerPID mirrors a MIB_TCPROW_OWNER_PID row returned by GetExtendedTcpTable.
|
||||
// windowsMIBTCPRowOwnerPID 镜像 GetExtendedTcpTable 返回的 MIB_TCPROW_OWNER_PID 行。
|
||||
type windowsMIBTCPRowOwnerPID struct {
|
||||
State uint32
|
||||
LocalAddr uint32
|
||||
@@ -85,7 +85,7 @@ type windowsMIBTCPRowOwnerPID struct {
|
||||
OwningPID uint32
|
||||
}
|
||||
|
||||
// windowsMIBTCP6RowOwnerPID mirrors a MIB_TCP6ROW_OWNER_PID row returned by GetExtendedTcpTable.
|
||||
// windowsMIBTCP6RowOwnerPID 镜像 GetExtendedTcpTable 返回的 MIB_TCP6ROW_OWNER_PID 行。
|
||||
type windowsMIBTCP6RowOwnerPID struct {
|
||||
State uint32
|
||||
LocalAddr [16]byte
|
||||
@@ -97,7 +97,7 @@ type windowsMIBTCP6RowOwnerPID struct {
|
||||
OwningPID uint32
|
||||
}
|
||||
|
||||
// windowsSystemInfo mirrors the subset of SYSTEM_INFO needed for CPU package sizing.
|
||||
// windowsSystemInfo 镜像 CPU 封装规模计算所需的 SYSTEM_INFO 子集。
|
||||
type windowsSystemInfo struct {
|
||||
ProcessorArchitecture uint16
|
||||
Reserved uint16
|
||||
@@ -112,21 +112,21 @@ type windowsSystemInfo struct {
|
||||
ProcessorRevision uint16
|
||||
}
|
||||
|
||||
// windowsSystemTimes stores system CPU time counters as 100ns units.
|
||||
// windowsSystemTimes 以 100 纳秒为单位存储系统 CPU 时间计数。
|
||||
type windowsSystemTimes struct {
|
||||
Idle uint64
|
||||
Kernel uint64
|
||||
User uint64
|
||||
}
|
||||
|
||||
// windowsLogicalProcessorInformation mirrors SYSTEM_LOGICAL_PROCESSOR_INFORMATION for core counting.
|
||||
// windowsLogicalProcessorInformation 镜像用于统计核心的 SYSTEM_LOGICAL_PROCESSOR_INFORMATION。
|
||||
type windowsLogicalProcessorInformation struct {
|
||||
ProcessorMask uintptr
|
||||
Relationship uint32
|
||||
Data [16]byte
|
||||
}
|
||||
|
||||
// windowsProcessMemoryCounters mirrors PROCESS_MEMORY_COUNTERS.
|
||||
// windowsProcessMemoryCounters 镜像 PROCESS_MEMORY_COUNTERS。
|
||||
type windowsProcessMemoryCounters struct {
|
||||
CB uint32
|
||||
PageFaultCount uint32
|
||||
@@ -140,7 +140,7 @@ type windowsProcessMemoryCounters struct {
|
||||
PeakPagefileUsage uintptr
|
||||
}
|
||||
|
||||
// windowsProcessDetails contains best-effort per-process fields requiring extra handles or commands.
|
||||
// windowsProcessDetails 包含需额外句柄或命令才能获取的尽力进程字段。
|
||||
type windowsProcessDetails struct {
|
||||
Exe string
|
||||
Cmdline string
|
||||
@@ -152,7 +152,7 @@ type windowsProcessDetails struct {
|
||||
MemoryVMS uint64
|
||||
}
|
||||
|
||||
// collectSystem fills Windows host identity, OS, and architecture fields.
|
||||
// collectSystem 填充 Windows 主机标识、操作系统与架构字段。
|
||||
func collectSystem(_ context.Context, hostID string, out *status.HostStatus) error {
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
@@ -170,7 +170,7 @@ func collectSystem(_ context.Context, hostID string, out *status.HostStatus) err
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectNetwork fills Windows interface, address, and MAC data using the portable net package.
|
||||
// collectNetwork 使用可移植 net 包填充 Windows 网卡、地址与 MAC 数据。
|
||||
func collectNetwork(_ context.Context, out *status.HostStatus) error {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
@@ -195,7 +195,7 @@ func collectNetwork(_ context.Context, out *status.HostStatus) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectResource fills Windows CPU, memory, and disk resource data.
|
||||
// collectResource 填充 Windows CPU、内存与磁盘资源数据。
|
||||
func collectResource(ctx context.Context, out *status.HostStatus) error {
|
||||
var errs []error
|
||||
out.CPU.LogicalCores = runtime.NumCPU()
|
||||
@@ -217,7 +217,7 @@ func collectResource(ctx context.Context, out *status.HostStatus) error {
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
// collectProcesses enumerates Windows processes with Toolhelp and returns best-effort names.
|
||||
// collectProcesses 通过 Toolhelp 枚举 Windows 进程并返回尽力获取的名称等信息。
|
||||
func collectProcesses(_ context.Context, out *status.HostStatus) error {
|
||||
processes, err := windowsProcessList()
|
||||
out.Processes.Items = processes
|
||||
@@ -229,7 +229,7 @@ func collectProcesses(_ context.Context, out *status.HostStatus) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectSockets reads Windows TCP listener tables and maps listener PIDs to process names.
|
||||
// collectSockets 读取 Windows TCP 监听表并将监听 PID 映射到进程名。
|
||||
func collectSockets(_ context.Context, out *status.HostStatus) error {
|
||||
processes, processErr := windowsProcessMap()
|
||||
var errs []error
|
||||
@@ -259,7 +259,7 @@ func collectSockets(_ context.Context, out *status.HostStatus) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// windowsReadMemory calls GlobalMemoryStatusEx and converts physical memory counters to API fields.
|
||||
// windowsReadMemory 调用 GlobalMemoryStatusEx 并将物理内存计数转换为 API 字段。
|
||||
func windowsReadMemory() (status.MemoryInfo, error) {
|
||||
memory := windowsMemoryStatus{Length: uint32(unsafe.Sizeof(windowsMemoryStatus{}))}
|
||||
ok, _, err := windowsGlobalMemoryStatusExProc.Call(uintptr(unsafe.Pointer(&memory)))
|
||||
@@ -269,7 +269,7 @@ func windowsReadMemory() (status.MemoryInfo, error) {
|
||||
return windowsMemoryInfoFromStatus(memory), nil
|
||||
}
|
||||
|
||||
// windowsVersion returns the legacy Windows major.minor.build tuple exposed by GetVersion.
|
||||
// windowsVersion 返回 GetVersion 暴露的传统 major.minor.build 版本元组。
|
||||
func windowsVersion() string {
|
||||
version, err := syscall.GetVersion()
|
||||
if err != nil {
|
||||
@@ -281,13 +281,13 @@ func windowsVersion() string {
|
||||
return fmt.Sprintf("%d.%d.%d", major, minor, build)
|
||||
}
|
||||
|
||||
// windowsUptimeSeconds returns host uptime in seconds from GetTickCount64.
|
||||
// windowsUptimeSeconds 从 GetTickCount64 返回主机运行时长(秒)。
|
||||
func windowsUptimeSeconds() uint64 {
|
||||
millis, _, _ := windowsGetTickCount64Proc.Call()
|
||||
return uint64(millis) / 1000
|
||||
}
|
||||
|
||||
// windowsPhysicalCores returns physical CPU core count from Windows processor topology.
|
||||
// windowsPhysicalCores 从 Windows 处理器拓扑返回物理 CPU 核心数。
|
||||
func windowsPhysicalCores() int {
|
||||
var size uint32
|
||||
result, _, _ := windowsGetLogicalProcessorInfoProc.Call(0, uintptr(unsafe.Pointer(&size)))
|
||||
@@ -319,7 +319,7 @@ func windowsPhysicalCores() int {
|
||||
return runtime.NumCPU()
|
||||
}
|
||||
|
||||
// windowsCPUModelName reads the first processor name from the registry.
|
||||
// windowsCPUModelName 从注册表读取首个处理器名称。
|
||||
func windowsCPUModelName() string {
|
||||
keyPath, _ := syscall.UTF16PtrFromString(`HARDWARE\DESCRIPTION\System\CentralProcessor\0`)
|
||||
var key syscall.Handle
|
||||
@@ -344,7 +344,7 @@ func windowsCPUModelName() string {
|
||||
return strings.TrimSpace(syscall.UTF16ToString(utf16s))
|
||||
}
|
||||
|
||||
// windowsReadCPUUsagePercent samples GetSystemTimes and returns best-effort CPU usage.
|
||||
// windowsReadCPUUsagePercent 采样 GetSystemTimes 并返回尽力估算的 CPU 使用率。
|
||||
func windowsReadCPUUsagePercent(ctx context.Context) float64 {
|
||||
prev, err := windowsReadSystemTimes()
|
||||
if err != nil {
|
||||
@@ -362,7 +362,7 @@ func windowsReadCPUUsagePercent(ctx context.Context) float64 {
|
||||
return windowsCPUUsagePercent(prev, next)
|
||||
}
|
||||
|
||||
// windowsReadSystemTimes returns idle, kernel, and user system counters from GetSystemTimes.
|
||||
// windowsReadSystemTimes 从 GetSystemTimes 返回空闲、内核与用户系统计数。
|
||||
func windowsReadSystemTimes() (windowsSystemTimes, error) {
|
||||
var idle, kernel, user syscall.Filetime
|
||||
ok, _, err := windowsGetSystemTimesProc.Call(
|
||||
@@ -376,7 +376,7 @@ func windowsReadSystemTimes() (windowsSystemTimes, error) {
|
||||
return windowsSystemTimes{Idle: windowsFiletimeUint64(idle), Kernel: windowsFiletimeUint64(kernel), User: windowsFiletimeUint64(user)}, nil
|
||||
}
|
||||
|
||||
// windowsCPUUsagePercent calculates non-idle CPU percentage between two Windows CPU samples.
|
||||
// windowsCPUUsagePercent 根据两次 Windows CPU 采样计算非空闲 CPU 百分比。
|
||||
func windowsCPUUsagePercent(prev windowsSystemTimes, next windowsSystemTimes) float64 {
|
||||
prevTotal := prev.Kernel + prev.User
|
||||
nextTotal := next.Kernel + next.User
|
||||
@@ -391,12 +391,12 @@ func windowsCPUUsagePercent(prev windowsSystemTimes, next windowsSystemTimes) fl
|
||||
return float64(totalDelta-idleDelta) / float64(totalDelta) * 100
|
||||
}
|
||||
|
||||
// windowsFiletimeUint64 converts a FILETIME to a monotonically comparable counter.
|
||||
// windowsFiletimeUint64 将 FILETIME 转换为可单调比较的计数。
|
||||
func windowsFiletimeUint64(value syscall.Filetime) uint64 {
|
||||
return uint64(value.HighDateTime)<<32 | uint64(value.LowDateTime)
|
||||
}
|
||||
|
||||
// windowsReadDisks enumerates fixed and remote Windows drives and returns capacity data.
|
||||
// windowsReadDisks 枚举 Windows 本地固定盘与远程盘并返回容量数据。
|
||||
func windowsReadDisks() ([]status.DiskInfo, error) {
|
||||
mask, _, _ := windowsGetLogicalDrivesProc.Call()
|
||||
if mask == 0 {
|
||||
@@ -430,7 +430,7 @@ func windowsReadDisks() ([]status.DiskInfo, error) {
|
||||
return disks, errors.Join(errs...)
|
||||
}
|
||||
|
||||
// windowsDiskInfoFromSpace converts Windows disk capacity counters into API disk fields.
|
||||
// windowsDiskInfoFromSpace 将 Windows 磁盘容量计数转换为 API 磁盘字段。
|
||||
func windowsDiskInfoFromSpace(root string, driveType uint32, total uint64, free uint64) status.DiskInfo {
|
||||
used := uint64(0)
|
||||
if total >= free {
|
||||
@@ -446,7 +446,7 @@ func windowsDiskInfoFromSpace(root string, driveType uint32, total uint64, free
|
||||
}
|
||||
}
|
||||
|
||||
// windowsDriveTypeName maps Windows drive type constants to stable API labels.
|
||||
// windowsDriveTypeName 将 Windows 驱动器类型常量映射为稳定的 API 标签。
|
||||
func windowsDriveTypeName(driveType uint32) string {
|
||||
switch driveType {
|
||||
case windowsDriveFixed:
|
||||
@@ -458,7 +458,7 @@ func windowsDriveTypeName(driveType uint32) string {
|
||||
}
|
||||
}
|
||||
|
||||
// windowsMemoryInfoFromStatus converts Windows physical memory counters into HostStatus memory data.
|
||||
// windowsMemoryInfoFromStatus 将 Windows 物理内存计数转换为 HostStatus 内存数据。
|
||||
func windowsMemoryInfoFromStatus(memory windowsMemoryStatus) status.MemoryInfo {
|
||||
used := uint64(0)
|
||||
if memory.TotalPhys >= memory.AvailPhys {
|
||||
@@ -474,7 +474,7 @@ func windowsMemoryInfoFromStatus(memory windowsMemoryStatus) status.MemoryInfo {
|
||||
}
|
||||
}
|
||||
|
||||
// windowsTCPListeners returns IPv4 or IPv6 TCP listeners from GetExtendedTcpTable.
|
||||
// windowsTCPListeners 从 GetExtendedTcpTable 返回 IPv4 或 IPv6 TCP 监听项。
|
||||
func windowsTCPListeners(family int, familyName string, processes map[int]status.ProcessInfo) ([]status.TCPListenerInfo, error) {
|
||||
table, err := windowsExtendedTCPTable(family)
|
||||
if err != nil {
|
||||
@@ -490,7 +490,7 @@ func windowsTCPListeners(family int, familyName string, processes map[int]status
|
||||
return windowsParseTCP6Rows(table[4:], count, processes), nil
|
||||
}
|
||||
|
||||
// windowsExtendedTCPTable calls GetExtendedTcpTable and returns the raw table bytes.
|
||||
// windowsExtendedTCPTable 调用 GetExtendedTcpTable 并返回原始表字节。
|
||||
func windowsExtendedTCPTable(family int) ([]byte, error) {
|
||||
var size uint32
|
||||
result, _, _ := windowsGetExtendedTCPTableProc.Call(
|
||||
@@ -522,7 +522,7 @@ func windowsExtendedTCPTable(family int) ([]byte, error) {
|
||||
return table, nil
|
||||
}
|
||||
|
||||
// windowsParseTCP4Rows converts raw MIB_TCPROW_OWNER_PID rows into listener records.
|
||||
// windowsParseTCP4Rows 将原始 MIB_TCPROW_OWNER_PID 行转换为监听记录。
|
||||
func windowsParseTCP4Rows(rows []byte, count uint32, processes map[int]status.ProcessInfo) []status.TCPListenerInfo {
|
||||
rowSize := int(unsafe.Sizeof(windowsMIBTCPRowOwnerPID{}))
|
||||
items := make([]status.TCPListenerInfo, 0, count)
|
||||
@@ -546,7 +546,7 @@ func windowsParseTCP4Rows(rows []byte, count uint32, processes map[int]status.Pr
|
||||
return items
|
||||
}
|
||||
|
||||
// windowsParseTCP6Rows converts raw MIB_TCP6ROW_OWNER_PID rows into listener records.
|
||||
// windowsParseTCP6Rows 将原始 MIB_TCP6ROW_OWNER_PID 行转换为监听记录。
|
||||
func windowsParseTCP6Rows(rows []byte, count uint32, processes map[int]status.ProcessInfo) []status.TCPListenerInfo {
|
||||
rowSize := int(unsafe.Sizeof(windowsMIBTCP6RowOwnerPID{}))
|
||||
items := make([]status.TCPListenerInfo, 0, count)
|
||||
@@ -568,13 +568,13 @@ func windowsParseTCP6Rows(rows []byte, count uint32, processes map[int]status.Pr
|
||||
return items
|
||||
}
|
||||
|
||||
// windowsTCPPortFromNetworkOrder decodes the low 16 bits Windows stores in network byte order.
|
||||
// windowsTCPPortFromNetworkOrder 解码 Windows 以网络字节序存储的低 16 位端口。
|
||||
func windowsTCPPortFromNetworkOrder(raw uint32) int {
|
||||
port := uint16(raw)
|
||||
return int(port>>8) | int(port&0xff)<<8
|
||||
}
|
||||
|
||||
// windowsProcessList enumerates processes with the Windows Toolhelp snapshot API.
|
||||
// windowsProcessList 使用 Windows Toolhelp 快照 API 枚举进程。
|
||||
func windowsProcessList() ([]status.ProcessInfo, error) {
|
||||
cmdlines := windowsProcessCommandLines()
|
||||
snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
|
||||
@@ -604,7 +604,7 @@ func windowsProcessList() ([]status.ProcessInfo, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// windowsProcessInfoFromEntry combines Toolhelp identity data with optional process details.
|
||||
// windowsProcessInfoFromEntry 合并 Toolhelp 身份数据与可选进程详情。
|
||||
func windowsProcessInfoFromEntry(entry syscall.ProcessEntry32, details windowsProcessDetails) status.ProcessInfo {
|
||||
name := syscall.UTF16ToString(entry.ExeFile[:])
|
||||
exe := details.Exe
|
||||
@@ -619,7 +619,7 @@ func windowsProcessInfoFromEntry(entry syscall.ProcessEntry32, details windowsPr
|
||||
}
|
||||
}
|
||||
|
||||
// windowsReadProcessDetails opens a process and reads fields that may require elevated privileges.
|
||||
// windowsReadProcessDetails 打开进程并读取可能需要提升权限的字段。
|
||||
func windowsReadProcessDetails(pid uint32) windowsProcessDetails {
|
||||
handle, err := syscall.OpenProcess(windowsProcessQueryLimitedInfo|windowsProcessQueryInformation|windowsProcessVMRead, false, pid)
|
||||
if err != nil {
|
||||
@@ -634,7 +634,7 @@ func windowsReadProcessDetails(pid uint32) windowsProcessDetails {
|
||||
return details
|
||||
}
|
||||
|
||||
// windowsQueryProcessImageName returns the full process image path when access allows it.
|
||||
// windowsQueryProcessImageName 在访问允许时返回完整进程映像路径。
|
||||
func windowsQueryProcessImageName(handle syscall.Handle) string {
|
||||
buf := make([]uint16, windowsMaxPath)
|
||||
size := uint32(len(buf))
|
||||
@@ -650,7 +650,7 @@ func windowsQueryProcessImageName(handle syscall.Handle) string {
|
||||
return syscall.UTF16ToString(buf[:size])
|
||||
}
|
||||
|
||||
// windowsQueryProcessTimes returns start time and lifetime-average CPU percentage.
|
||||
// windowsQueryProcessTimes 返回启动时间与生命周期平均 CPU 百分比。
|
||||
func windowsQueryProcessTimes(handle syscall.Handle) (int64, float64) {
|
||||
var creation, exit, kernel, user syscall.Filetime
|
||||
if err := syscall.GetProcessTimes(handle, &creation, &exit, &kernel, &user); err != nil {
|
||||
@@ -666,7 +666,7 @@ func windowsQueryProcessTimes(handle syscall.Handle) (int64, float64) {
|
||||
return startNanos / int64(time.Second), percent
|
||||
}
|
||||
|
||||
// windowsQueryProcessMemory returns working set and pagefile usage when access allows it.
|
||||
// windowsQueryProcessMemory 在访问允许时返回工作集与页面文件占用。
|
||||
func windowsQueryProcessMemory(handle syscall.Handle) (uint64, uint64) {
|
||||
counters := windowsProcessMemoryCounters{CB: uint32(unsafe.Sizeof(windowsProcessMemoryCounters{}))}
|
||||
ok, _, _ := windowsGetProcessMemoryInfoProc.Call(
|
||||
@@ -680,7 +680,7 @@ func windowsQueryProcessMemory(handle syscall.Handle) (uint64, uint64) {
|
||||
return uint64(counters.WorkingSetSize), uint64(counters.PagefileUsage)
|
||||
}
|
||||
|
||||
// windowsQueryProcessUsername returns DOMAIN\user for a process token when access allows it.
|
||||
// windowsQueryProcessUsername 在访问允许时返回进程令牌的 DOMAIN\user。
|
||||
func windowsQueryProcessUsername(handle syscall.Handle) string {
|
||||
var token syscall.Handle
|
||||
ok, _, _ := windowsOpenProcessTokenProc.Call(uintptr(handle), uintptr(windowsTokenQuery), uintptr(unsafe.Pointer(&token)))
|
||||
@@ -702,7 +702,7 @@ func windowsQueryProcessUsername(handle syscall.Handle) string {
|
||||
return windowsLookupAccountName(sid)
|
||||
}
|
||||
|
||||
// windowsLookupAccountName resolves a SID pointer to DOMAIN\name.
|
||||
// windowsLookupAccountName 将 SID 指针解析为 DOMAIN\name。
|
||||
func windowsLookupAccountName(sid uintptr) string {
|
||||
var nameSize, domainSize uint32
|
||||
var sidType uint32
|
||||
@@ -732,7 +732,7 @@ func windowsLookupAccountName(sid uintptr) string {
|
||||
return domainName + `\` + account
|
||||
}
|
||||
|
||||
// windowsProcessCommandLines reads command lines in one best-effort WMIC call to avoid per-process shelling.
|
||||
// windowsProcessCommandLines 通过一次尽力 WMIC 调用读取命令行,避免逐进程 shell。
|
||||
func windowsProcessCommandLines() map[int]string {
|
||||
out := map[int]string{}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
@@ -760,7 +760,7 @@ func windowsProcessCommandLines() map[int]string {
|
||||
return out
|
||||
}
|
||||
|
||||
// windowsProcessMap returns process metadata keyed by PID for TCP owner mapping.
|
||||
// windowsProcessMap 返回以 PID 为键的进程元数据,供 TCP 属主映射使用。
|
||||
func windowsProcessMap() (map[int]status.ProcessInfo, error) {
|
||||
processes, err := windowsProcessList()
|
||||
out := make(map[int]status.ProcessInfo, len(processes))
|
||||
@@ -770,7 +770,7 @@ func windowsProcessMap() (map[int]status.ProcessInfo, error) {
|
||||
return out, err
|
||||
}
|
||||
|
||||
// windowsSortedKeys returns deterministic sorted keys from a string set.
|
||||
// windowsSortedKeys 从字符串集合返回确定顺序的排序键列表。
|
||||
func windowsSortedKeys(values map[string]struct{}) []string {
|
||||
keys := make([]string, 0, len(values))
|
||||
for key := range values {
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestWindowsMemoryInfoFromStatus verifies Windows memory counters are exposed in bytes.
|
||||
// TestWindowsMemoryInfoFromStatus 验证 Windows 内存计数以字节对外暴露。
|
||||
func TestWindowsMemoryInfoFromStatus(t *testing.T) {
|
||||
got := windowsMemoryInfoFromStatus(windowsMemoryStatus{
|
||||
TotalPhys: 10,
|
||||
@@ -25,14 +25,14 @@ func TestWindowsMemoryInfoFromStatus(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestWindowsTCPPortFromNetworkOrder verifies Windows TCP port values are decoded.
|
||||
// TestWindowsTCPPortFromNetworkOrder 验证 Windows TCP 端口值被正确解码。
|
||||
func TestWindowsTCPPortFromNetworkOrder(t *testing.T) {
|
||||
if got := windowsTCPPortFromNetworkOrder(0x0000901f); got != 8080 {
|
||||
t.Fatalf("port = %d, want 8080", got)
|
||||
}
|
||||
}
|
||||
|
||||
// TestWindowsDiskInfoFromSpace verifies Windows disk counters are mapped to API disk fields.
|
||||
// TestWindowsDiskInfoFromSpace 验证 Windows 磁盘计数映射到 API 磁盘字段。
|
||||
func TestWindowsDiskInfoFromSpace(t *testing.T) {
|
||||
got := windowsDiskInfoFromSpace(`C:\`, windowsDriveFixed, 100, 40)
|
||||
|
||||
@@ -50,7 +50,7 @@ func TestWindowsDiskInfoFromSpace(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestWindowsCPUUsagePercent verifies idle and kernel counters are converted to busy percentage.
|
||||
// TestWindowsCPUUsagePercent 验证空闲与内核计数转换为繁忙百分比。
|
||||
func TestWindowsCPUUsagePercent(t *testing.T) {
|
||||
prev := windowsSystemTimes{Idle: 100, Kernel: 500, User: 500}
|
||||
next := windowsSystemTimes{Idle: 150, Kernel: 650, User: 700}
|
||||
@@ -62,7 +62,7 @@ func TestWindowsCPUUsagePercent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestWindowsProcessInfoFromEntry verifies Toolhelp process data is enriched with memory and command line data.
|
||||
// TestWindowsProcessInfoFromEntry 验证 Toolhelp 进程数据补充内存与命令行信息。
|
||||
func TestWindowsProcessInfoFromEntry(t *testing.T) {
|
||||
entry := syscall.ProcessEntry32{ProcessID: 123, ParentProcessID: 12}
|
||||
copy(entry.ExeFile[:], syscall.StringToUTF16("agent.exe"))
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// networkAddressSets separates interface addresses into deterministic IPv4 and IPv6 lists.
|
||||
// networkAddressSets 将接口地址拆分为确定顺序的 IPv4 与 IPv6 列表。
|
||||
func networkAddressSets(values map[string]struct{}) (ipv4s []string, ipv6s []string) {
|
||||
for value := range values {
|
||||
host, _, err := net.ParseCIDR(value)
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestNetworkAddressSetsSeparatesIPv4AndIPv6 verifies flattened IP lists are split by address family.
|
||||
// TestNetworkAddressSetsSeparatesIPv4AndIPv6 验证展平 IP 列表按地址族拆分。
|
||||
func TestNetworkAddressSetsSeparatesIPv4AndIPv6(t *testing.T) {
|
||||
ipv4s, ipv6s := networkAddressSets(map[string]struct{}{
|
||||
"fe80::1/64": {},
|
||||
|
||||
Reference in New Issue
Block a user