import { docker } from "../dockerService";
/**
* Retrieve a snapshot of container resource usage (CPU, memory, network).
*
* @param {string} containerId - Docker container id
* @returns {Promise<Object>} Object with cpuPercent, memPercent and netIO {rx,tx}
*/
export async function getStats(containerId) {
const container = docker.getContainer(containerId);
const stream = await container.stats({ stream: false });
const cpuDelta =
stream.cpu_stats.cpu_usage.total_usage -
stream.precpu_stats.cpu_usage.total_usage;
const systemDelta =
stream.cpu_stats.system_cpu_usage - stream.precpu_stats.system_cpu_usage;
// Get number of CPUs for proper normalization
let numCpus = 1;
if (typeof stream.cpu_stats.online_cpus === 'number' && stream.cpu_stats.online_cpus > 0) {
numCpus = stream.cpu_stats.online_cpus;
} else if (
stream.cpu_stats.cpu_usage &&
Array.isArray(stream.cpu_stats.cpu_usage.percpu_usage) &&
stream.cpu_stats.cpu_usage.percpu_usage.length > 0
) {
numCpus = stream.cpu_stats.cpu_usage.percpu_usage.length;
}
// Calculate normalized CPU percentage
const cpuPercent = systemDelta > 0
? ((cpuDelta / systemDelta) * numCpus * 100)
: 0;
const memUsage = stream.memory_stats.usage || 0;
const memLimit = stream.memory_stats.limit || 1;
const memPercent = (memUsage / memLimit) * 100;
const rx = stream.networks
? Object.values(stream.networks)
.map((n) => n.rx_bytes)
.reduce((a, b) => a + b, 0)
: 0;
const tx = stream.networks
? Object.values(stream.networks)
.map((n) => n.tx_bytes)
.reduce((a, b) => a + b, 0)
: 0;
return {
cpuPercent: cpuPercent.toFixed(1),
memPercent: memPercent.toFixed(1),
netIO: { rx, tx },
};
}