update health_persistence.py

This commit is contained in:
MacRimi
2026-04-16 19:33:47 +02:00
parent 774d42d5be
commit cf871da880
3 changed files with 21 additions and 38 deletions

View File

@@ -74,7 +74,6 @@ export function ProxmoxDashboard() {
serverName: "Loading...", serverName: "Loading...",
nodeId: "Loading...", nodeId: "Loading...",
}) })
const [isInitialLoading, setIsInitialLoading] = useState(true)
const [isRefreshing, setIsRefreshing] = useState(false) const [isRefreshing, setIsRefreshing] = useState(false)
const [isServerConnected, setIsServerConnected] = useState(true) const [isServerConnected, setIsServerConnected] = useState(true)
const [componentKey, setComponentKey] = useState(0) const [componentKey, setComponentKey] = useState(0)
@@ -193,8 +192,8 @@ export function ProxmoxDashboard() {
}, []) }, [])
useEffect(() => { useEffect(() => {
// Siempre fetch inicial — mark loading done when system data arrives // Siempre fetch inicial
fetchSystemData().finally(() => setIsInitialLoading(false)) fetchSystemData()
fetchHealthInfoCount() fetchHealthInfoCount()
fetchUpdateStatus() fetchUpdateStatus()
@@ -373,21 +372,6 @@ export function ProxmoxDashboard() {
} }
} }
if (isInitialLoading) {
return (
<div className="min-h-screen bg-background flex items-center justify-center">
<div className="flex flex-col items-center gap-4">
<div className="relative">
<div className="h-12 w-12 rounded-full border-2 border-muted"></div>
<div className="absolute inset-0 h-12 w-12 rounded-full border-2 border-transparent border-t-primary animate-spin"></div>
</div>
<div className="text-sm font-medium text-foreground">Loading ProxMenux Monitor...</div>
<p className="text-xs text-muted-foreground">Connecting to server and fetching system status</p>
</div>
</div>
)
}
return ( return (
<div className="min-h-screen bg-background"> <div className="min-h-screen bg-background">
<OnboardingCarousel /> <OnboardingCarousel />

View File

@@ -259,19 +259,13 @@ export function SystemOverview() {
if (!hasAttemptedLoad || loadingStates.system) { if (!hasAttemptedLoad || loadingStates.system) {
return ( return (
<div className="space-y-6"> <div className="flex flex-col items-center justify-center min-h-[400px] gap-4">
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-6"> <div className="relative">
{[...Array(4)].map((_, i) => ( <div className="h-12 w-12 rounded-full border-2 border-muted"></div>
<Card key={i} className="bg-card border-border animate-pulse"> <div className="absolute inset-0 h-12 w-12 rounded-full border-2 border-transparent border-t-primary animate-spin"></div>
<CardContent className="p-6">
<div className="h-4 bg-muted rounded w-1/2 mb-4"></div>
<div className="h-8 bg-muted rounded w-3/4 mb-2"></div>
<div className="h-2 bg-muted rounded w-full mb-2"></div>
<div className="h-3 bg-muted rounded w-2/3"></div>
</CardContent>
</Card>
))}
</div> </div>
<div className="text-sm font-medium text-foreground">Loading system overview...</div>
<p className="text-xs text-muted-foreground">Fetching system status and metrics</p>
</div> </div>
) )
} }

View File

@@ -338,20 +338,25 @@ class HealthPersistence:
else: else:
print(f"[HealthPersistence] Database initialized with {len(tables)} tables") print(f"[HealthPersistence] Database initialized with {len(tables)} tables")
# ─── Startup migration: clean stale looping disk I/O errors ─── # ─── Startup migration: clean stale errors from previous bug ───
# Previous versions had a bug where journal-based disk errors were # Previous versions had a bug where journal-based errors were
# re-processed every cycle, causing infinite notification loops. # re-processed every cycle, causing infinite notification loops.
# On upgrade, clean up any stale disk errors that are stuck in the # On upgrade, clean up any stale errors that are stuck in the
# active state from the old buggy behavior. # active state from the old buggy behavior.
# Covers: disk I/O (smart_*, disk_*), VM/CT (vm_*, ct_*, vmct_*),
# and log errors (log_*) — all journal-sourced categories.
try: try:
cursor = conn.cursor() cursor = conn.cursor()
# Delete active (unresolved) disk errors from journal that are
# older than 2 hours — these are leftovers from the feedback loop.
# Real new errors will be re-detected from fresh journal entries.
cutoff = (datetime.now() - timedelta(hours=2)).isoformat() cutoff = (datetime.now() - timedelta(hours=2)).isoformat()
cursor.execute(''' cursor.execute('''
DELETE FROM errors DELETE FROM errors
WHERE error_key LIKE 'smart_%' WHERE ( error_key LIKE 'smart_%'
OR error_key LIKE 'disk_%'
OR error_key LIKE 'vm_%'
OR error_key LIKE 'ct_%'
OR error_key LIKE 'vmct_%'
OR error_key LIKE 'log_%'
)
AND resolved_at IS NULL AND resolved_at IS NULL
AND acknowledged = 0 AND acknowledged = 0
AND last_seen < ? AND last_seen < ?
@@ -359,7 +364,7 @@ class HealthPersistence:
cleaned = cursor.rowcount cleaned = cursor.rowcount
if cleaned > 0: if cleaned > 0:
conn.commit() conn.commit()
print(f"[HealthPersistence] Startup cleanup: removed {cleaned} stale disk error(s) from previous bug") print(f"[HealthPersistence] Startup cleanup: removed {cleaned} stale error(s) from previous versions")
except Exception as e: except Exception as e:
print(f"[HealthPersistence] Startup cleanup warning: {e}") print(f"[HealthPersistence] Startup cleanup warning: {e}")