report: Noise-Eskalations-Befreiung fuer dauerhaft-laute Benign-Patterns

Bekannte Noise-Patterns, die strukturell sehr laut sind (Unraid-mdadm-Spam
~5760/Tag, Fritz!Box-SOA ~1170/Tag), hielten den Report-Status dauerhaft
auf >= WARNUNG ueber noise_threshold_exceeded und entwerteten damit die
Ampel - das System konnte nie OK erreichen, egal wie gesund.

Neue Datei noise-escalation-exempt.patterns listet solche Patterns. Sie
zaehlen weiterhin als Noise und erscheinen in der Breakdown-Tabelle (jetzt
mit Hinweis-Spalte "eskalations-befreit"), zaehlen aber nicht mehr zu
noise_threshold_exceeded. Neue/unerwartete laute Patterns eskalieren
weiterhin zur WARNUNG. Jede Befreiung traegt Begruendung + Recheck.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 15:15:10 +02:00
parent 8bb250220b
commit e89b88a513
2 changed files with 77 additions and 8 deletions
+45 -8
View File
@@ -29,6 +29,7 @@ TRAEFIK_ACME_PATH="${TRAEFIK_ACME_PATH:-/mnt/user/appdata/traefik/letsencrypt/ac
NOISE_PATTERNS_FILE="${NOISE_PATTERNS_FILE:-/mnt/user/services/homelab-infra/services/posture-check/log-noise.patterns}"
NORMALIZE_NOISE_SCRIPT="${NORMALIZE_NOISE_SCRIPT:-/mnt/user/services/homelab-infra/services/posture-check/lib/normalize-noise-patterns.sh}"
NOISE_ESCALATION_THRESHOLD="${NOISE_ESCALATION_THRESHOLD:-500}"
NOISE_ESCALATION_EXEMPT_FILE="${NOISE_ESCALATION_EXEMPT_FILE:-/mnt/user/services/homelab-infra/services/posture-check/noise-escalation-exempt.patterns}"
NOISE_BREAKDOWN_TOP_N="${NOISE_BREAKDOWN_TOP_N:-10}"
POSTURE_CHECK_FILE="${POSTURE_CHECK_FILE:-/mnt/user/services/posture-check/last.json}"
LOCK_FILE="${LOCK_FILE:-/tmp/homelab-daily-report.lock}"
@@ -880,12 +881,35 @@ collect_log_highlights() {
fi
fi
# Threshold escalation: how many patterns produced more than the threshold?
local noise_threshold_exceeded=0
# Escalation-exempt patterns: known noise that is also permanently very loud
# (e.g. Unraid mdadm parse spam). Without this, such a pattern would keep the
# report stuck at >= WARNUNG forever and devalue the OK/WARNUNG/KRITISCH
# signal. Exempt patterns are still counted/shown as noise, but do NOT count
# toward noise_threshold_exceeded. New/unexpected loud patterns still escalate.
local noise_exempt="$TMP_DIR/noise-escalation-exempt.normalized"
: > "$noise_exempt"
if [ -f "$NOISE_ESCALATION_EXEMPT_FILE" ]; then
grep -Ev '^[[:space:]]*(#|$)' "$NOISE_ESCALATION_EXEMPT_FILE" 2>/dev/null \
| sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//' \
| grep -v '^$' > "$noise_exempt" || : > "$noise_exempt"
fi
# Threshold escalation: how many NON-exempt patterns exceeded the threshold?
local noise_threshold_exceeded=0 noise_threshold_exempt=0
if [ -s "$noise_by_pattern" ]; then
noise_threshold_exceeded="$(awk -v t="$NOISE_ESCALATION_THRESHOLD" '$1 > t { n++ } END { print n + 0 }' "$noise_by_pattern")"
noise_threshold_exceeded="$(awk -F '\t' -v t="$NOISE_ESCALATION_THRESHOLD" '
NR == FNR { exempt[$0] = 1; next }
$1 > t && !($2 in exempt) { n++ }
END { print n + 0 }
' "$noise_exempt" "$noise_by_pattern")"
noise_threshold_exempt="$(awk -F '\t' -v t="$NOISE_ESCALATION_THRESHOLD" '
NR == FNR { exempt[$0] = 1; next }
$1 > t && ($2 in exempt) { n++ }
END { print n + 0 }
' "$noise_exempt" "$noise_by_pattern")"
fi
set_summary "noise_threshold_exceeded" "$noise_threshold_exceeded"
set_summary "noise_threshold_exempt" "$noise_threshold_exempt"
local hit_count attention_count known_noise_count
hit_count="$(count_lines < "$hits")"
@@ -906,6 +930,9 @@ collect_log_highlights() {
if [ "$noise_threshold_exceeded" -gt 0 ]; then
append "- WARNUNG: $noise_threshold_exceeded Pattern ueberschreit(en) die Schwelle - bitte pruefen ob noch wirklich Noise."
fi
if [ "${noise_threshold_exempt:-0}" -gt 0 ]; then
append "- Hinweis: $noise_threshold_exempt laute(s) Pattern ist/sind als bewusst eskalations-befreit markiert (siehe \`$NOISE_ESCALATION_EXEMPT_FILE\`) und loesen keine WARNUNG aus."
fi
append ""
if [ "$attention_count" -eq 0 ]; then
@@ -955,22 +982,32 @@ collect_log_highlights() {
if [ -s "$noise_by_pattern" ]; then
append "#### Pattern mit den meisten Treffern"
append ""
append "| Pattern | Anzahl |"
append "|---|---:|"
append "| Pattern | Anzahl | Hinweis |"
append "|---|---:|---|"
head -n "$NOISE_BREAKDOWN_TOP_N" "$noise_by_pattern" \
| while IFS="$(printf '\t')" read -r cnt pat; do
local short="$pat"
local short="$pat" note=""
# Mark patterns that are deliberately exempt from escalation.
if [ -s "$noise_exempt" ] && grep -Fxq -- "$pat" "$noise_exempt"; then
if [ "$cnt" -gt "$NOISE_ESCALATION_THRESHOLD" ]; then
note="eskalations-befreit"
fi
elif [ "$cnt" -gt "$NOISE_ESCALATION_THRESHOLD" ]; then
note="ueber Schwelle"
fi
if [ "${#short}" -gt 80 ]; then
short="${short:0:77}..."
fi
# Escape pipe characters that would break the markdown table.
short="${short//|/\\|}"
append "| \`$short\` | $cnt |"
append "| \`$short\` | $cnt | $note |"
done
append ""
fi
if [ "$noise_threshold_exceeded" -gt 0 ]; then
append "Bewertung: $noise_threshold_exceeded Pattern ueberschreit(en) die Eskalations-Schwelle ($NOISE_ESCALATION_THRESHOLD). Bitte pruefen, ob die als Noise eingeordneten Meldungen noch fachlich Noise sind oder ob sich ein echter Vorfall darunter versteckt."
append "Bewertung: $noise_threshold_exceeded nicht-befreite(s) Pattern ueberschreit(en) die Eskalations-Schwelle ($NOISE_ESCALATION_THRESHOLD). Bitte pruefen, ob die als Noise eingeordneten Meldungen noch fachlich Noise sind oder ob sich ein echter Vorfall darunter versteckt."
elif [ "${noise_threshold_exempt:-0}" -gt 0 ]; then
append "Bewertung: Kein nicht-befreites Pattern ueberschreitet die Eskalations-Schwelle ($NOISE_ESCALATION_THRESHOLD). $noise_threshold_exempt lautes Pattern ist bewusst eskalations-befreit und mit Begruendung dokumentiert."
else
append "Bewertung: Kein Pattern ueberschreitet die Eskalations-Schwelle ($NOISE_ESCALATION_THRESHOLD)."
fi
@@ -0,0 +1,32 @@
# noise-escalation-exempt.patterns - Daily Operations Report
#
# Pattern, die als Rauschen bekannt UND dauerhaft sehr laut sind, sollen die
# Eskalations-Schwelle (NOISE_ESCALATION_THRESHOLD) nicht in eine WARNUNG
# uebersetzen. Ohne diese Ausnahme haengt der Report-Status strukturell auf
# >= WARNUNG fest (z. B. mdadm-Noise auf Unraid feuert dauerhaft > 5000/Tag),
# was die OK/WARNUNG/KRITISCH-Ampel entwertet.
#
# Wirkung: Ein hier gelistetes Pattern wird weiterhin als Noise gezaehlt und
# in der Breakdown-Tabelle gezeigt (mit Markierung "eskalations-befreit"),
# zaehlt aber NICHT mehr zu noise_threshold_exceeded. Neue/unerwartete laute
# Patterns loesen weiterhin eine WARNUNG aus.
#
# Format:
# - Exakte Pattern-Zeile wie in log-noise.patterns (nach Normalisierung:
# getrimmt, ohne Kommentar). Muss zeichengenau dem Eintrag entsprechen.
# - Zeilen mit '#' sind Kommentare, Leerzeilen werden ignoriert.
#
# Eine Befreiung heisst NICHT "ignorieren", sondern "Volumen ist als Noise
# akzeptiert; nur die ESKALATION ist abgeschaltet".
#
# Last reviewed: 2026-06-10
# node-exporter kann /proc/mdstat auf Unraid nicht parsen (eigener Array-
# Treiber, kein Linux-mdadm). Dauerhaft > 5000/Tag, rein kosmetisch.
# Re-check: nur bei Migration auf echtes mdadm-RAID.
monitoring-node-exporter.*mdadm.*Cannot parse /host/proc/mdstat
# Fritz!Box sendet RFC-1035-widrige Multi-Question-SOA-Queries fuer
# myfritz.net/myfritz.link; AdGuard lehnt sie ab. ~1000+/Tag, kein Impact.
# Re-check: falls derselbe Fehler fuer Nicht-AVM-Domains auftaucht.
adguard.*bad question section.*only 1 question allowed