feat(monitoring): add Beszel fleet integration to Monitor page

- New api/services/beszel.ts: Zod-validated Beszel API client with
  PocketBase auth, system fetching, and MySQL upsert
- New api/routes/beszel.ts: GET /api/beszel (read) + POST /api/beszel/collect (trigger)
- Updated api/server.ts: register route, add to 5min scheduler
- Updated src/pages/Monitor.tsx: Fleet section showing all 17 systems
  with CPU/RAM/disk bars, status dots, container count, and link to
  Beszel dashboard

Architecture: Beszel hub → API → tbl_eal_monitoring (category='fleet')
→ Monitor.tsx grid. Collected every 5min alongside existing metrics.
This commit is contained in:
2026-06-23 20:09:12 +01:00
parent 08d2a31dc9
commit 769c63b2a8
4 changed files with 380 additions and 5 deletions
+9 -1
View File
@@ -26,6 +26,8 @@ import { openSessionsDb } from './services/sessions/db.js'
import { DEFAULT_DB_PATH } from './services/sessions/indexer.js'
import { collectAllServerMetrics } from './services/server-metrics.js'
import { collectMonitoringData } from './services/monitoring-collector.js'
import beszelRouter from './routes/beszel.js'
import { collectBeszelFleet } from './services/beszel.js'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
@@ -133,8 +135,8 @@ app.use('/api/financial', financialRouter)
app.use('/api/mcps', mcpsRouter)
app.use('/api/n8n', n8nRouter)
app.use('/api/paperclip', paperclipRouter)
app.use('/api/ai', aiRouter)
app.use('/api/operations', operationsRouter)
app.use('/api/beszel', beszelRouter)
// Observabilidade (Espelho) — sessões Claude Code
const sessionsDb = openSessionsDb(process.env.OBSERVABILIDADE_DB ?? DEFAULT_DB_PATH)
@@ -215,6 +217,9 @@ app.listen(PORT, () => {
collectMonitoringData().catch(err =>
console.error('[SCHEDULER] Initial monitoring collection failed:', err.message)
)
collectBeszelFleet().catch(err =>
console.error('[SCHEDULER] Initial Beszel fleet collection failed:', err instanceof Error ? err.message : err)
)
}, 30000)
// Recurring collection
@@ -225,6 +230,9 @@ app.listen(PORT, () => {
collectMonitoringData().catch(err =>
console.error('[SCHEDULER] Monitoring collection failed:', err.message)
)
collectBeszelFleet().catch(err =>
console.error('[SCHEDULER] Beszel fleet collection failed:', err instanceof Error ? err.message : err)
)
}, INTERVAL)
}
})