feat: Enhance container stats monitoring and UI integration with new ContainerStatsComponent

This commit is contained in:
2025-11-26 16:36:01 +00:00
parent a14af4af9c
commit 9de32cd00d
5 changed files with 228 additions and 151 deletions

View File

@@ -285,21 +285,25 @@ export class OneboxDaemon {
private async broadcastStats(): Promise<void> {
try {
const services = this.oneboxRef.services.listServices();
const runningServices = services.filter(s => s.status === 'running' && s.containerID);
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
logger.info(`Broadcasting stats for ${runningServices.length} running services`);
for (const service of runningServices) {
try {
const stats = await this.oneboxRef.docker.getContainerStats(service.containerID!);
if (stats) {
logger.info(`Broadcasting stats for ${service.name}: CPU=${stats.cpuPercent.toFixed(1)}%, Mem=${Math.round(stats.memoryUsed / 1024 / 1024)}MB`);
this.oneboxRef.httpServer.broadcastStatsUpdate(service.name, stats);
} else {
logger.warn(`No stats returned for ${service.name} (containerID: ${service.containerID})`);
}
} catch (error) {
logger.warn(`Stats collection failed for ${service.name}: ${getErrorMessage(error)}`);
}
}
} catch {
// Silently ignore broadcast errors
} catch (error) {
logger.error(`Broadcast stats error: ${getErrorMessage(error)}`);
}
}

View File

@@ -574,14 +574,23 @@ export class OneboxDockerManager {
/**
* Get container stats (CPU, memory, network)
* Handles both regular containers and Swarm services
*/
async getContainerStats(containerID: string): Promise<IContainerStats | null> {
try {
const container = await this.dockerClient!.getContainerById(containerID);
// Try to get container directly first
let container = await this.dockerClient!.getContainerById(containerID);
// If not found, it might be a service ID - try to get the actual container ID
if (!container) {
const serviceContainerId = await this.getContainerIdForService(containerID);
if (serviceContainerId) {
container = await this.dockerClient!.getContainerById(serviceContainerId);
}
}
if (!container) {
// Container not found - this is expected for Swarm services where we have service ID instead of container ID
// Return null silently
// Container/service not found
return null;
}