agent 0.10.0:新增 GET /api/v1/metrics(资源采集,复用 internal/sysinfo;CPU 两次采样差值 + 1 秒内复用上次结果)、GET /api/v1/logs/nginx(日志尾部,路径白名单来自 nginx -T / 环境变量 / 默认目录,32KB 块倒读、单行 4KB 截断、上限 2000 行)、GET /api/v1/frps/config(frps.toml 回读,256KB 上限) internal/sysinfo:补 LoadAvg 与 UptimeSeconds(Linux /proc/loadavg 与 /proc/uptime、Windows GetTickCount64、其它平台空值) 应用侧:AgentClient 三个只读方法;request 错误改为带状态码的 statusError,新增 ErrAgentEndpointMissing,把 404/405 统一转成「agent 版本过低需 ≥ 0.10.0」提示;补 service/handler/router 前端:公网 Agent 页「VPS 资源」横排带(占满环境与依赖整行);日志中心「公网 Nginx」页签;frps 同源配置弹窗「比对 VPS 实际文件」 二进制:内嵌 fonu-agent-linux-amd64 / arm64 用新代码重编;VERSION → 1.2.4
77 lines
1.6 KiB
Go
77 lines
1.6 KiB
Go
//go:build linux
|
||
|
||
package sysinfo
|
||
|
||
import (
|
||
"os"
|
||
"strconv"
|
||
"strings"
|
||
"syscall"
|
||
)
|
||
|
||
func readPlatform() (Stats, CPUSample) {
|
||
var (
|
||
stats Stats
|
||
sample CPUSample
|
||
)
|
||
if raw, err := os.ReadFile("/proc/stat"); err == nil {
|
||
sample = parseProcStat(string(raw))
|
||
}
|
||
if raw, err := os.ReadFile("/proc/meminfo"); err == nil {
|
||
stats.MemTotalBytes, stats.MemUsedBytes = parseMemInfo(string(raw))
|
||
}
|
||
stats.DiskTotalBytes, stats.DiskUsedBytes = diskUsage("/")
|
||
return stats, sample
|
||
}
|
||
|
||
// LoadAvg 返回 1 / 5 / 15 分钟平均负载;读取失败返回 nil
|
||
func LoadAvg() []float64 {
|
||
raw, err := os.ReadFile("/proc/loadavg")
|
||
if err != nil {
|
||
return nil
|
||
}
|
||
fields := strings.Fields(string(raw))
|
||
if len(fields) < 3 {
|
||
return nil
|
||
}
|
||
values := make([]float64, 0, 3)
|
||
for _, field := range fields[:3] {
|
||
value, err := strconv.ParseFloat(field, 64)
|
||
if err != nil {
|
||
return nil
|
||
}
|
||
values = append(values, value)
|
||
}
|
||
return values
|
||
}
|
||
|
||
// UptimeSeconds 返回系统运行秒数(/proc/uptime)
|
||
func UptimeSeconds() uint64 {
|
||
raw, err := os.ReadFile("/proc/uptime")
|
||
if err != nil {
|
||
return 0
|
||
}
|
||
fields := strings.Fields(string(raw))
|
||
if len(fields) == 0 {
|
||
return 0
|
||
}
|
||
seconds, err := strconv.ParseFloat(fields[0], 64)
|
||
if err != nil || seconds < 0 {
|
||
return 0
|
||
}
|
||
return uint64(seconds)
|
||
}
|
||
|
||
func diskUsage(path string) (total, used uint64) {
|
||
var stat syscall.Statfs_t
|
||
if err := syscall.Statfs(path, &stat); err != nil {
|
||
return 0, 0
|
||
}
|
||
total = stat.Blocks * uint64(stat.Bsize)
|
||
free := stat.Bavail * uint64(stat.Bsize)
|
||
if free > total {
|
||
return total, 0
|
||
}
|
||
return total, total - free
|
||
}
|