mirror of
https://github.com/fankes/beszel.git
synced 2025-10-20 02:09:28 +08:00
temperature alerts
This commit is contained in:
@@ -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",
|
alertRecords, err := am.app.Dao().FindRecordsByExpr("alerts",
|
||||||
dbx.NewExp("system={:system}", dbx.Params{"system": systemRecord.GetId()}),
|
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 {
|
for _, alertRecord := range alertRecords {
|
||||||
name := alertRecord.GetString("name")
|
name := alertRecord.GetString("name")
|
||||||
switch name {
|
switch name {
|
||||||
case "CPU", "Memory", "Disk":
|
case "CPU":
|
||||||
if name == "CPU" {
|
am.handleSlidingValueAlert(systemRecord, alertRecord, name, "%", systemInfo.Cpu)
|
||||||
am.handleSlidingValueAlert(systemRecord, alertRecord, name, systemInfo.Cpu)
|
case "Memory":
|
||||||
} else if name == "Memory" {
|
am.handleSlidingValueAlert(systemRecord, alertRecord, name, "%", systemInfo.MemPct)
|
||||||
am.handleSlidingValueAlert(systemRecord, alertRecord, name, systemInfo.MemPct)
|
case "Disk":
|
||||||
} else if name == "Disk" {
|
am.handleSlidingValueAlert(systemRecord, alertRecord, name+" usage", "%", systemInfo.DiskPct)
|
||||||
am.handleSlidingValueAlert(systemRecord, alertRecord, name, 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")
|
triggered := alertRecord.GetBool("triggered")
|
||||||
threshold := alertRecord.GetFloat("value")
|
threshold := alertRecord.GetFloat("value")
|
||||||
// fmt.Println(name, curValue, "threshold", threshold, "triggered", triggered)
|
// fmt.Println(name, curValue, "threshold", threshold, "triggered", triggered)
|
||||||
@@ -73,13 +82,13 @@ func (am *AlertManager) handleSlidingValueAlert(systemRecord *models.Record, ale
|
|||||||
if !triggered && curValue > threshold {
|
if !triggered && curValue > threshold {
|
||||||
alertRecord.Set("triggered", true)
|
alertRecord.Set("triggered", true)
|
||||||
systemName = systemRecord.GetString("name")
|
systemName = systemRecord.GetString("name")
|
||||||
subject = fmt.Sprintf("%s usage above threshold on %s", name, systemName)
|
subject = fmt.Sprintf("%s above threshold on %s", name, systemName)
|
||||||
body = fmt.Sprintf("%s usage on %s is %.1f%%.", name, systemName, curValue)
|
body = fmt.Sprintf("%s on %s is %v%s.", name, systemName, curValue, unit)
|
||||||
} else if triggered && curValue <= threshold {
|
} else if triggered && curValue <= threshold {
|
||||||
alertRecord.Set("triggered", false)
|
alertRecord.Set("triggered", false)
|
||||||
systemName = systemRecord.GetString("name")
|
systemName = systemRecord.GetString("name")
|
||||||
subject = fmt.Sprintf("%s usage below threshold on %s", name, systemName)
|
subject = fmt.Sprintf("%s below threshold on %s", name, systemName)
|
||||||
body = fmt.Sprintf("%s usage on %s is below threshold at %.1f%%.", name, systemName, curValue)
|
body = fmt.Sprintf("%s on %s is below threshold at %v%s.", name, systemName, curValue, unit)
|
||||||
} else {
|
} else {
|
||||||
// fmt.Println(name, "not triggered")
|
// fmt.Println(name, "not triggered")
|
||||||
return
|
return
|
||||||
|
@@ -306,8 +306,8 @@ func (h *Hub) updateSystem(record *models.Record) {
|
|||||||
h.app.Logger().Error("Failed to save record: ", "err", err.Error())
|
h.app.Logger().Error("Failed to save record: ", "err", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// system info alerts (todo: temp alerts, extra fs alerts)
|
// system info alerts (todo: extra fs alerts)
|
||||||
h.am.HandleSystemInfoAlerts(record, systemData.Info)
|
h.am.HandleSystemAlerts(record, systemData.Info, systemData.Stats.Temperatures)
|
||||||
}
|
}
|
||||||
|
|
||||||
// set system to specified status and save record
|
// set system to specified status and save record
|
||||||
|
@@ -82,6 +82,14 @@ export default function AlertsButton({ system }: { system: SystemRecord }) {
|
|||||||
title="Disk Usage"
|
title="Disk Usage"
|
||||||
description="Triggers when root usage exceeds a threshold."
|
description="Triggers when root usage exceeds a threshold."
|
||||||
/>
|
/>
|
||||||
|
<AlertWithSlider
|
||||||
|
system={system}
|
||||||
|
alerts={systemAlerts}
|
||||||
|
name="Temperature"
|
||||||
|
title="Temperature"
|
||||||
|
description="Triggers when any sensor exceeds a threshold."
|
||||||
|
unit=" °C"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
@@ -143,15 +151,17 @@ function AlertWithSlider({
|
|||||||
name,
|
name,
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
|
unit = '%',
|
||||||
}: {
|
}: {
|
||||||
system: SystemRecord
|
system: SystemRecord
|
||||||
alerts: AlertRecord[]
|
alerts: AlertRecord[]
|
||||||
name: string
|
name: string
|
||||||
title: string
|
title: string
|
||||||
description: string
|
description: string
|
||||||
|
unit?: string
|
||||||
}) {
|
}) {
|
||||||
const [pendingChange, setPendingChange] = useState(false)
|
const [pendingChange, setPendingChange] = useState(false)
|
||||||
const [liveValue, setLiveValue] = useState(50)
|
const [liveValue, setLiveValue] = useState(80)
|
||||||
|
|
||||||
const alert = useMemo(() => {
|
const alert = useMemo(() => {
|
||||||
const alert = alerts.find((alert) => alert.name === name)
|
const alert = alerts.find((alert) => alert.name === name)
|
||||||
@@ -215,12 +225,15 @@ function AlertWithSlider({
|
|||||||
onValueChange={(val) => {
|
onValueChange={(val) => {
|
||||||
setLiveValue(val[0])
|
setLiveValue(val[0])
|
||||||
}}
|
}}
|
||||||
min={10}
|
min={1}
|
||||||
max={99}
|
max={99}
|
||||||
// step={1}
|
// step={1}
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
<span className="tabular-nums tracking-tighter text-[.92em]">{liveValue}%</span>
|
<span className="tabular-nums tracking-tighter text-[.92em] shrink-0">
|
||||||
|
{liveValue}
|
||||||
|
{unit}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user