feat: pos system event-trigger — state-based threshold monitors (eventer)
Each line of event.env is an independent rule: ["msg" if ] <check> <op> <thr>. Check runs on every pass; first numeric output compared float-safe; op is the rightmost 'op threshold' pair so checks with their own >/< parse fine. Alerts once on false->true + one recovery message on true->false (no repeats while the condition holds); per-rule state keyed by rule-line hash in ~/.local/share/linux_post_install/eventer/state/. Subcommands: run (timer entrypoint), config (interactive add/remove/edit with check-validation), list (rules + live values), enable [interval] (systemd user timer pos-event-trigger.timer; 5m..weekly or OnCalendar; graceful without a user manager, loginctl enable-linger attempt), disable, status. --dry-run honors the DEV.md convention. Alerts via lib/notify.sh (Telegram default). New: bin/pos-system-event-trigger, lib/eventer-lib.sh, config/event.env template (no-clobber via postinstall), install.sh lib install, INTERACTIVE_CMDS entry. Docs: POS.md system row, HOWTO.md index, howto/event-trigger.md. make gen && make check green; functional tests cover trigger/recovery/no-repeat, float+unit parsing, editor add/remove/edit + validation + dry-run, timer enable/disable/status, dispatcher routing.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
# How-To: `pos system event-trigger`
|
||||
|
||||
State-based threshold monitors: each line of `event.env` is an independent rule;
|
||||
when a rule's check crosses its threshold you get one alert (plus one recovery
|
||||
message when it clears). Alerts go through `lib/notify.sh` — Telegram by
|
||||
default, `NOTIFY_PLATFORM` for more.
|
||||
|
||||
```bash
|
||||
pos system event-trigger config # interactive rule editor
|
||||
pos system event-trigger list # rules + live check values
|
||||
pos system event-trigger enable 5m # evaluate every 5 minutes via systemd
|
||||
pos system event-trigger status # timer + rule count
|
||||
pos system event-trigger disable # stop monitoring
|
||||
pos system event-trigger run --dry-run # preview what would fire
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rule format
|
||||
|
||||
One rule per line in `~/.config/linux_post_install/event.env` (chmod 600):
|
||||
|
||||
```
|
||||
["<message>" if ] <check-command> <op> <threshold>
|
||||
```
|
||||
|
||||
| Part | Meaning |
|
||||
|------|---------|
|
||||
| `"<message>" if` | Optional custom alert text (quote-stripped); without it the message is auto-composed |
|
||||
| `<check-command>` | Any shell command; its **first numeric output** is the value (pipes/args fine) |
|
||||
| `<op>` | `>` `<` `>=` `<=` `==` `!=` |
|
||||
| `<threshold>` | Number with optional unit suffix — `60c`, `80%`, `10g` all work |
|
||||
|
||||
The operator is detected as the rightmost `op threshold` pair in the line, so
|
||||
check commands containing their own `>`/`<` (redirection, awk) don't confuse it.
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
# event.env
|
||||
"CPU too hot" if sensors -u | grep -m1 temp1_input | awk '{print $2}' > 60c
|
||||
"Disk nearly full" if df -P / | awk 'NR==2{print $5+0}' > 80%
|
||||
"Load high" if uptime | sed 's/.*load average: //; s/,.*//' >= 4
|
||||
```
|
||||
|
||||
Behavior:
|
||||
|
||||
- The check runs on every pass. Non-numeric/empty output, or an unparseable
|
||||
line → the rule is skipped with a warning (other rules still run).
|
||||
- Alerts fire **once** when the condition turns true, and once more when it
|
||||
recovers — a hot CPU for two hours is one message, not twenty.
|
||||
- State is tracked per rule in `~/.local/share/linux_post_install/eventer/state/`
|
||||
(keyed by a hash of the rule line — editing a rule resets its state).
|
||||
|
||||
## Scheduling
|
||||
|
||||
`enable [interval]` installs a systemd **user timer** (`pos-event-trigger.timer`
|
||||
+ oneshot `.service` that runs `pos system event-trigger run`). Intervals:
|
||||
`5m 10m 15m 30m 45m hourly 2h 6h 12h daily weekly`, or a raw `OnCalendar=…`.
|
||||
Requires a reachable user systemd manager; run
|
||||
`sudo loginctl enable-linger $USER` once so timers fire without login (the tool
|
||||
tries this and warns if it can't).
|
||||
|
||||
## Alerting
|
||||
|
||||
`run` sends via `lib/notify.sh notify_send`, which delivers to every platform in
|
||||
`NOTIFY_PLATFORM` (default `telegram`; comma-separated = fan out). Adding a
|
||||
Matrix/Synapse sender later needs no changes here — see DOC/DEV.md → Alerting.
|
||||
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
- Reference: [DOC/POS.md → system](../POS.md#system)
|
||||
- Notifications: [communication](howto/communication.md) / `lib/notify.sh`
|
||||
Reference in New Issue
Block a user