feat: Implement real-time stats and metrics for platform services with WebSocket integration

This commit is contained in:
2025-11-26 14:12:20 +00:00
parent 3e8cd6e3d0
commit a14af4af9c
12 changed files with 735 additions and 16 deletions

View File

@@ -21,7 +21,9 @@ export class OneboxDaemon {
private smartdaemon: plugins.smartdaemon.SmartDaemon | null = null;
private running = false;
private monitoringInterval: number | null = null;
private metricsInterval = 60000; // 1 minute
private statsInterval: number | null = null;
private metricsInterval = 60000; // 1 minute (for DB storage)
private statsBroadcastInterval = 5000; // 5 seconds (for real-time WebSocket)
private pidFilePath: string = PID_FILE_PATH;
private lastDomainSync = 0; // Timestamp of last Cloudflare domain sync
private domainSyncInterval = 6 * 60 * 60 * 1000; // 6 hours
@@ -184,6 +186,11 @@ export class OneboxDaemon {
await this.monitoringTick();
}, this.metricsInterval);
// Start stats broadcasting loop (faster for real-time UI)
this.statsInterval = setInterval(async () => {
await this.broadcastStats();
}, this.statsBroadcastInterval);
// Run first tick immediately
this.monitoringTick();
}
@@ -195,8 +202,12 @@ export class OneboxDaemon {
if (this.monitoringInterval !== null) {
clearInterval(this.monitoringInterval);
this.monitoringInterval = null;
logger.debug('Monitoring loop stopped');
}
if (this.statsInterval !== null) {
clearInterval(this.statsInterval);
this.statsInterval = null;
}
logger.debug('Monitoring loops stopped');
}
/**
@@ -268,6 +279,30 @@ export class OneboxDaemon {
}
}
/**
* Broadcast stats to WebSocket clients (real-time updates)
*/
private async broadcastStats(): Promise<void> {
try {
const services = this.oneboxRef.services.listServices();
for (const service of services) {
if (service.status === 'running' && service.containerID) {
try {
const stats = await this.oneboxRef.docker.getContainerStats(service.containerID);
if (stats) {
this.oneboxRef.httpServer.broadcastStatsUpdate(service.name, stats);
}
} catch {
// Silently ignore - stats collection can fail transiently
}
}
}
} catch {
// Silently ignore broadcast errors
}
}
/**
* Check SSL certificate expiration
*/