-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
executable file
·139 lines (112 loc) · 4.51 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env node
import figlet from 'figlet';
import gradient from 'gradient-string';
import { input, confirm } from '@inquirer/prompts';
import shell from 'shelljs';
import chalk from 'chalk';
async function main() {
console.log(gradient.retro(figlet.textSync('Pod Watcher')));
console.log('Welcome to Pod Watcher! You can input the name of the pod you want to monitor for peak CPU and memory usage.')
const selectedPods = (await input({ message: "Enter pod names (separated by ','): ", required: true })).split(',');
const podNames = [];
const { stdout } = shell.exec('kubectl get pods -o jsonpath={..metadata.name}', { silent: true })
for (const podName of stdout.split(' ')) {
for (const pod of selectedPods) {
if (podName.startsWith(pod)) {
podNames.push(podName);
}
}
}
console.log(podNames);
const podPeakCPU = new Map();
const podPeakMemory = new Map();
let cpuJob;
let memJob;
if (await confirm({ message: 'Do you want to ' + chalk.green('START') + ' to watch these memory usages of pods?', default: true })) {
addScriptIntoPods(podNames);
cpuJob = startCollectCPU(podNames, podPeakCPU);
memJob = startCollectMemory(podNames, podPeakMemory);
}
else {
return;
}
console.log('Now you can start your process to monitor the peak CPU and memory usage of the pods. Once your process is complete, you can stop the watcher to review the results.');
if (await confirm({ message: 'Do you want to ' + chalk.red('STOP') + ' the watcher to view the results?', default: true })) {
console.log('\nPeak usage of each pod\n');
const maxPodNameLength = findMaxPodNameLength(podNames);
const blank = ' ';
console.log(`${'NAME'.padEnd(maxPodNameLength)} ${blank} CPU(cores) ${blank} MEMORY(bytes)`);
podNames.forEach(pod => {
const cpu_usage = formatCPU(podPeakCPU.get(pod));
const memory_usage = bytesToMB(podPeakMemory.get(pod));
console.log(`${pod.padEnd(maxPodNameLength)} ${blank} ${cpu_usage.padEnd('CPU(cores)'.length)} ${blank} ${memory_usage}`);
});
}
clearTimeout(cpuJob);
clearTimeout(memJob);
}
function addScriptIntoPods(podNames) {
const shellScript = `
cat <<'EOF' > /calc_cpu.sh
#!/bin/bash
tstart=\\$(date +%s%6N)
cstart=\\$(cat /sys/fs/cgroup/cpu.stat | grep usage_usec | awk -F' ' '{print \\$2}')
sleep 1
tstop=\\$(date +%s%6N)
cstop=\\$(cat /sys/fs/cgroup/cpu.stat | grep usage_usec | awk -F' ' '{print \\$2}')
cpu_usage=\\$(awk -v cstart="\\$cstart" -v cstop="\\$cstop" -v tstart="\\$tstart" -v tstop="\\$tstop" 'BEGIN { printf "%.0f", (cstop - cstart) * 1000 / (tstop - tstart) }')
echo \\$cpu_usage
EOF
chmod +x /calc_cpu.sh
`;
for (const podName of podNames) {
const command = `kubectl exec -it ${podName} -- bash -c "${shellScript.replace(/"/g, '\\"')}"`;
shell.exec(command);
}
}
function startCollectCPU(podNames, podPeakCPU) {
return setInterval(() => {
Promise.all(podNames.map(podName => {
return new Promise((resolve, reject) => {
collectCPU(podName, podPeakCPU);
resolve();
});
}));
}, 1000);
}
function collectCPU(podName, podPeakCPU) {
const { stdout } = shell.exec(`kubectl exec ${podName} -- sh /calc_cpu.sh`, { silent: true })
const cpu_usage = Number(stdout.trim());
if (cpu_usage > (podPeakCPU.get(podName) || 0)) {
podPeakCPU.set(podName, cpu_usage);
}
}
function startCollectMemory(podNames, podPeakMemory) {
return setInterval(() => {
Promise.all(podNames.map(podName => {
return new Promise((resolve, reject) => {
collectMemory(podName, podPeakMemory);
resolve();
});
}));
}, 1000);
}
function collectMemory(podName, podPeakMemory) {
const { stdout } = shell.exec(`kubectl exec ${podName} -- cat /sys/fs/cgroup/memory.current`, { silent: true })
const memory_usage = Number(stdout.trim());
if (memory_usage > (podPeakMemory.get(podName) || 0)) {
podPeakMemory.set(podName, memory_usage);
}
}
function findMaxPodNameLength(podNames) {
return podNames.reduce((a, b) => {
return a.length > b.length ? a : b;
}).length;
}
function formatCPU(cpu_usage) {
return `${parseFloat(cpu_usage).toFixed(0)}m`
}
function bytesToMB(bytes) {
return `${parseFloat(bytes / (1024 ** 2)).toFixed(0)}Mi`
}
await main();