fix: 修复 Agent 状态与监控大屏

This commit is contained in:
Logan.Li committed 2026-07-27 15:56:03 +08:00
1 parent 83662487cb
commit e557782176
9 files changed
+155 -591

No files matched your search

+38 -29
View File
@@ -61,29 +61,30 @@ func (h *AgentHandler) ReceiveReport(c *gin.Context) {
// 存储到数据库
report := model.AgentReport{
Hostname: req.Hostname,
CPUUsage: req.CPU.UsagePercent,
CPUIOwait: req.CPU.IOWait,
CPUCores: req.CPU.CoreCount,
Load1: req.CPU.Load1,
Load5: req.CPU.Load5,
Load15: req.CPU.Load15,
MemTotal: req.Memory.TotalGB,
MemUsed: req.Memory.UsedGB,
MemUsage: req.Memory.UsagePercent,
Hostname: req.Hostname,
IP: strings.TrimSpace(req.IP), // 使用 Agent 自报 IP,避免反向代理地址误关联。 // Logan.Li
CPUUsage: req.CPU.UsagePercent,
CPUIOwait: req.CPU.IOWait,
CPUCores: req.CPU.CoreCount,
Load1: req.CPU.Load1,
Load5: req.CPU.Load5,
Load15: req.CPU.Load15,
MemTotal: req.Memory.TotalGB,
MemUsed: req.Memory.UsedGB,
MemUsage: req.Memory.UsagePercent,
MemAvailable: req.Memory.AvailableGB,
MemSwapUsed: req.Memory.SwapUsedGB,
DiskInfo: string(diskJSON),
PortInfo: string(portJSON),
NetInfo: string(netJSON),
DiskIOInfo: string(dioJSON),
DiskInfo: string(diskJSON),
PortInfo: string(portJSON),
NetInfo: string(netJSON),
DiskIOInfo: string(dioJSON),
// v2.0 新增
SwapInfo: string(swapJSON),
ProcessTopInfo: string(processTopJSON),
FDInfo: string(fdJSON),
CSInfo: string(csJSON),
HeartbeatInfo: string(heartbeatJSON),
ReportTime: reportTime,
ReportTime: reportTime,
}
if err := h.db.Create(&report).Error; err != nil {
@@ -99,9 +100,9 @@ func (h *AgentHandler) ReceiveReport(c *gin.Context) {
for _, d := range req.Disks {
totalDiskGB += d.TotalGB
}
memGB := math.Ceil(req.Memory.TotalGB) // 31.34 → 32, 62.79 → 63(物理内存向上取整)
memMB := int64(memGB * 1024) // GB → MB
diskGB := int64(totalDiskGB + 0.5) // 39.99 → 40
memGB := math.Ceil(req.Memory.TotalGB) // 31.34 → 32, 62.79 → 63(物理内存向上取整)
memMB := int64(memGB * 1024) // GB → MB
diskGB := int64(totalDiskGB + 0.5) // 39.99 → 40
clientIP := c.ClientIP()
@@ -277,7 +278,7 @@ func (h *AgentHandler) writeHotMetric(c *gin.Context, key string, value float64,
func (h *AgentHandler) GetLatestReports(c *gin.Context) {
var results []model.AgentLatestResponse
threeMinAgo := time.Now().Add(-3 * time.Minute)
// 以 servers 表为主,LEFT JOIN 最近 3 分钟内的 Agent 上报
// 以 servers 表为主,按资产名或 Agent 自报 IP 关联最近 3 分钟内的上报。 // Logan.Li
// 未装 Agent 的主机也会显示(agent_status='not_installed'),打破"不显示→无法安装"的循环
h.db.Raw(`
SELECT
@@ -302,7 +303,8 @@ func (h *AgentHandler) GetLatestReports(c *gin.Context) {
a.report_time,
COALESCE(s.agent_version, '') as agent_version,
CASE
WHEN a.hostname IS NOT NULL THEN COALESCE(s.agent_status, 'online')
WHEN a.id IS NOT NULL THEN 'online'
WHEN COALESCE(s.agent_version, '') <> '' OR COALESCE(s.agent_status, '') = 'online' THEN 'offline'
ELSE 'not_installed'
END as agent_status,
COALESCE(s.os, '') as os,
@@ -312,14 +314,13 @@ func (h *AgentHandler) GetLatestReports(c *gin.Context) {
COALESCE(r.name, '') as region,
CASE WHEN s.password != '' OR s.ssh_key != '' THEN true ELSE false END as has_auth
FROM asset_servers s
LEFT JOIN (
SELECT * FROM monitor_agent_reports
WHERE id IN (
SELECT MAX(id) FROM monitor_agent_reports
WHERE report_time >= ?
GROUP BY hostname
)
) a ON a.hostname = s.hostname
LEFT JOIN monitor_agent_reports a ON a.id = (
SELECT ar.id FROM monitor_agent_reports ar
WHERE ar.report_time >= ?
AND (ar.hostname = s.hostname OR (ar.ip <> '' AND ar.ip = s.ip))
ORDER BY ar.report_time DESC, ar.id DESC
LIMIT 1
)
LEFT JOIN asset_regions r ON r.id = s.region_id
ORDER BY a.report_time DESC, s.id ASC
`, threeMinAgo).Scan(&results)
@@ -409,8 +410,16 @@ func (h *AgentHandler) GetHostHistory(c *gin.Context) {
return
}
var server model.Server
serverIP := ""
if h.db.Where("hostname = ?", hostname).Take(&server).Error == nil {
serverIP = strings.TrimSpace(server.IP)
}
var reports []model.AgentReport
h.db.Where("hostname = ? AND report_time >= ? AND report_time <= ?", hostname, since, until).
// 资产名可能与操作系统主机名不同,优先兼容 Agent 自报 IP。 // Logan.Li
h.db.Where("hostname = ? OR (ip <> '' AND ip = ?)", hostname, serverIP).
Where("report_time >= ? AND report_time <= ?", since, until).
Order("report_time ASC").
Find(&reports)