Add visible "Updated Xs ago" timestamps and freshness indicators to
make cached stats look more alive and help users know data currency.
Backend changes:
- luci.metrics: Add _freshness metadata (age, fresh, timestamp_epoch)
to overview, waf_stats, and connections responses
- luci.crowdsec-dashboard: Add _freshness metadata to get_overview
response using sed injection into cached JSON
Frontend changes:
- metrics/dashboard.js: Display freshness indicator (green/yellow/red)
in header, animate value changes with flash effect
- crowdsec-dashboard/overview.js: Display freshness indicator next to
running badge, update on poll
Shared utilities (kiss-theme.js):
- formatAge(seconds): Format "Xs ago", "Xm ago", "Xh ago"
- getFreshnessClass(age): Return fresh/recent/stale based on age
- getFreshnessColor(class): Return #00c853/#ff9800/#f44336
- freshnessIndicator(age, id): Create indicator DOM element
- updateFreshness(age, id): Update existing indicator
Freshness thresholds:
- Fresh (green): < 15s for metrics, < 30s for CrowdSec
- Recent (yellow): < 45s for metrics, < 90s for CrowdSec
- Stale (red): > threshold
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- WAF blocked now counts mitmproxy scenario decisions (1031 blocks)
- Removed waf_threats field (redundant with waf_blocked)
- Fixed dashboard to show 3 WAF stats: Bans, Alerts, Blocked
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
UI:
- Clean card grid with colored stat values
- Services status bar (HAProxy, WAF, CrowdSec) with glowing dots
- Two-panel layout for WAF/Security and Connections
- Live clock with pulsing indicator
- Proper KissTheme.wrap() integration
Performance:
- Double-buffer cache at /tmp/secubox/metrics-cache.json
- 30s TTL with async background refresh
- Cron job for periodic cache updates
- Instant RPCD response (no computation on request)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>