feat(alerts): add alert for failed systemd services (#2173)

Adds a user-configurable "Failed Services" alert that notifies when any
tracked systemd service enters the failed state, and again when all services
recover.

---------

Signed-off-by: Martin Stenröse <martin@stenrose.se>
Co-authored-by: henrygd <hank@henrygd.me>
This commit is contained in:
Martin Stenröse
2026-09-02 02:41:48 +02:00
committed by GitHub
parent ed88e6efae
commit 097180e8d7
17 changed files with 891 additions and 52 deletions

View File

@@ -37,7 +37,24 @@ func cpuStateAlertValue(name string, breakdown []float64) (float64, bool) {
}
func (am *AlertManager) HandleSystemAlerts(systemRecord *core.Record, data *system.CombinedData) error {
alerts := am.alertsCache.GetAlertsExcludingNames(systemRecord.Id, "Status")
// Systemd alerts are binary state, not numeric thresholds, so they're handled
// separately. They read their own state from the database and don't use data.
// Read the confirmed empty state from the record being saved instead of data:
// dashboard polling can replace the system's in-memory payload concurrently.
var currentInfo system.Info
confirmedEmptySnapshot := false
if err := systemRecord.UnmarshalJSONField("info", &currentInfo); err == nil {
confirmedEmptySnapshot = len(currentInfo.Services) > 0 && currentInfo.Services[0] == 0
}
if err := am.HandleSystemdAlerts(systemRecord, confirmedEmptySnapshot); err != nil {
am.hub.Logger().Error("Error handling systemd alerts", "err", err)
}
if data == nil {
return nil
}
alerts := am.alertsCache.GetAlertsExcludingNames(systemRecord.Id, "Status", alertNameSystemdFailed)
if len(alerts) == 0 {
return nil
}