- 支持 Windows Agent 构建、安装脚本和统一上报协议 - 增强 RDP 剪贴板、虚拟盘和文件传输能力 - 新增 AIOps 上下文工具、告警 RCA trace 落库和回放接口 - 重构 docs 模块文档并补充终端、堡垒机、监控、AI Agent 设计
108 lines
2.5 KiB
Go
108 lines
2.5 KiB
Go
//go:build !windows
|
|
|
|
// 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
|
|
}
|