mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-23 15:49:10 +00:00
388 lines
14 KiB
JavaScript
388 lines
14 KiB
JavaScript
const ApiService = require('../utils/apiService');
|
|
const ErrorService = require('../utils/errorService');
|
|
const fs = require('fs');
|
|
const { NodeSSH } = require('node-ssh');
|
|
const fetch = require('node-fetch');
|
|
const { COMMAND, serverUrl } = require('../utils/config');
|
|
|
|
module.exports = {
|
|
run: async monitor => {
|
|
try {
|
|
if (
|
|
monitor &&
|
|
monitor.type &&
|
|
monitor.agentlessConfig &&
|
|
typeof monitor.agentlessConfig === 'object'
|
|
) {
|
|
const {
|
|
host,
|
|
port,
|
|
username,
|
|
authentication,
|
|
password,
|
|
identityFile,
|
|
} = monitor.agentlessConfig;
|
|
const ssh = new NodeSSH();
|
|
|
|
const config = {
|
|
host,
|
|
port,
|
|
username,
|
|
};
|
|
|
|
if (authentication === 'password') {
|
|
config.password = password;
|
|
} else {
|
|
await fetch(`${serverUrl}/file/${identityFile}`).then(
|
|
res =>
|
|
new Promise((resolve, reject) => {
|
|
const dest = fs.createWriteStream(
|
|
`./${identityFile}`
|
|
);
|
|
res.body.pipe(dest);
|
|
res.body.on('end', () => {
|
|
setTimeout(() => {
|
|
config.privateKey = fs.readFileSync(
|
|
`./${identityFile}`,
|
|
'utf8'
|
|
);
|
|
resolve();
|
|
}, 1000);
|
|
});
|
|
dest.on('error', reject);
|
|
})
|
|
);
|
|
fs.unlinkSync(`./${identityFile}`);
|
|
}
|
|
|
|
ssh.connect(config)
|
|
.then(async function() {
|
|
let os;
|
|
try {
|
|
const {
|
|
stdout: osLine,
|
|
stderr,
|
|
} = await ssh.execCommand('uname -a');
|
|
|
|
if (stderr) throw stderr;
|
|
|
|
os = osLine.split(' ')[0];
|
|
} catch (e) {
|
|
const { stdout: osLine } = await ssh.execCommand(
|
|
'wmic os get name'
|
|
);
|
|
|
|
os = osLine.split(' ')[1];
|
|
}
|
|
|
|
const serverData = await execCommands(ssh, os);
|
|
|
|
ssh.dispose();
|
|
|
|
await ApiService.ping(monitor._id, {
|
|
monitor,
|
|
serverData,
|
|
type: monitor.type,
|
|
});
|
|
})
|
|
.catch(error => {
|
|
ErrorService.log(
|
|
'serverMonitors.run.ssh.connect',
|
|
error
|
|
);
|
|
throw error;
|
|
});
|
|
}
|
|
} catch (error) {
|
|
ErrorService.log('serverMonitors.run', error);
|
|
throw error;
|
|
}
|
|
},
|
|
};
|
|
|
|
const execCommands = async (exec, os) => {
|
|
try {
|
|
const isSSH = exec instanceof NodeSSH;
|
|
|
|
// TODO: complete commands and make platform specific
|
|
let cpuLoad,
|
|
avgCpuLoad,
|
|
cpuCores,
|
|
memoryUsed,
|
|
totalMemory,
|
|
swapUsed,
|
|
storageUsed,
|
|
totalStorage,
|
|
storageUsage,
|
|
mainTemp,
|
|
maxTemp;
|
|
|
|
if (os === 'Linux') {
|
|
const { stdout: load } = await (isSSH
|
|
? exec.execCommand(COMMAND.linux.load)
|
|
: exec(COMMAND.linux.load));
|
|
const { stdout: cpu } = await (isSSH
|
|
? exec.execCommand(COMMAND.linux.cpu)
|
|
: exec(COMMAND.linux.cpu));
|
|
const { stdout: mem } = await (isSSH
|
|
? exec.execCommand(COMMAND.linux.mem)
|
|
: exec(COMMAND.linux.mem));
|
|
const { stdout: disk } = await (isSSH
|
|
? exec.execCommand(COMMAND.linux.disk)
|
|
: exec(COMMAND.linux.disk));
|
|
const { stdout: temp } = await (isSSH
|
|
? exec.execCommand(COMMAND.linux.temp)
|
|
: exec(COMMAND.linux.temp));
|
|
|
|
const loadLines = load
|
|
.replace(/\t|:|,|-/gi, '')
|
|
.trim()
|
|
.split('\n')
|
|
.map(line => {
|
|
const words = line
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
return words;
|
|
});
|
|
const cpuLines = cpu
|
|
.replace(/\t|:/gi, '')
|
|
.trim()
|
|
.split('\n')
|
|
.map(line => line.replace(/\s+/g, ' ').trim());
|
|
const memLines = mem
|
|
.replace(/\t|:/gi, '')
|
|
.trim()
|
|
.split('\n')
|
|
.map(line => {
|
|
const words = line
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
return words[words.length - 2];
|
|
});
|
|
const diskLines = disk
|
|
.replace(/\t|:|M|G|%/gi, '')
|
|
.trim()
|
|
.split('\n')
|
|
.map(line => {
|
|
const words = line
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
return {
|
|
storageUsed: words[2],
|
|
totalStorage: words[1],
|
|
storageUsage: words[4],
|
|
};
|
|
})
|
|
.reduce((disks, disk) => {
|
|
return {
|
|
storageUsed: disks.storageUsed + disk.storageUsed,
|
|
totalStorage: disks.totalStorage + disk.totalStorage,
|
|
storageUsage: disks.storageUsage + disk.storageUsage,
|
|
};
|
|
});
|
|
const tempLines = temp
|
|
.replace(/\t|:|\+|°|C/gi, '')
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
|
|
cpuLoad = loadLines[3][1];
|
|
avgCpuLoad = loadLines[2][10];
|
|
cpuCores = cpuLines.length / 2;
|
|
memoryUsed =
|
|
(parseFloat(memLines[0]) - parseFloat(memLines[1])) * 1024;
|
|
totalMemory = memLines[0] * 1024;
|
|
swapUsed =
|
|
(parseFloat(memLines[4]) - parseFloat(memLines[5])) * 1024;
|
|
storageUsed = diskLines.storageUsed * 1024 * 1024 * 1024;
|
|
totalStorage = diskLines.totalStorage * 1024 * 1024 * 1024;
|
|
storageUsage = diskLines.storageUsage;
|
|
mainTemp = tempLines[1];
|
|
maxTemp = tempLines[1];
|
|
} else if (os === 'Darwin') {
|
|
const { stdout: load } = await (isSSH
|
|
? exec.execCommand(COMMAND.darwin.load)
|
|
: exec(COMMAND.darwin.load));
|
|
const { stdout: cpu } = await (isSSH
|
|
? exec.execCommand(COMMAND.darwin.cpu)
|
|
: exec(COMMAND.darwin.cpu));
|
|
const { stdout: usedMem } = await (isSSH
|
|
? exec.execCommand(COMMAND.darwin.mem.used)
|
|
: exec(COMMAND.darwin.mem.used));
|
|
const { stdout: totalMem } = await (isSSH
|
|
? exec.execCommand(COMMAND.darwin.mem.total)
|
|
: exec(COMMAND.darwin.mem.total));
|
|
const { stdout: swapMem } = await (isSSH
|
|
? exec.execCommand(COMMAND.darwin.mem.swap)
|
|
: exec(COMMAND.darwin.mem.swap));
|
|
const { stdout: disk } = await (isSSH
|
|
? exec.execCommand(COMMAND.darwin.disk)
|
|
: exec(COMMAND.darwin.disk));
|
|
const { stdout: temp } = await (isSSH
|
|
? exec.execCommand(COMMAND.darwin.temp)
|
|
: exec(COMMAND.darwin.temp));
|
|
|
|
const loadLines = load
|
|
.replace(/\t|:|,|-|%/gi, '')
|
|
.trim()
|
|
.split('\n')
|
|
.map(line => {
|
|
const words = line
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
return words;
|
|
});
|
|
const memLines = usedMem
|
|
.replace(/\t|:|M|G|\(|\)/gi, '')
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
const swapLines = swapMem
|
|
.replace(/\t|:|M|G|\(|\)|=/gi, '')
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
const diskLines = disk
|
|
.replace(/\t|:|Mi|Gi|%/gi, '')
|
|
.trim()
|
|
.split('\n')
|
|
.map(line => {
|
|
const words = line
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
return {
|
|
storageUsed: words[2],
|
|
totalStorage: words[1],
|
|
storageUsage: words[4],
|
|
};
|
|
})
|
|
.reduce((disks, disk) => {
|
|
return {
|
|
storageUsed: disks.storageUsed + disk.storageUsed,
|
|
totalStorage: disks.totalStorage + disk.totalStorage,
|
|
storageUsage: disks.storageUsage + disk.storageUsage,
|
|
};
|
|
});
|
|
|
|
cpuLoad = loadLines[1][2];
|
|
avgCpuLoad = loadLines[0][3];
|
|
cpuCores = cpu.replace('\n', '');
|
|
memoryUsed =
|
|
(parseFloat(memLines[1]) - parseFloat(memLines[3])) *
|
|
1024 *
|
|
1024;
|
|
totalMemory = totalMem.replace('\n', '');
|
|
swapUsed = swapLines[3] * 1024 * 1024;
|
|
storageUsed = diskLines.storageUsed * 1024 * 1024 * 1024;
|
|
totalStorage = diskLines.totalStorage * 1024 * 1024 * 1024;
|
|
storageUsage = diskLines.storageUsage;
|
|
mainTemp = temp.replace('\n', '');
|
|
maxTemp = temp.replace('\n', '');
|
|
} else if (os === 'Windows') {
|
|
const { stdout: load } = await (isSSH
|
|
? exec.execCommand(COMMAND.win.load)
|
|
: exec(COMMAND.win.load));
|
|
const { stdout: cpu } = await (isSSH
|
|
? exec.execCommand(COMMAND.win.cpu)
|
|
: exec(COMMAND.win.cpu));
|
|
const { stdout: freeMem } = await (isSSH
|
|
? exec.execCommand(COMMAND.win.mem.free)
|
|
: exec(COMMAND.win.mem.free));
|
|
const { stdout: totalMem } = await (isSSH
|
|
? exec.execCommand(COMMAND.win.mem.total)
|
|
: exec(COMMAND.win.mem.total));
|
|
const { stdout: totalSwapMem } = await (isSSH
|
|
? exec.execCommand(COMMAND.win.mem.totalSwap)
|
|
: exec(COMMAND.win.mem.totalSwap));
|
|
const { stdout: freeSwapMem } = await (isSSH
|
|
? exec.execCommand(COMMAND.win.mem.freeSwap)
|
|
: exec(COMMAND.win.mem.freeSwap));
|
|
const { stdout: freeDisk } = await (isSSH
|
|
? exec.execCommand(COMMAND.win.disk.free)
|
|
: exec(COMMAND.win.disk.free));
|
|
const { stdout: totalDisk } = await (isSSH
|
|
? exec.execCommand(COMMAND.win.disk.total)
|
|
: exec(COMMAND.win.disk.total));
|
|
const { stdout: temp } = await (isSSH
|
|
? exec.execCommand(COMMAND.win.temp)
|
|
: exec(COMMAND.win.temp));
|
|
|
|
const loadLines = load
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
const cpuLines = cpu
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
const freeMemLines = freeMem
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
const totalMemLines = totalMem
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
const totalSwapMemLines = totalSwapMem
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
const freeSwapMemLines = freeSwapMem
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
const freeDiskLines = freeDisk
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
const totalDiskLines = totalDisk
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
const tempLines = temp
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.split(' ');
|
|
|
|
cpuLoad = loadLines[1];
|
|
avgCpuLoad = loadLines[1];
|
|
cpuCores = cpuLines[1];
|
|
memoryUsed =
|
|
parseFloat(totalMemLines[1]) -
|
|
parseFloat(freeMemLines[1]) * 1024;
|
|
totalMemory = totalMemLines[1];
|
|
swapUsed =
|
|
parseFloat(totalSwapMemLines[1]) -
|
|
parseFloat(freeSwapMemLines[1]);
|
|
storageUsed =
|
|
parseFloat(totalDiskLines[1]) - parseFloat(freeDiskLines[1]);
|
|
totalStorage = totalDiskLines[1];
|
|
storageUsage = (storageUsed / parseFloat(totalDiskLines[1])) * 100;
|
|
mainTemp = tempLines[1];
|
|
maxTemp = tempLines[1];
|
|
}
|
|
|
|
return {
|
|
cpuLoad,
|
|
avgCpuLoad,
|
|
cpuCores,
|
|
memoryUsed,
|
|
totalMemory,
|
|
swapUsed,
|
|
storageUsed,
|
|
totalStorage,
|
|
storageUsage,
|
|
mainTemp,
|
|
maxTemp,
|
|
};
|
|
} catch (error) {
|
|
ErrorService.log('serverMonitors.execCommands', error);
|
|
throw error;
|
|
}
|
|
};
|