feat: 修复服务器硬件规格(CPU核/内存/磁盘) + Top 5 资源排行
修复: - agent.go ReceiveReport 写入 cpu(核数)/memory(总内存MB)/disk(总磁盘GB) 到 servers 表 - 之前 Agent 上报只写了 cpu_usage/memory_usage/disk_usage 使用率,硬件规格始终为 0 新功能: - GET /api/v1/metrics/top?metric=cpu|memory|disk&limit=5 主机排行 API - HostMonitor 新增 Top 5 排行面板: CPU/内存/磁盘 使用率排名 - TopRankCard 组件: 排名号+主机名+进度条+百分比
This commit is contained in:
1 parent
06d7451cf9
commit
737f00169f
8 files changed
+150
-567
No files matched your search
@@ -76,12 +76,23 @@ func (h *AgentHandler) ReceiveReport(c *gin.Context) {
|
||||
|
||||
// 同步更新 servers 表的实时指标(通过 hostname 匹配)
|
||||
diskAvg := avgDiskUsage(req.Disks)
|
||||
|
||||
// 计算硬件规格
|
||||
totalDiskGB := 0.0
|
||||
for _, d := range req.Disks {
|
||||
totalDiskGB += d.TotalGB
|
||||
}
|
||||
memMB := int64(req.Memory.TotalGB * 1024) // GB → MB
|
||||
|
||||
result := h.db.Model(&models.Server{}).
|
||||
Where("hostname = ? OR ip = ?", req.Hostname, req.Hostname).
|
||||
Updates(map[string]interface{}{
|
||||
"cpu_usage": req.CPU.UsagePercent,
|
||||
"memory_usage": req.Memory.UsagePercent,
|
||||
"disk_usage": diskAvg,
|
||||
"cpu": req.CPU.CoreCount,
|
||||
"memory": memMB,
|
||||
"disk": int64(totalDiskGB),
|
||||
"status": "running",
|
||||
})
|
||||
|
||||
|
||||
@@ -127,6 +127,62 @@ func (h *MetricsHandler) ListMetricNames(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Data: names})
|
||||
}
|
||||
|
||||
// TopHosts 返回指定指标的 Top N 主机排行
|
||||
// GET /api/v1/metrics/top?metric=cpu&limit=5
|
||||
func (h *MetricsHandler) TopHosts(c *gin.Context) {
|
||||
metric := c.DefaultQuery("metric", "cpu")
|
||||
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "5"))
|
||||
|
||||
type HostRank struct {
|
||||
Hostname string `json:"hostname"`
|
||||
IP string `json:"ip"`
|
||||
CPUUsage float64 `json:"cpu_usage"`
|
||||
MemUsage float64 `json:"memory_usage"`
|
||||
DiskUsage float64 `json:"disk_usage"`
|
||||
CPUCores int `json:"cpu_cores"`
|
||||
MemMB int64 `json:"memory_mb"`
|
||||
DiskGB int64 `json:"disk_gb"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
var servers []models.Server
|
||||
orderField := "cpu_usage DESC"
|
||||
switch metric {
|
||||
case "cpu":
|
||||
orderField = "cpu_usage DESC"
|
||||
case "mem", "memory":
|
||||
orderField = "memory_usage DESC"
|
||||
case "disk":
|
||||
orderField = "disk_usage DESC"
|
||||
default:
|
||||
orderField = "cpu_usage DESC"
|
||||
}
|
||||
|
||||
h.db.Where("agent_status = ?", "online").
|
||||
Order(orderField).
|
||||
Limit(limit).
|
||||
Find(&servers)
|
||||
|
||||
result := make([]HostRank, len(servers))
|
||||
for i, s := range servers {
|
||||
result[i] = HostRank{
|
||||
Hostname: s.Hostname,
|
||||
IP: s.IP,
|
||||
CPUUsage: s.CPUUsage,
|
||||
MemUsage: s.MemoryUsage,
|
||||
DiskUsage: s.DiskUsage,
|
||||
CPUCores: s.CPU,
|
||||
MemMB: s.Memory,
|
||||
DiskGB: s.Disk,
|
||||
Status: s.Status,
|
||||
}
|
||||
}
|
||||
if result == nil {
|
||||
result = []HostRank{}
|
||||
}
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Data: result})
|
||||
}
|
||||
|
||||
func now() int64 {
|
||||
return time.Now().Unix()
|
||||
}
|
||||
@@ -473,6 +473,7 @@ func Register(r *gin.Engine, db *gorm.DB, log *zap.Logger, cfg *config.Config, c
|
||||
metricsGroup.GET("/list", metricsHandler.ListMetrics)
|
||||
metricsGroup.GET("/query", metricsHandler.QueryValues)
|
||||
metricsGroup.GET("/names", metricsHandler.ListMetricNames)
|
||||
metricsGroup.GET("/top", metricsHandler.TopHosts)
|
||||
}
|
||||
|
||||
// SNMP 设备管理 — 网络设备/服务器硬件 // Logan.Li
|
||||
|
||||
Reference in new issue
Block a user