Initial commit
This commit is contained in:
203
node_modules/ping/lib/parser/base.js
generated
vendored
Normal file
203
node_modules/ping/lib/parser/base.js
generated
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
'use strict';
|
||||
|
||||
/* eslint no-unused-vars: 0 */
|
||||
|
||||
var __ = require('underscore');
|
||||
|
||||
/**
|
||||
* Parsed response
|
||||
* @typedef {object} PingResponse
|
||||
* @param {string} inputHost - The input IP address or HOST
|
||||
* @param {string} host - The input IP address or HOST
|
||||
* @param {string} numeric_host - Target IP address
|
||||
* @param {boolean} alive - True for existed host
|
||||
* @param {string} output - Raw stdout from system ping
|
||||
* @param {number} time - Time (float) in ms for first successful ping response
|
||||
* @param {string} min - Minimum time for collection records
|
||||
* @param {string} max - Maximum time for collection records
|
||||
* @param {string} avg - Average time for collection records
|
||||
* @param {number} packetLoss - Packet Losses in percent (number)
|
||||
* @param {string} stddev - Standard deviation time for collected records
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*
|
||||
* @param {string} addr - Hostname or ip addres
|
||||
* @param {PingConfig} config - Config object in probe()
|
||||
*/
|
||||
function parser(addr, config) {
|
||||
// Initial state is 0
|
||||
this._state = 0;
|
||||
|
||||
// Initial cache value
|
||||
this._response = {
|
||||
inputHost: addr,
|
||||
host: 'unknown',
|
||||
alive: false,
|
||||
output: 'unknown',
|
||||
time: 'unknown',
|
||||
times: [],
|
||||
min: 'unknown',
|
||||
max: 'unknown',
|
||||
avg: 'unknown',
|
||||
stddev: 'unknown',
|
||||
packetLoss: 'unknown',
|
||||
};
|
||||
|
||||
// Initial times storage for ping time
|
||||
this._times = [];
|
||||
|
||||
// Initial lines storage for ping output
|
||||
this._lines = [];
|
||||
|
||||
// strip string regexp
|
||||
this._stripRegex = /[ ]*\r?\n?$/g;
|
||||
|
||||
// Ping Config
|
||||
this._pingConfig = config || {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum for parser states
|
||||
* @readonly
|
||||
* @enum {number}
|
||||
*/
|
||||
parser.prototype.STATES = {
|
||||
INIT: 0,
|
||||
HEADER: 1,
|
||||
BODY: 2,
|
||||
FOOTER: 3,
|
||||
END: 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* Change state of this parser
|
||||
* @param {number} state - parser.STATES
|
||||
* @return {this} - This instance
|
||||
*/
|
||||
parser.prototype._changeState = function (state) {
|
||||
var states = __.values(this.STATES);
|
||||
if (states.indexOf(state) < 0) {
|
||||
throw new Error('Unknown state');
|
||||
}
|
||||
|
||||
this._state = state;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Process output's header
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
parser.prototype._processHeader = function (line) {
|
||||
throw new Error('Subclass should implement this method');
|
||||
};
|
||||
|
||||
/**
|
||||
* Process output's body
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
parser.prototype._processBody = function (line) {
|
||||
throw new Error('Subclass should implement this method');
|
||||
};
|
||||
|
||||
/**
|
||||
* Process output's footer
|
||||
* @param {string} line - A line from system ping
|
||||
*/
|
||||
parser.prototype._processFooter = function (line) {
|
||||
throw new Error('Subclass should implement this method');
|
||||
};
|
||||
|
||||
/**
|
||||
* Process a line from system ping
|
||||
* @param {string} line - A line from system ping
|
||||
* @return {this} - This instance
|
||||
*/
|
||||
parser.prototype.eat = function (line) {
|
||||
var headerStates = [
|
||||
this.STATES.INIT,
|
||||
this.STATES.HEADER,
|
||||
];
|
||||
|
||||
// Store lines
|
||||
this._lines.push(line);
|
||||
|
||||
// Strip all space \r\n at the end
|
||||
var _line = line.replace(this._stripRegex, '');
|
||||
|
||||
if (_line.length === 0) {
|
||||
// Do nothing if this is an empty line
|
||||
} else if (headerStates.indexOf(this._state) >= 0) {
|
||||
this._processHeader(_line);
|
||||
} else if (this._state === this.STATES.BODY) {
|
||||
this._processBody(_line);
|
||||
} else if (this._state === this.STATES.FOOTER) {
|
||||
this._processFooter(_line);
|
||||
} else if (this._state === this.STATES.END) {
|
||||
// Do nothing
|
||||
} else {
|
||||
throw new Error('Unknown state');
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get results after parsing certain lines from system ping
|
||||
* @return {PingResponse} - Response from parsing ping output
|
||||
*/
|
||||
parser.prototype.getResult = function () {
|
||||
var ret = __.extend({}, this._response);
|
||||
|
||||
// Concat output
|
||||
ret.output = this._lines.join('\n');
|
||||
|
||||
// Determine alive
|
||||
ret.alive = this._times.length > 0;
|
||||
|
||||
// Update time at first successful line
|
||||
if (ret.alive) {
|
||||
this._response.time = this._times[0];
|
||||
ret.time = this._response.time;
|
||||
this._response.times = this._times;
|
||||
ret.times = this._response.times;
|
||||
}
|
||||
|
||||
// Get stddev
|
||||
if (
|
||||
ret.stddev === 'unknown' && ret.alive
|
||||
) {
|
||||
var numberOfSamples = this._times.length;
|
||||
|
||||
var sumOfAllSquareDifferences = __.reduce(
|
||||
this._times,
|
||||
function (memory, time) {
|
||||
var differenceFromMean = time - ret.avg;
|
||||
var squaredDifference =
|
||||
differenceFromMean * differenceFromMean;
|
||||
return memory + squaredDifference;
|
||||
},
|
||||
0
|
||||
);
|
||||
var variances = sumOfAllSquareDifferences / numberOfSamples;
|
||||
|
||||
ret.stddev = Math.round(
|
||||
Math.sqrt(variances) * 1000
|
||||
) / 1000;
|
||||
}
|
||||
|
||||
// Fix min, avg, max, stddev up to 3 decimal points
|
||||
__.each(['min', 'avg', 'max', 'stddev', 'packetLoss'], function (key) {
|
||||
var v = ret[key];
|
||||
if (__.isNumber(v)) {
|
||||
ret[key] = v.toFixed(3);
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
module.exports = parser;
|
Reference in New Issue
Block a user