mirror of
https://github.com/RGJorge/ContainerFlow.git
synced 2026-08-03 07:21:42 +02:00
v0.0.1
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import { docker } from "./docker";
|
||||
import type { Service, Stats, DockerEvent } from "../shared/types";
|
||||
|
||||
export async function pollStats(services: Service[]): Promise<Stats[]> {
|
||||
const running = services.filter((s) => s.state === "running");
|
||||
const results: Stats[] = [];
|
||||
|
||||
for (const svc of running) {
|
||||
try {
|
||||
const container = docker.getContainer(svc.id);
|
||||
const raw = await container.stats({ stream: false });
|
||||
|
||||
const cpuDelta =
|
||||
raw.cpu_stats.cpu_usage.total_usage - raw.precpu_stats.cpu_usage.total_usage;
|
||||
const sysDelta =
|
||||
raw.cpu_stats.system_cpu_usage - raw.precpu_stats.system_cpu_usage;
|
||||
|
||||
const cpu =
|
||||
sysDelta > 0
|
||||
? (cpuDelta / sysDelta) * (raw.cpu_stats.online_cpus || 1) * 100
|
||||
: 0;
|
||||
|
||||
const memUsage = raw.memory_stats.usage || 0;
|
||||
const memLimit = raw.memory_stats.limit || 1;
|
||||
|
||||
results.push({
|
||||
service: svc.uid,
|
||||
cpu: parseFloat(cpu.toFixed(2)),
|
||||
mem_mb: parseFloat((memUsage / 1024 / 1024).toFixed(1)),
|
||||
mem_percent: parseFloat(((memUsage / memLimit) * 100).toFixed(1)),
|
||||
});
|
||||
} catch {
|
||||
// Container may have stopped between discovery and stats
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
export function watchDockerEvents(onEvent: (event: DockerEvent) => void) {
|
||||
docker.getEvents({}, (err, stream) => {
|
||||
if (err || !stream) {
|
||||
console.error("Failed to watch Docker events:", err);
|
||||
return;
|
||||
}
|
||||
|
||||
stream.on("data", (chunk: Buffer) => {
|
||||
try {
|
||||
const event = JSON.parse(chunk.toString());
|
||||
if (event.Type !== "container") return;
|
||||
|
||||
const action = event.Action?.split(":")[0]; // "health_status: healthy" → "health_status"
|
||||
if (!["start", "stop", "die", "restart", "health_status"].includes(action)) return;
|
||||
|
||||
const svcName =
|
||||
event.Actor?.Attributes?.["com.docker.compose.service"] ||
|
||||
event.Actor?.Attributes?.name ||
|
||||
"unknown";
|
||||
const svcProject =
|
||||
event.Actor?.Attributes?.["com.docker.compose.project"] ||
|
||||
"standalone";
|
||||
onEvent({
|
||||
type: "docker",
|
||||
action,
|
||||
service: `${svcProject}/${svcName}`,
|
||||
time: event.time || Date.now() / 1000,
|
||||
});
|
||||
} catch {}
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user