monitoring: a read error must not erase the CVE timeline (management #0082)

The exporter pruned first_seen on every scrape, keeping only what it had just
seen. A report that failed to parse - a file being written, a brief I/O error -
was skipped by a silent `continue`, so its findings never entered seen_keys and
their first-seen timestamps were deleted for good. Nothing reported it, and
"first seen" simply restarted at now.

Pruning is now limited to targets whose report was actually read this round.
Proven both ways against a throwaway results directory rather than by reasoning:
make one report unreadable and its entry survives while read_errors counts 1; fix
the other report but drop its finding and that entry is pruned as before. The
distinction is the point - the old behaviour was not too aggressive, it was
indiscriminate.

Two numbers now leave the exporter: trivy_reports_total and
trivy_report_read_errors, with alerts on both. They cover what TrivyScanStale
cannot reach by construction - a target that never produced a report has no series
for time() to compare against, so it stays quiet no matter how long it has been
broken.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Thore Cimbal
2026-08-19 12:00:00 +00:00
co-authored by Claude Opus 5
parent be6b5f0657
commit 9a106151f1
2 changed files with 47 additions and 3 deletions
+20
View File
@@ -85,6 +85,26 @@ groups:
room: security
annotations:
summary: "CVE-Scan fuer {{ $labels.target }} ist aelter als 2 Tage — Scanner pruefen (ein still gestorbener Scanner macht blind)"
# TrivyScanStale hat eine Blindstelle, die es prinzipiell nicht schliessen
# kann: ein Target OHNE je erfolgreichen Bericht hat gar keine Serie, an der
# 'time() - ...' haengen koennte. Es bleibt also still. Die beiden Regeln
# darunter fangen die zwei Faelle ab, die dahinterstecken.
- alert: TrivyReportUnreadable
expr: trivy_report_read_errors > 0
for: 30m
labels:
severity: warning
room: security
annotations:
summary: "{{ $value }} CVE-Bericht(e) sind seit 30 min unlesbar — die betroffenen Targets werden NICHT ausgewertet und faellt sonst niemandem auf"
- alert: TrivyNoReports
expr: trivy_reports_total == 0
for: 1h
labels:
severity: critical
room: security
annotations:
summary: "Der CVE-Exporter findet ueberhaupt keine Berichte mehr — der Scanner liefert nichts, die Schwachstellen-Sicht ist blind"
# Sicherungen (management #0030). Bis 2026-08-14 gab es hierzu KEINE Regel: ein
# fehlgeschlagenes naechtliches Backup waere unbemerkt geblieben - genau der stille