// Package collector 提供服务器各项系统指标的采集能力。 // 本文件实现内存使用率采集,通过解析 Linux /proc/meminfo 获取。 // // 署名 Logan.Li package collector import ( "bufio" "fmt" "os" "strconv" "strings" "ezops/agent/model" ) // kbToGB 将 KB 转换为 GB 的换算系数 const kbToGB = 1.0 / (1024.0 * 1024.0) // MemCollector 内存指标采集器,通过解析 /proc/meminfo 获取 type MemCollector struct{} // NewMemCollector 创建内存采集器实例 func NewMemCollector() *MemCollector { return &MemCollector{} } // Collect 采集当前内存指标 func (m *MemCollector) Collect() (model.MemoryStat, error) { values, err := parseMemInfo() if err != nil { return model.MemoryStat{}, fmt.Errorf("读取内存信息失败: %w", err) } totalKB := values["MemTotal"] buffersKB := values["Buffers"] cachedKB := values["Cached"] availableKB := values["MemAvailable"] freeKB := values["MemFree"] // 若内核未提供 MemAvailable(较老版本),则按传统方式估算可用内存 if availableKB == 0 { availableKB = freeKB + buffersKB + cachedKB } usedKB := uint64(0) if totalKB > availableKB { usedKB = totalKB - availableKB } stat := model.MemoryStat{ TotalGB: float64(totalKB) * kbToGB, UsedGB: float64(usedKB) * kbToGB, CachedGB: float64(buffersKB+cachedKB) * kbToGB, } if totalKB > 0 { stat.UsagePercent = float64(usedKB) / float64(totalKB) * 100.0 } return stat, nil } // parseMemInfo 解析 /proc/meminfo,返回 字段名 -> 数值(KB) 的映射 func parseMemInfo() (map[string]uint64, error) { result := make(map[string]uint64) f, err := os.Open("/proc/meminfo") if err != nil { return nil, err } defer f.Close() scanner := bufio.NewScanner(f) for scanner.Scan() { line := scanner.Text() // 形如: MemTotal: 16384000 kB parts := strings.SplitN(line, ":", 2) if len(parts) != 2 { continue } key := strings.TrimSpace(parts[0]) valFields := strings.Fields(parts[1]) if len(valFields) == 0 { continue } val, err := strconv.ParseUint(valFields[0], 10, 64) if err != nil { continue } result[key] = val } if err := scanner.Err(); err != nil { return nil, err } return result, nil }