mirror of
https://github.com/henrygd/beszel.git
synced 2026-09-21 08:57:48 +02:00
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:
@@ -250,8 +250,10 @@ func (sys *System) createRecords(data *system.CombinedData) (*core.Record, error
|
||||
}
|
||||
}
|
||||
|
||||
// add new systemd_stats record
|
||||
if len(data.SystemdServices) > 0 {
|
||||
// Update systemd service records when the agent reports a fresh snapshot.
|
||||
// The length check keeps snapshots from older agents working, while the
|
||||
// explicit marker lets newer agents report that a fresh snapshot is empty.
|
||||
if data.SystemdServicesUpdated || len(data.SystemdServices) > 0 {
|
||||
if err := createSystemdStatsRecords(txApp, data.SystemdServices, sys.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -307,7 +309,10 @@ func createSystemDetailsRecord(app core.App, data *system.Details, systemId stri
|
||||
|
||||
func createSystemdStatsRecords(app core.App, data []*systemd.Service, systemId string) error {
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
_, err := app.DB().NewQuery(
|
||||
"DELETE FROM systemd_services WHERE system = {:system}",
|
||||
).Bind(dbx.Params{"system": systemId}).Execute()
|
||||
return err
|
||||
}
|
||||
// shared params for all records
|
||||
params := dbx.Params{
|
||||
@@ -332,7 +337,16 @@ func createSystemdStatsRecords(app core.App, data []*systemd.Service, systemId s
|
||||
"INSERT INTO systemd_services (id, system, name, state, sub, cpu, cpuPeak, memory, memPeak, updated) VALUES %s ON CONFLICT(id) DO UPDATE SET system = excluded.system, name = excluded.name, state = excluded.state, sub = excluded.sub, cpu = excluded.cpu, cpuPeak = excluded.cpuPeak, memory = excluded.memory, memPeak = excluded.memPeak, updated = excluded.updated",
|
||||
strings.Join(valueStrings, ","),
|
||||
)
|
||||
_, err := app.DB().NewQuery(queryString).Bind(params).Execute()
|
||||
if _, err := app.DB().NewQuery(queryString).Bind(params).Execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
// Remove services the agent no longer reports. Every row in this batch shares the
|
||||
// same updated timestamp, so anything older no longer exists on the host. Left in
|
||||
// place these rows survive until the retention sweep and surface inconsistently
|
||||
// across the dashboard, the services table, and alerts.
|
||||
_, err := app.DB().NewQuery(
|
||||
"DELETE FROM systemd_services WHERE system = {:system} AND updated < {:updated}",
|
||||
).Bind(dbx.Params{"system": systemId, "updated": params["updated"]}).Execute()
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user