From 10d348c052689c30d941bf45c47c553b2ea62be2 Mon Sep 17 00:00:00 2001 From: Henry Dollman Date: Sat, 12 Oct 2024 14:57:46 -0400 Subject: [PATCH] temperature alerts --- beszel/internal/alerts/alerts.go | 35 +++++++++++++-------- beszel/internal/hub/hub.go | 4 +-- beszel/site/src/components/table-alerts.tsx | 19 +++++++++-- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/beszel/internal/alerts/alerts.go b/beszel/internal/alerts/alerts.go index 922492c..bfdc7c2 100644 --- a/beszel/internal/alerts/alerts.go +++ b/beszel/internal/alerts/alerts.go @@ -39,7 +39,7 @@ func NewAlertManager(app *pocketbase.PocketBase) *AlertManager { } } -func (am *AlertManager) HandleSystemInfoAlerts(systemRecord *models.Record, systemInfo system.Info) { +func (am *AlertManager) HandleSystemAlerts(systemRecord *models.Record, systemInfo system.Info, temperatures map[string]float64) { alertRecords, err := am.app.Dao().FindRecordsByExpr("alerts", dbx.NewExp("system={:system}", dbx.Params{"system": systemRecord.GetId()}), ) @@ -51,19 +51,28 @@ func (am *AlertManager) HandleSystemInfoAlerts(systemRecord *models.Record, syst for _, alertRecord := range alertRecords { name := alertRecord.GetString("name") switch name { - case "CPU", "Memory", "Disk": - if name == "CPU" { - am.handleSlidingValueAlert(systemRecord, alertRecord, name, systemInfo.Cpu) - } else if name == "Memory" { - am.handleSlidingValueAlert(systemRecord, alertRecord, name, systemInfo.MemPct) - } else if name == "Disk" { - am.handleSlidingValueAlert(systemRecord, alertRecord, name, systemInfo.DiskPct) + case "CPU": + am.handleSlidingValueAlert(systemRecord, alertRecord, name, "%", systemInfo.Cpu) + case "Memory": + am.handleSlidingValueAlert(systemRecord, alertRecord, name, "%", systemInfo.MemPct) + case "Disk": + am.handleSlidingValueAlert(systemRecord, alertRecord, name+" usage", "%", systemInfo.DiskPct) + case "Temperature": + if temperatures == nil { + continue } + highTemp := 0.0 + for _, temp := range temperatures { + if temp > highTemp { + highTemp = temp + } + } + am.handleSlidingValueAlert(systemRecord, alertRecord, name, "°C", highTemp) } } } -func (am *AlertManager) handleSlidingValueAlert(systemRecord *models.Record, alertRecord *models.Record, name string, curValue float64) { +func (am *AlertManager) handleSlidingValueAlert(systemRecord *models.Record, alertRecord *models.Record, name, unit string, curValue float64) { triggered := alertRecord.GetBool("triggered") threshold := alertRecord.GetFloat("value") // fmt.Println(name, curValue, "threshold", threshold, "triggered", triggered) @@ -73,13 +82,13 @@ func (am *AlertManager) handleSlidingValueAlert(systemRecord *models.Record, ale if !triggered && curValue > threshold { alertRecord.Set("triggered", true) systemName = systemRecord.GetString("name") - subject = fmt.Sprintf("%s usage above threshold on %s", name, systemName) - body = fmt.Sprintf("%s usage on %s is %.1f%%.", name, systemName, curValue) + subject = fmt.Sprintf("%s above threshold on %s", name, systemName) + body = fmt.Sprintf("%s on %s is %v%s.", name, systemName, curValue, unit) } else if triggered && curValue <= threshold { alertRecord.Set("triggered", false) systemName = systemRecord.GetString("name") - subject = fmt.Sprintf("%s usage below threshold on %s", name, systemName) - body = fmt.Sprintf("%s usage on %s is below threshold at %.1f%%.", name, systemName, curValue) + subject = fmt.Sprintf("%s below threshold on %s", name, systemName) + body = fmt.Sprintf("%s on %s is below threshold at %v%s.", name, systemName, curValue, unit) } else { // fmt.Println(name, "not triggered") return diff --git a/beszel/internal/hub/hub.go b/beszel/internal/hub/hub.go index 19ca016..b6d97fd 100644 --- a/beszel/internal/hub/hub.go +++ b/beszel/internal/hub/hub.go @@ -306,8 +306,8 @@ func (h *Hub) updateSystem(record *models.Record) { h.app.Logger().Error("Failed to save record: ", "err", err.Error()) } } - // system info alerts (todo: temp alerts, extra fs alerts) - h.am.HandleSystemInfoAlerts(record, systemData.Info) + // system info alerts (todo: extra fs alerts) + h.am.HandleSystemAlerts(record, systemData.Info, systemData.Stats.Temperatures) } // set system to specified status and save record diff --git a/beszel/site/src/components/table-alerts.tsx b/beszel/site/src/components/table-alerts.tsx index 933e394..1273e55 100644 --- a/beszel/site/src/components/table-alerts.tsx +++ b/beszel/site/src/components/table-alerts.tsx @@ -82,6 +82,14 @@ export default function AlertsButton({ system }: { system: SystemRecord }) { title="Disk Usage" description="Triggers when root usage exceeds a threshold." /> + @@ -143,15 +151,17 @@ function AlertWithSlider({ name, title, description, + unit = '%', }: { system: SystemRecord alerts: AlertRecord[] name: string title: string description: string + unit?: string }) { const [pendingChange, setPendingChange] = useState(false) - const [liveValue, setLiveValue] = useState(50) + const [liveValue, setLiveValue] = useState(80) const alert = useMemo(() => { const alert = alerts.find((alert) => alert.name === name) @@ -215,12 +225,15 @@ function AlertWithSlider({ onValueChange={(val) => { setLiveValue(val[0]) }} - min={10} + min={1} max={99} // step={1} /> - {liveValue}% + + {liveValue} + {unit} + )}