Files
aiops/agent/collector/mem.go
T
attacker 8240a88a84 feat(k8s): M14 Namespace 管理看板(资源配额 + 命名空间 CRUD)
- 后端: ListNamespacesDetailed/CreateNamespace/DeleteNamespace/ListResourceQuotas/ListLimitRanges
- 后端: GetNamespacesDetail handler (6 API calls aggregate, not N×3)
- 后端: CreateNamespaceHandler + DeleteNamespaceHandler (system NS protection)
- 前端: NamespaceManagementPage.tsx (~280行) — 表格+概览卡片+创建/删除弹框
- 路由: GET/POST/DELETE /:clusterCode/namespaces + GET /namespace/:ns/detail
- 验证: 9/9 通过 (urllib), TS 零错误, Vite 构建成功
2026-06-24 23:46:52 +08:00

106 lines
2.5 KiB
Go

// 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"]
swapTotalKB := values["SwapTotal"]
swapFreeKB := values["SwapFree"]
// 若内核未提供 MemAvailable(较老版本),则按传统方式估算可用内存
if availableKB == 0 {
availableKB = freeKB + buffersKB + cachedKB
}
usedKB := uint64(0)
if totalKB > availableKB {
usedKB = totalKB - availableKB
}
// Swap used
swapUsedKB := uint64(0)
if swapTotalKB > swapFreeKB {
swapUsedKB = swapTotalKB - swapFreeKB
}
stat := model.MemoryStat{
TotalGB: float64(totalKB) * kbToGB,
UsedGB: float64(usedKB) * kbToGB,
CachedGB: float64(buffersKB+cachedKB) * kbToGB,
AvailableGB: float64(availableKB) * kbToGB,
SwapUsedGB: float64(swapUsedKB) * 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
}