UNPKG

@nodefony/monitoring-bundle

Version:

Nodefony Framework Bundle Monitoring

349 lines (316 loc) 9.66 kB
var QS = require('qs'); var shortId = require("shortid"); var request = require("request"); var os = require("os"); const cpuAverage = function () { let totalIdle = 0; let totalTick = 0; let cpus = os.cpus(); //Loop through CPU cores for (let i = 0; i < cpus.length; i++) { let cpu = cpus[i]; //Total up the time in the cores tick for (let type in cpu.times) { totalTick += cpu.times[type]; } //Total up the idle time of the core totalIdle += cpu.times.idle; } //Return the average return { idle: totalIdle / cpus.length, total: totalTick / cpus.length }; }; const cpuInit = function () { let start = cpuAverage.call(this); return () => { let end = cpuAverage.call(this); let dif = {}; dif.idle = end.idle - start.idle; dif.total = end.total - start.total; dif.percent = 100 - ~~(100 * dif.idle / dif.total); this.cpu.push(dif); return dif; }; }; const averaging = class averaging { constructor() { this.timesConcurence = []; this.statusCode = {}; this.requestBySec = []; this.cpu = []; this.total = 0; } addTimeAverage(tab) { let status = {}; let time = 0; for (let i = 0; i < tab.length; i++) { time += tab[i].time; if (tab[i].statusCode in this.statusCode) { this.statusCode[tab[i].statusCode] += 1; } else { this.statusCode[tab[i].statusCode] = 1; } if (tab[i].statusCode in status) { status[tab[i].statusCode] += 1; } else { status[tab[i].statusCode] = 1; } } let res = time / tab.length; this.timesConcurence.push(res); let requestBySec = (tab.length / (time / 1000)); this.requestBySec.push(requestBySec); return { average: (res / 1000).toFixed(2), total: (time / 1000).toFixed(2), requestBySec: requestBySec.toFixed(2), statusCode: status }; } average() { let time = 0; for (let i = 0; i < this.timesConcurence.length; i++) { time += this.timesConcurence[i]; } return ((time / this.timesConcurence.length) / 1000).toFixed(2); } cpuAverage() { let idle = 0; let total = 0; let percent = 0; for (let i = 0; i < this.cpu.length; i++) { idle += this.cpu[i].idle; total += this.cpu[i].total; percent += this.cpu[i].percent; } return { idle: ((idle / this.cpu.length)).toFixed(2), total: ((total / this.cpu.length)).toFixed(2), percent: ((percent / this.cpu.length)).toFixed(2) }; } }; const testLoad = class testLoad { constructor(context, manager, options) { this.manager = manager; this.nbRequest = parseInt(options.nbRequest, 10); this.nbRequestSent = 0; this.nbError = 0; this.nbSuccess = 0; this.concurrence = parseInt(options.concurence, 10); this.interval = (this.nbRequest / this.concurrence); this.context = context; this.options = options; this.averaging = new averaging(); this.sid = options.sid; this.httpsSettings = this.manager.get("httpsServer").settings; this.rootDir = this.manager.kernel.rootDir; this.stopChain = false; this.running = false; /*this.agentOptions = { key: fs.readFileSync(this.rootDir+this.httpsSettings.certificats.key), cert: fs.readFileSync(this.rootDir+this.httpsSettings.certificats.cert), rejectUnauthorized: false, }; if ( this.httpsSettings.certificats.ca ){ this.agentOptions["ca"] = fs.readFileSync(this.rootDir+this.httpsSettings.certificats.ca) ; }*/ this.agentOptions = { "rejectUnauthorized": false }; } requests(start) { let tab = []; let cpu = cpuInit.call(this.averaging); for (let i = 0; i < this.concurrence; i++) { tab.push(this.HttpRequest()); } let myResult = null; this.running = true; //tab.map(function(ele){return ele()}) Promise.all(tab) .catch((e) => { this.manager.logger(e, "ERROR"); this.running = false; //throw e ; this.context.send(JSON.stringify({ running: this.running, message: e.message })); }) .then((result) => { //console.log(result) //this.manager.logger( "PROMISE HTTP THEN" , "DEBUG"); myResult = result; let stop = new Date().getTime(); if (result) { let addTimeAverage = this.averaging.addTimeAverage(result); let time = (stop - start); this.averaging.total += time; let sec = time / 1000; let nbRequestSec = this.concurrence / addTimeAverage.average; //this.averaging.addRequestBySec( nbRequestSec ); this.context.send(JSON.stringify({ average: addTimeAverage.average, statusCode: addTimeAverage.statusCode, requestBySecond: nbRequestSec.toFixed(2), totalTime: sec, //this.averaging.averageResquestBySec(), percentEnd: ((this.nbRequestSent * 100) / this.nbRequest).toFixed(2), nbResquest: this.nbRequestSent, running: this.running, cpu: cpu() })); if ((this.nbRequestSent < this.nbRequest) && this.stopChain === false) { this.requests(new Date().getTime()); } else { this.running = false; let avg = this.averaging.average(); this.context.send(JSON.stringify({ message: "END LOAD TEST", average: avg, averageNet: ((avg / this.concurrence) * 1000).toFixed(2), // ms totalTime: this.averaging.total / 1000, stop: stop, statusCode: this.averaging.statusCode, requestBySecond: (this.nbRequestSent / (this.averaging.total / 1000)).toFixed(2), percentEnd: 100, nbResquest: this.nbRequestSent, running: this.running, cpu: this.averaging.cpuAverage(), //prototcol:prototcol })); this.context.close(); } } }) .done(( /*ele*/ ) => { this.manager.logger("PROMISE concurrence HTTP DONE", "DEBUG"); }); } HttpRequest() { let options = { url: this.options.url, method: this.options.method || "GET", forever: true, // keepAlive followRedirect: true, agentOptions: this.agentOptions, headers: { //'User-Agent': 'NODEFONY' 'User-Agent': this.manager.userAgent }, jar: null }; if (this.context.session) { var j = request.jar(); var cookie = request.cookie(this.context.session.name + "=" + this.context.session.id); var url = options.url; j.setCookie(cookie, url); options.jar = j; } let promise = new Promise((resolve /*, reject*/ ) => { var start = new Date().getTime(); request(options, (error, response /*, body*/ ) => { var stop = new Date().getTime(); this.nbRequestSent += 1; //console.log(this.nbRequestSent); if (error) { let code = error.code; //console.log(error) this.nbError += 1; resolve({ error: error, message: error.message, statusCode: code, time: stop - start }); return; } let code = response.statusCode; resolve({ statusCode: code, time: stop - start }); }); }); return promise; } stop(sid) { this.stopChain = true; delete this.manager.connections[sid]; } handleMessage(message) { if (!message) { return; } switch (message.action) { case "stop": this.stop(this.sid); break; default: return; } } }; // service module.exports = class serverLoad extends nodefony.Service { constructor(container, kernel) { super("serverLoad", container, container.get("notificationsCenter")); this.kernel = kernel; this.connections = {}; this.userAgent = "nodefony/" + this.kernel.settings.version + " (" + process.platform + ";" + process.arch + ") V8/" + process.versions.v8 + " node/" + process.versions.node; } logger(pci, severity, msgid) { if (!msgid) { msgid = "\x1b[34m SERVICE SERVER LOAD \x1b[0m"; } if (this.realTime) { return this.realTime.logger(pci, severity, msgid); } else { return this.kernel.logger(pci, severity, msgid); } } handleConnection(message, context) { switch (message.type) { case "action": if (message.sid) { this.connections[message.sid].handleMessage(message); return; } break; default: if (message.query) { let obj = QS.parse(message.query); this.loadHTTP(context, obj); } else { this.loadHTTP(context, message); } } } loadHTTP(context, options) { let sid = null; if (!options.sid) { sid = shortId.generate(); let start = new Date().getTime(); context.send(JSON.stringify({ message: "START LOAD TEST", nbRequest: options.nbRequest, running: true, concurence: options.concurence, percentEnd: 0, start: start, sid: sid })); this.connections[sid] = new testLoad(context, this, options); this.connections[sid].requests(start); } else { sid = options.sid; this.connections[sid].context = null; this.connections[sid].context = context; } context.listen(this, "onClose", function () { this.connections[sid].stop(sid); }); } };