@u4/adbkit
Version:
A Typescript client for the Android Debug Bridge.
138 lines • 4.96 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = __importDefault(require("events"));
const parser_1 = __importDefault(require("../parser"));
const RE_CPULINE = /^cpu[0-9]+ .*$/gm;
const RE_COLSEP = / +/g;
class ProcStat extends events_1.default {
constructor(sync) {
super();
this.sync = sync;
this.interval = 1000;
this.on = (event, listener) => super.on(event, listener);
this.off = (event, listener) => super.off(event, listener);
this.once = (event, listener) => super.once(event, listener);
this.emit = (event, ...args) => super.emit(event, ...args);
this.stats = this._emptyStats();
this._ignore = {};
this._timer = setInterval(() => {
return this.update();
}, this.interval);
this.update();
}
end() {
clearInterval(this._timer);
if (this.sync) {
this.sync.end();
this.sync = undefined;
}
}
async update() {
if (!this.sync) {
throw Error('Closed');
}
try {
const transfert = await this.sync.pull('/proc/stat');
const out = await new parser_1.default(transfert).readAll();
return this._parse(out.toString());
}
catch (err) {
this._error(err);
return await Promise.reject(err);
}
}
_parse(out) {
let match = null;
let val;
const stats = this._emptyStats();
while ((match = RE_CPULINE.exec(out))) {
const line = match[0];
const cols = line.split(RE_COLSEP);
const type = cols.shift();
if (!type)
continue;
if (this._ignore[type] === line) {
continue;
}
let total = 0;
for (let i = 0, len = cols.length; i < len; i++) {
val = cols[i];
total += +val;
}
stats.cpus[type] = {
line: line,
user: +cols[0] || 0,
nice: +cols[1] || 0,
system: +cols[2] || 0,
idle: +cols[3] || 0,
iowait: +cols[4] || 0,
irq: +cols[5] || 0,
softirq: +cols[6] || 0,
steal: +cols[7] || 0,
guest: +cols[8] || 0,
guestnice: +cols[9] || 0,
total,
};
}
return this._set(stats);
}
_set(stats) {
const loads = {};
let found = false;
const ref = stats.cpus;
for (const id in ref) {
const cur = ref[id];
const old = this.stats.cpus[id];
if (!old) {
continue;
}
const ticks = cur.total - old.total;
if (ticks > 0) {
found = true;
// Calculate percentages for everything. For ease of formatting,
// let's do `x / y * 100` as `100 / y * x`.
const m = 100 / ticks;
loads[id] = {
user: Math.floor(m * (cur.user - old.user)),
nice: Math.floor(m * (cur.nice - old.nice)),
system: Math.floor(m * (cur.system - old.system)),
idle: Math.floor(m * (cur.idle - old.idle)),
iowait: Math.floor(m * (cur.iowait - old.iowait)),
irq: Math.floor(m * (cur.irq - old.irq)),
softirq: Math.floor(m * (cur.softirq - old.softirq)),
steal: Math.floor(m * (cur.steal - old.steal)),
guest: Math.floor(m * (cur.guest - old.guest)),
guestnice: Math.floor(m * (cur.guestnice - old.guestnice)),
total: 100,
};
}
else {
// The CPU is either offline (nothing was done) or it mysteriously
// warped back in time (idle stat dropped significantly), causing the
// total tick count to be <0. The latter seems to only happen on
// Galaxy S4 so far. Either way we don't want those anomalies in our
// stats. We'll also ignore the line in the next cycle. This doesn't
// completely eliminate the anomalies, but it helps.
this._ignore[id] = cur.line;
delete stats.cpus[id];
}
}
if (found) {
this.emit('load', loads);
}
return (this.stats = stats);
}
_error(err) {
return this.emit('error', err);
}
_emptyStats() {
return {
cpus: {},
};
}
}
exports.default = ProcStat;
//# sourceMappingURL=stat.js.map