Fix server notifications been sent multiple times on status change in agent

This commit is contained in:
headlessdev 2025-04-29 20:25:57 +02:00
parent 502f749151
commit ead8bd7408

View File

@ -8,12 +8,21 @@ import (
"io" "io"
"net/http" "net/http"
"strings" "strings"
"sync"
"time" "time"
"github.com/corecontrol/agent/internal/models" "github.com/corecontrol/agent/internal/models"
"github.com/corecontrol/agent/internal/notifications" "github.com/corecontrol/agent/internal/notifications"
) )
// notificationState tracks the last notification time for each server
var notificationState = struct {
sync.RWMutex
lastNotification map[int]time.Time
}{
lastNotification: make(map[int]time.Time),
}
// MonitorServers checks and updates the status of all servers // MonitorServers checks and updates the status of all servers
func MonitorServers(db *sql.DB, client *http.Client, servers []models.Server, notifSender *notifications.NotificationSender) { func MonitorServers(db *sql.DB, client *http.Client, servers []models.Server, notifSender *notifications.NotificationSender) {
var notificationTemplate string var notificationTemplate string
@ -39,7 +48,9 @@ func MonitorServers(db *sql.DB, client *http.Client, servers []models.Server, no
online, cpuUsage = fetchCPUUsage(client, baseURL, logPrefix) online, cpuUsage = fetchCPUUsage(client, baseURL, logPrefix)
if !online { if !online {
updateServerStatus(db, server.ID, false, 0, 0, 0, 0, 0, "") updateServerStatus(db, server.ID, false, 0, 0, 0, 0, 0, "")
sendStatusChangeNotification(server, online, notificationTemplate, notifSender) if shouldSendNotification(server.ID, online) {
sendStatusChangeNotification(server, online, notificationTemplate, notifSender)
}
addServerHistoryEntry(db, server.ID, false, 0, 0, 0, 0, 0) addServerHistoryEntry(db, server.ID, false, 0, 0, 0, 0, 0)
continue continue
} }
@ -52,7 +63,9 @@ func MonitorServers(db *sql.DB, client *http.Client, servers []models.Server, no
if !memOnline { if !memOnline {
online = false online = false
updateServerStatus(db, server.ID, false, 0, 0, 0, 0, 0, "") updateServerStatus(db, server.ID, false, 0, 0, 0, 0, 0, "")
sendStatusChangeNotification(server, online, notificationTemplate, notifSender) if shouldSendNotification(server.ID, online) {
sendStatusChangeNotification(server, online, notificationTemplate, notifSender)
}
addServerHistoryEntry(db, server.ID, false, 0, 0, 0, 0, 0) addServerHistoryEntry(db, server.ID, false, 0, 0, 0, 0, 0)
continue continue
} }
@ -63,7 +76,9 @@ func MonitorServers(db *sql.DB, client *http.Client, servers []models.Server, no
if !diskOnline { if !diskOnline {
online = false online = false
updateServerStatus(db, server.ID, false, 0, 0, 0, 0, 0, "") updateServerStatus(db, server.ID, false, 0, 0, 0, 0, 0, "")
sendStatusChangeNotification(server, online, notificationTemplate, notifSender) if shouldSendNotification(server.ID, online) {
sendStatusChangeNotification(server, online, notificationTemplate, notifSender)
}
addServerHistoryEntry(db, server.ID, false, 0, 0, 0, 0, 0) addServerHistoryEntry(db, server.ID, false, 0, 0, 0, 0, 0)
continue continue
} }
@ -78,7 +93,7 @@ func MonitorServers(db *sql.DB, client *http.Client, servers []models.Server, no
temp = tempVal temp = tempVal
// Check if status changed and send notification if needed // Check if status changed and send notification if needed
if online != server.Online { if online != server.Online && shouldSendNotification(server.ID, online) {
sendStatusChangeNotification(server, online, notificationTemplate, notifSender) sendStatusChangeNotification(server, online, notificationTemplate, notifSender)
} }
@ -93,6 +108,23 @@ func MonitorServers(db *sql.DB, client *http.Client, servers []models.Server, no
} }
} }
// shouldSendNotification checks if a notification should be sent based on cooldown period
func shouldSendNotification(serverID int, online bool) bool {
notificationState.Lock()
defer notificationState.Unlock()
lastNotif, exists := notificationState.lastNotification[serverID]
now := time.Now()
// If no previous notification or more than 5 minutes have passed
if !exists || now.Sub(lastNotif) > 5*time.Minute {
notificationState.lastNotification[serverID] = now
return true
}
return false
}
// Helper function to fetch CPU usage // Helper function to fetch CPU usage
func fetchCPUUsage(client *http.Client, baseURL, logPrefix string) (bool, float64) { func fetchCPUUsage(client *http.Client, baseURL, logPrefix string) (bool, float64) {
cpuResp, err := client.Get(fmt.Sprintf("%s/api/4/cpu", baseURL)) cpuResp, err := client.Get(fmt.Sprintf("%s/api/4/cpu", baseURL))