'a'
mh-two-thousand-and-two
2024-04-12 44d2c92345cd156a59fc327b3060292a282d2893
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
140
141
142
143
144
145
146
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()) {
            const 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;