Created
February 13, 2020 10:27
-
-
Save yurynix/6beef61ec4189b37fad0c86bf9fe21b7 to your computer and use it in GitHub Desktop.
Some useful stats from the proc filesystem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const util = require('util'); | |
const fs = require('fs'); | |
const readfile = util.promisify(fs.readFile); | |
const readdir = util.promisify(fs.readdir); | |
const readlink = util.promisify(fs.readlink); | |
const stat = util.promisify(fs.stat); | |
async function getProcessRSSMemory(pid) { | |
try { | |
const statsFile = `/proc/${pid}/status`; | |
const statsFileContent = await readfile(statsFile, { encoding: 'utf8' }); | |
const rssRegex = /vmRSS:\s*([^\n]+)/ig | |
const rssMatch = rssRegex.exec(statsFileContent); | |
if (rssMatch && rssMatch.length > 1) { | |
return rssMatch[1]; | |
} | |
} catch (ex) { | |
console.log(`Failure getProcessRSSMemory(${pid})`, ex); | |
} | |
return null; | |
} | |
async function getRunningPids() { | |
const files = await readdir('/proc'); | |
const pids = files | |
.map(file => parseInt(file, 10)) | |
.filter(pid => !isNaN(pid) && pid !== process.pid && pid !== 1); | |
return pids; | |
} | |
async function getRunningExecutables() { | |
const pids = await getRunningPids(); | |
const results = await Promise.all( | |
pids.map(async pid => { | |
try { | |
const exe = await readlink(`/proc/${pid}/exe`); | |
return { | |
exe, | |
pid, | |
}; | |
} catch (ex) { | |
// We might get EACCESS here, since we get the list of all process | |
// and not all of them belongs to us. | |
return null; | |
} | |
}), | |
); | |
return results.filter(result => result); | |
} | |
async function getProcessFds(pid) { | |
const fdLinks = await readdir(`/proc/${pid}/fd`); | |
const fdNames = await Promise.all(fdLinks.map(async fd => { | |
try { | |
const fdLink = `/proc/${pid}/fd/${fd}`; | |
const name = await readlink(fdLink); | |
const fdStat = await stat(fdLink); | |
return { | |
name, | |
fd, | |
stat: fdStat | |
}; | |
} catch (ex) { | |
return null; | |
} | |
})); | |
return fdNames.filter(fdInfo => !!fdInfo); | |
} | |
async function getAllProcessFds() { | |
const pids = await getRunningPids(); | |
pids.push(process.pid); // Add myself | |
const processFds = await Promise.all(pids.map(async pid => { | |
try { | |
const fds = await getProcessFds(pid); | |
const name = await readlink(`/proc/${pid}/exe`); | |
return { | |
name, | |
pid, | |
fds | |
} | |
} catch (ex) { | |
return { pid }; | |
} | |
})); | |
return processFds; | |
} | |
// based on https://unix.stackexchange.com/questions/62154/when-was-a-process-started | |
async function getProcessUptimeInSeconds(pid) { | |
try { | |
const processStat = await readfile(`/proc/${pid}/stat`, { encoding: 'utf8' }); | |
const systeUptime = await readfile('/proc/uptime', { encoding: 'utf8' }); | |
const processStartTime = parseInt(processStat.split(' ')[21], 10) / 100; | |
const uptime = parseInt(systeUptime.split(' ')[0], 10); | |
return uptime - processStartTime; | |
} catch (ex) { | |
console.log(`Failure getProcessUptimeInSeconds(${pid})`, ex); | |
} | |
return null; | |
} | |
async function getProcessStats() { | |
const runningPids = await getRunningExecutables(); | |
const runningPidsWithUptime = await Promise.all(runningPids.map(async processInfo => { | |
const uptime = await getProcessUptimeInSeconds(processInfo.pid); | |
return { | |
...processInfo, | |
uptime, | |
} | |
})); | |
return runningPidsWithUptime; | |
} | |
function printProcessStats(processStats) { | |
processStats.forEach(processInfo => { | |
console.log(`[process_stats] pid: ${processInfo.pid} exe: ${processInfo.exe} uptime: ${processInfo.uptime}`); | |
}); | |
if (processStats.length === 0) { | |
console.log('[process_stats] No processes running'); | |
} | |
} | |
module.exports = { | |
getProcessRSSMemory, | |
getProcessStats, | |
printProcessStats, | |
getProcessFds, | |
getAllProcessFds | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment