feat: Enhance container stats monitoring and UI integration with new ContainerStatsComponent
This commit is contained in:
@@ -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)}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user