agent notifications for server offline/online

This commit is contained in:
headlessdev 2025-04-21 13:31:07 +02:00
parent 1ae8b3e324
commit 8dade95c75

View File

@ -208,6 +208,7 @@ func deleteOldEntries(db *sql.DB) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel() defer cancel()
// Delete old uptime history entries
res, err := db.ExecContext(ctx, res, err := db.ExecContext(ctx,
`DELETE FROM uptime_history WHERE "createdAt" < now() - interval '30 days'`, `DELETE FROM uptime_history WHERE "createdAt" < now() - interval '30 days'`,
) )
@ -216,6 +217,17 @@ func deleteOldEntries(db *sql.DB) error {
} }
affected, _ := res.RowsAffected() affected, _ := res.RowsAffected()
fmt.Printf("Deleted %d old entries from uptime_history\n", affected) fmt.Printf("Deleted %d old entries from uptime_history\n", affected)
// Delete old server history entries
res, err = db.ExecContext(ctx,
`DELETE FROM server_history WHERE "createdAt" < now() - interval '30 days'`,
)
if err != nil {
return err
}
affected, _ = res.RowsAffected()
fmt.Printf("Deleted %d old entries from server_history\n", affected)
return nil return nil
} }
@ -368,6 +380,12 @@ func checkAndUpdateStatus(db *sql.DB, client *http.Client, apps []Application) {
} }
func checkAndUpdateServerStatus(db *sql.DB, client *http.Client, servers []Server) { func checkAndUpdateServerStatus(db *sql.DB, client *http.Client, servers []Server) {
var notificationTemplate string
err := db.QueryRow("SELECT notification_text_server FROM settings LIMIT 1").Scan(&notificationTemplate)
if err != nil || notificationTemplate == "" {
notificationTemplate = "The server !name is now !status!"
}
for _, server := range servers { for _, server := range servers {
if !server.Monitoring || !server.MonitoringURL.Valid { if !server.Monitoring || !server.MonitoringURL.Valid {
continue continue
@ -385,76 +403,110 @@ func checkAndUpdateServerStatus(db *sql.DB, client *http.Client, servers []Serve
if err != nil { if err != nil {
fmt.Printf("%s CPU request failed: %v\n", logPrefix, err) fmt.Printf("%s CPU request failed: %v\n", logPrefix, err)
updateServerStatus(db, server.ID, false, 0, 0, 0) updateServerStatus(db, server.ID, false, 0, 0, 0)
continue online = false
} } else {
defer cpuResp.Body.Close() defer cpuResp.Body.Close()
if cpuResp.StatusCode != http.StatusOK { if cpuResp.StatusCode != http.StatusOK {
fmt.Printf("%s Bad CPU status code: %d\n", logPrefix, cpuResp.StatusCode) fmt.Printf("%s Bad CPU status code: %d\n", logPrefix, cpuResp.StatusCode)
updateServerStatus(db, server.ID, false, 0, 0, 0) updateServerStatus(db, server.ID, false, 0, 0, 0)
continue online = false
} else {
var cpuData CPUResponse
if err := json.NewDecoder(cpuResp.Body).Decode(&cpuData); err != nil {
fmt.Printf("%s Failed to parse CPU JSON: %v\n", logPrefix, err)
updateServerStatus(db, server.ID, false, 0, 0, 0)
online = false
} else {
cpuUsage = cpuData.Total
}
}
} }
var cpuData CPUResponse if online {
if err := json.NewDecoder(cpuResp.Body).Decode(&cpuData); err != nil { // Get Memory usage
fmt.Printf("%s Failed to parse CPU JSON: %v\n", logPrefix, err) memResp, err := client.Get(fmt.Sprintf("%s/api/4/mem", baseURL))
updateServerStatus(db, server.ID, false, 0, 0, 0) if err != nil {
continue fmt.Printf("%s Memory request failed: %v\n", logPrefix, err)
} updateServerStatus(db, server.ID, false, 0, 0, 0)
cpuUsage = cpuData.Total online = false
} else {
defer memResp.Body.Close()
// Get Memory usage if memResp.StatusCode != http.StatusOK {
memResp, err := client.Get(fmt.Sprintf("%s/api/4/mem", baseURL)) fmt.Printf("%s Bad memory status code: %d\n", logPrefix, memResp.StatusCode)
if err != nil { updateServerStatus(db, server.ID, false, 0, 0, 0)
fmt.Printf("%s Memory request failed: %v\n", logPrefix, err) online = false
updateServerStatus(db, server.ID, false, 0, 0, 0) } else {
continue var memData MemoryResponse
} if err := json.NewDecoder(memResp.Body).Decode(&memData); err != nil {
defer memResp.Body.Close() fmt.Printf("%s Failed to parse memory JSON: %v\n", logPrefix, err)
updateServerStatus(db, server.ID, false, 0, 0, 0)
if memResp.StatusCode != http.StatusOK { online = false
fmt.Printf("%s Bad memory status code: %d\n", logPrefix, memResp.StatusCode) } else {
updateServerStatus(db, server.ID, false, 0, 0, 0) ramUsage = memData.Percent
continue }
}
}
} }
var memData MemoryResponse if online {
if err := json.NewDecoder(memResp.Body).Decode(&memData); err != nil { // Get Disk usage
fmt.Printf("%s Failed to parse memory JSON: %v\n", logPrefix, err) fsResp, err := client.Get(fmt.Sprintf("%s/api/4/fs", baseURL))
updateServerStatus(db, server.ID, false, 0, 0, 0) if err != nil {
continue fmt.Printf("%s Filesystem request failed: %v\n", logPrefix, err)
} updateServerStatus(db, server.ID, false, 0, 0, 0)
ramUsage = memData.Percent online = false
} else {
defer fsResp.Body.Close()
// Get Disk usage if fsResp.StatusCode != http.StatusOK {
fsResp, err := client.Get(fmt.Sprintf("%s/api/4/fs", baseURL)) fmt.Printf("%s Bad filesystem status code: %d\n", logPrefix, fsResp.StatusCode)
if err != nil { updateServerStatus(db, server.ID, false, 0, 0, 0)
fmt.Printf("%s Filesystem request failed: %v\n", logPrefix, err) online = false
updateServerStatus(db, server.ID, false, 0, 0, 0) } else {
continue var fsData FSResponse
} if err := json.NewDecoder(fsResp.Body).Decode(&fsData); err != nil {
defer fsResp.Body.Close() fmt.Printf("%s Failed to parse filesystem JSON: %v\n", logPrefix, err)
updateServerStatus(db, server.ID, false, 0, 0, 0)
if fsResp.StatusCode != http.StatusOK { online = false
fmt.Printf("%s Bad filesystem status code: %d\n", logPrefix, fsResp.StatusCode) } else if len(fsData) > 0 {
updateServerStatus(db, server.ID, false, 0, 0, 0) diskUsage = fsData[0].Percent
continue }
}
}
} }
var fsData FSResponse // Check if status changed and send notification if needed
if err := json.NewDecoder(fsResp.Body).Decode(&fsData); err != nil { if online != server.Online {
fmt.Printf("%s Failed to parse filesystem JSON: %v\n", logPrefix, err) status := "offline"
updateServerStatus(db, server.ID, false, 0, 0, 0) if online {
continue status = "online"
} }
// Use the first filesystem entry's percentage message := notificationTemplate
if len(fsData) > 0 { message = strings.ReplaceAll(message, "!name", server.Name)
diskUsage = fsData[0].Percent message = strings.ReplaceAll(message, "!status", status)
sendNotifications(message)
} }
// Update server status with metrics // Update server status with metrics
updateServerStatus(db, server.ID, online, cpuUsage, ramUsage, diskUsage) updateServerStatus(db, server.ID, online, cpuUsage, ramUsage, diskUsage)
// Add entry to server history
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
_, err = db.ExecContext(ctx,
`INSERT INTO server_history(
"serverId", online, "cpuUsage", "ramUsage", "diskUsage", "createdAt"
) VALUES ($1, $2, $3, $4, $5, now())`,
server.ID, online, fmt.Sprintf("%.2f", cpuUsage), fmt.Sprintf("%.2f", ramUsage), fmt.Sprintf("%.2f", diskUsage),
)
cancel()
if err != nil {
fmt.Printf("%s Failed to insert history: %v\n", logPrefix, err)
}
fmt.Printf("%s Updated - CPU: %.2f%%, RAM: %.2f%%, Disk: %.2f%%\n", fmt.Printf("%s Updated - CPU: %.2f%%, RAM: %.2f%%, Disk: %.2f%%\n",
logPrefix, cpuUsage, ramUsage, diskUsage) logPrefix, cpuUsage, ramUsage, diskUsage)
} }