From 3147c98399c23b208c5691c766493353ad5ea1b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20R=C3=B6=C3=B6s?= Date: Tue, 9 Jun 2026 12:53:53 +0200 Subject: [PATCH] alert: give alerts their own severity levels Decouple alert severity from the event-log (syslog) levels. alert.h now defines alert_level_t {NOTICE, WARNING, ATTENTION, ERROR}, ordered by ascending severity with ATTENTION sitting between WARNING and ERROR. ac_level and alert_level_to_string are retyped to alert_level_t. The climate_zone and power_rail sources map their states onto the new scale (error/critical -> ERROR, otherwise WARNING). When an alert is written into the system log, alert_set maps the alert level to an event level (ATTENTION has no distinct event-log slot, so it logs as WARNING). The eventlog levels and the log wire/flash format are unchanged. The alert service already carries the level in a full byte, so the alert wire format is unaffected. --- include/mios/alert.h | 13 +++++++++++-- src/lib/hw/climate_zone.c | 6 +++--- src/lib/hw/power_rail.c | 6 +++--- src/util/alert.c | 31 +++++++++++++++++++++++-------- 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/include/mios/alert.h b/include/mios/alert.h index a07c9a88..5a1ac082 100644 --- a/include/mios/alert.h +++ b/include/mios/alert.h @@ -6,6 +6,15 @@ #include "eventlog.h" +// Alert severity, independent of the event-log levels. Ordered by +// ascending severity: ATTENTION sits between WARNING and ERROR. +typedef enum { + ALERT_LEVEL_NOTICE, + ALERT_LEVEL_WARNING, + ALERT_LEVEL_ATTENTION, + ALERT_LEVEL_ERROR, +} alert_level_t; + typedef struct alert_source { SLIST_ENTRY(alert_source) as_link; const struct alert_class *as_class; @@ -16,7 +25,7 @@ typedef struct alert_source { typedef struct alert_class { void (*ac_message)(const struct alert_source *as, struct stream *output); - event_level_t (*ac_level)(const struct alert_source *as); + alert_level_t (*ac_level)(const struct alert_source *as); void (*ac_refcount)(struct alert_source *as, int value); } alert_class_t; @@ -30,4 +39,4 @@ int alert_set(alert_source_t *as, int code); alert_source_t *alert_get_next(alert_source_t *as); -const char *alert_level_to_string(event_level_t level); +const char *alert_level_to_string(alert_level_t level); diff --git a/src/lib/hw/climate_zone.c b/src/lib/hw/climate_zone.c index 0a463c71..910e0201 100644 --- a/src/lib/hw/climate_zone.c +++ b/src/lib/hw/climate_zone.c @@ -108,7 +108,7 @@ climate_zone_alert_message(const struct alert_source *as, struct stream *output) } -static event_level_t +static alert_level_t climate_zone_alert_level(const struct alert_source *as) { if(as->as_code & (CLIMATE_ZONE_OT_ERROR | @@ -120,8 +120,8 @@ climate_zone_alert_level(const struct alert_source *as) CLIMATE_ZONE_TEMP_SENSE_ERROR | CLIMATE_ZONE_RH_SENSE_ERROR | CLIMATE_ZONE_FAN_SENSE_ERROR)) - return LOG_ERR; - return LOG_WARNING; + return ALERT_LEVEL_ERROR; + return ALERT_LEVEL_WARNING; } __attribute__((always_inline)) diff --git a/src/lib/hw/power_rail.c b/src/lib/hw/power_rail.c index aeb8c429..5124ab64 100644 --- a/src/lib/hw/power_rail.c +++ b/src/lib/hw/power_rail.c @@ -107,7 +107,7 @@ power_rail_alert_message(const struct alert_source *as, struct stream *output) } -static event_level_t +static alert_level_t power_rail_alert_level(const struct alert_source *as) { if(as->as_code & (POWER_RAIL_TEMP_CRIT | @@ -117,8 +117,8 @@ power_rail_alert_level(const struct alert_source *as) POWER_RAIL_OC_ALERT | POWER_RAIL_UC_ALERT | POWER_RAIL_FAULT)) - return LOG_ALERT; - return LOG_WARNING; + return ALERT_LEVEL_ERROR; + return ALERT_LEVEL_WARNING; } diff --git a/src/util/alert.c b/src/util/alert.c index c8a4a036..b5d73b8f 100644 --- a/src/util/alert.c +++ b/src/util/alert.c @@ -47,6 +47,21 @@ alert_unregister(alert_source_t *as) alert_source_refcount(as, -1); } +// Map an alert severity onto the event-log level used when the alert +// is written into the system log. ATTENTION has no distinct event-log +// slot, so it logs as WARNING. +static event_level_t +alert_level_to_event_level(alert_level_t level) +{ + switch(level) { + case ALERT_LEVEL_NOTICE: return LOG_NOTICE; + case ALERT_LEVEL_WARNING: return LOG_WARNING; + case ALERT_LEVEL_ATTENTION: return LOG_WARNING; + case ALERT_LEVEL_ERROR: return LOG_ERR; + } + return LOG_WARNING; +} + int alert_set(alert_source_t *as, int code) { @@ -62,7 +77,7 @@ alert_set(alert_source_t *as, int code) stprintf(st, "Alert raised [%s] -- ", as->as_key); const alert_class_t *ac = as->as_class; ac->ac_message(as, st); - evlog_stream_end(ac->ac_level(as)); + evlog_stream_end(alert_level_to_event_level(ac->ac_level(as))); } ghook_invoke(GHOOK_ALERT_UPDATED); @@ -89,12 +104,12 @@ alert_get_next(alert_source_t *cur) return as; } -#define LEVELTBL "EMERG\0ALERT\0CRIT\0ERROR\0WARNING\0NOTICE\0INFO\0DEBUG\0\0" +#define LEVELTBL "NOTICE\0WARNING\0ATTENTION\0ERROR\0\0" const char * -alert_level_to_string(event_level_t level) +alert_level_to_string(alert_level_t level) { - return strtbl(LEVELTBL, level & 7); + return strtbl(LEVELTBL, level & 3); } @@ -112,10 +127,10 @@ fake_alert_message(const struct alert_source *as, struct stream *output) } -static event_level_t +static alert_level_t fake_alert_level(const struct alert_source *as) { - return LOG_WARNING; + return ALERT_LEVEL_WARNING; } static void @@ -166,7 +181,7 @@ cmd_alert(cli_t *cli, int argc, char **argv) return raise_fake_alert(cli, argv[2]); } - cli_printf(cli, "Name Severity Details\n"); + cli_printf(cli, "Name Severity Details\n"); cli_printf(cli, "========================================================\n"); while((as = alert_get_next(as)) != NULL) { @@ -177,7 +192,7 @@ cmd_alert(cli_t *cli, int argc, char **argv) continue; } - cli_printf(cli, "%-8s ", + cli_printf(cli, "%-9s ", alert_level_to_string(as->as_class->ac_level(as))); as->as_class->ac_message(as, cli->cl_stream); cli_printf(cli, "\n");