You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
2.9 KiB

2 years ago
const memoize = require('./memoize');
const each = require('./each');
const trim = require('./trim');
const toNum = require('./toNum');
const contain = require('./contain');
const concat = require('./concat');
const range = require('./range');
const startWith = require('./startWith');
const fs = require('fs');
const cpu = {
stat() {
let usage = 0;
if (isV2()) {
const data = parseKeyValue(read('cpu.stat'));
usage = toNum(data['usage_usec']);
} else {
usage = Math.round(toNum(read('cpuacct/cpuacct.usage')) / 1000);
}
return {
usage
};
},
max() {
let max = Infinity;
if (isV2()) {
let data = read('cpu.max');
if (!startWith(data, 'max')) {
data = data.split(' ');
const quota = toNum(data[0]);
const period = toNum(data[1]);
max = quota / period;
}
} else {
const quota = toNum(read('cpu/cpu.cfs_quota_us'));
if (quota !== -1) {
const period = toNum(read('cpu/cpu.cfs_period_us'));
max = quota / period;
}
}
return max;
}
};
const cpuset = {
cpus() {
let effective = [];
let p = 'cpuset/cpuset.effective_cpus';
if (isV2()) {
p = 'cpuset.cpus.effective';
}
effective = parseRange(read(p));
return {
effective
};
}
};
const memory = {
max() {
let max = Infinity;
if (isV2()) {
let data = read('memory.max');
if (data !== 'max') {
max = toNum(data);
}
} else {
max = toNum(read('memory/memory.limit_in_bytes'));
}
return max;
},
current() {
let p = 'memory/memory.usage_in_bytes';
if (isV2()) {
p = 'memory.current';
}
return toNum(read(p));
}
};
const isV2 = memoize(function() {
return fs.existsSync(resolve('cgroup.controllers'));
});
function read(p) {
return fs.readFileSync(resolve(p), 'utf8');
}
/* a 1
* b 2
*/
function parseKeyValue(data) {
const ret = {};
each(data.split('\n'), line => {
line = trim(line);
if (line) {
line = line.split(' ');
ret[line[0]] = line[1];
}
});
return ret;
}
/* 1-2,4-5 */
function parseRange(data) {
let ret = [];
each(data.split(','), r => {
if (!contain(r, '-')) {
ret.push(toNum(r));
} else {
r = r.split('-');
ret = concat(ret, range(toNum(r[0]), toNum(r[1]) + 1));
}
});
return ret;
}
function resolve(p) {
return `/sys/fs/cgroup/${p}`;
}
exports = {
cpu,
cpuset,
memory,
version() {
return isV2() ? 2 : 1;
}
};
module.exports = exports;