Skip to content
This repository was archived by the owner on Mar 4, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/nodejs-dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var parseSettings = require("../lib/parse-settings");
var appName = appPkg.name || "node";
var program = new commander.Command(pkg.name);

// Mimic commander sintax errors (with offsets) for consistency
// Mimic commander syntax errors (with offsets) for consistency
/* eslint-disable no-console */
var exitWithError = function () {
var args = Array.prototype.slice.call(arguments);
Expand Down
12 changes: 6 additions & 6 deletions lib/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var generateLayouts = require("./generate-layouts");
var LogProvider = require("./providers/log-provider");
var MetricsProvider = require("./providers/metrics-provider");
var BaseView = require("./views/base-view");
var GotoTimeView = require("./views/goto-time-view.js");
var GotoTimeView = require("./views/goto-time-view");

var THROTTLE_TIMEOUT = 150;

Expand Down Expand Up @@ -72,21 +72,21 @@ Dashboard.prototype._configureKeys = function () {
this._showLayout(target);
}.bind(this), THROTTLE_TIMEOUT));

var helpNode = this.helpView.node;
this.container.key(["?", "h", "S-h"], function () {
helpNode.toggle();
this.gotoTimeView.hide();
this.helpView.toggle();
this.screen.render();
}.bind(this));

this.container.key(["g", "S-g"], function () {
helpNode.hide();
this.helpView.hide();
this.gotoTimeView.toggle();
this.screen.render();
}.bind(this));

this.container.key("escape", function () {
if (helpNode.visible || this.gotoTimeView.isVisible()) {
helpNode.hide();
if (this.helpView.isVisible() || this.gotoTimeView.isVisible()) {
this.helpView.hide();
this.gotoTimeView.hide();
this.screen.render();
} else {
Expand Down
191 changes: 9 additions & 182 deletions lib/providers/metrics-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@

var EventEmitter = require("events").EventEmitter;
var _ = require("lodash");
var constants = require("../constants");
var time = require("../time");

// get the defined aggregation levels
var AGGREGATE_TIME_LEVELS = require("../constants.js").AGGREGATE_TIME_LEVELS;
var TIME_SCALES = require("../constants.js").TIME_SCALES;
var AGGREGATE_TIME_LEVELS = constants.AGGREGATE_TIME_LEVELS;

// what a valid time offset looks like
var TIME_LABEL_PATTERN = /^(\d+y)?\s*(\d{1,3}d)?\s*(\d{1,2})?(:\d{1,2})?(:\d{2})?$/i;
Expand Down Expand Up @@ -78,177 +79,6 @@ var MetricsProvider =
// MetricsProvider inherits from EventEmitter
MetricsProvider.prototype = Object.create(EventEmitter.prototype);

/**
* Given a time index and unit of time measure, compute a condensed, human-readable label.
*
* @param {Number} timeIndex
* The logical index of time.
*
* @param {Number} aggregateTimeUnits
* The unit of time measure.
*
* @returns {String}
* A scaled, string-representation of time at the index is returned.
*/
var getTimeIndexLabel =
function getTimeIndexLabel(timeIndex, aggregateTimeUnits) {
var DIGITS_PER_UNIT = 2;

var timeValue = timeIndex * aggregateTimeUnits;
var timeElements = [];

if (timeValue === 0) {
return ":00";
}

_.every(TIME_SCALES, function (timeScale, index, timeScales) {
var timeElement = {
units: timeScale.units,
value: 0
};

// stop reducing when it cannot be divided
if (timeValue < timeScale.divisor) {
return false;
}

// don't capture a time element for milliseconds
if (timeScale.units !== "ms") {
// reduce by the divisor
timeElement.value = timeValue / timeScale.divisor;

// if there are more elements after, take the modulo to get the remainder
if (index < timeScales.length - 1) {
timeElement.value = Math.floor(timeElement.value % timeScales[index + 1].divisor);
} else {
timeElement.value = Math.floor(timeElement.value);
}

timeElements.push(timeElement);
}

// reduce
timeValue /= timeScale.divisor;

return true;
});

return _.reduce(timeElements, function (prev, curr, index) {
switch (curr.units) {
case "s":
return ":" + _.padStart(curr.value, DIGITS_PER_UNIT, "0");
case "m":
case "h":
if (index < timeElements.length - 1) {
return (curr.units === "m" ? ":" : " ")
+ _.padStart(curr.value, DIGITS_PER_UNIT, "0")
+ prev;
} else {
return curr.value + prev;
}
default:
return curr.value + curr.units + prev;
}
}, "");
};

/**
* Given a time label value (ex: 2y 5d 1:22:33), produce the actual
* time value in ms.
*
* @param {String} label
* The time label to convert.
*
* @throws {Error}
* An error is thrown if the time label cannot be converted to ms.
*
* @returns {Number}
* The time value in ms is returned.
*/
var convertTimeLabelToMilliseconds = function (label) {
/* eslint-disable no-magic-numbers */

// a container for all time elements
var timeElements = {
y: 0,
d: 0,
t: [],
h: 0,
m: 0,
s: 0
};

// the initial divisor
var divisor = TIME_SCALES[0].divisor;

// break up the input
var split = TIME_LABEL_PATTERN.exec(label);

// take the broken apart pieces and consume them
_.each(_.slice(split, 1), function (value, index) {
var pieces;

// skip undefined values
if (value === undefined) {
return;
}

// get the numeric and unit components, if any
pieces = /^:?(\d*)([yd])?/.exec(value);

switch (index) {
case 0:
case 1:
// year and day are just keys
timeElements[pieces[2]] = +pieces[1];
break;
case 2:
case 3:
case 4:
// time is only slightly trickier; missing elements get pushed down
timeElements.t.push(+pieces[1]);
break;
}
});

while (timeElements.t.length < 3) {
// complete the time picture with leading zeros
timeElements.t.unshift(0);
}

// convert time parts to keys
timeElements.h = timeElements.t[0];
timeElements.m = timeElements.t[1];
timeElements.s = timeElements.t[2];

// now we can discard the time array
delete timeElements.t;

// now, reduce the time elements by the scaling factors
return _.reduce(TIME_SCALES, function (prev, timeScale, index) {
// the divisor grows with each time scale factor
divisor *= timeScale.divisor;

// if the time element is represented, multiply by current divisor
if (timeElements[timeScale.units]) {
// if there are more time scales to go, make sure the current value
// does not exceed its limits (ex: 90s should be 1:30 instead)
if (index < TIME_SCALES.length - 1) {
if (timeElements[timeScale.units] >= TIME_SCALES[index + 1].divisor) {
throw new Error("Enter a valid time value");
}
}

// continue to accumulate the time
prev += timeElements[timeScale.units] * divisor;
}

return prev;
}, 0);

/* eslint-enable no-magic-numbers */
};

/**
* Given a moment in time, the start time, and time units, produce the
* correct time index.
Expand Down Expand Up @@ -304,18 +134,15 @@ MetricsProvider.prototype.setZoomLevel = function setZoomLevel(zoom) {
* An object containing the time range is returned
*/
MetricsProvider.prototype.getAvailableTimeRange = function getAvailableTimeRange() {
var maxAverages = this._aggregation[this.lowestAggregateTimeUnits].data.length - 1;
return {
minTime: {
label: getTimeIndexLabel(0, this.lowestAggregateTimeUnits),
label: time.getLabel(0),
value: 0
},
maxTime: {
label: getTimeIndexLabel(
this._aggregation[this.lowestAggregateTimeUnits].data.length - 1,
this.lowestAggregateTimeUnits
),
value: (this._aggregation[this.lowestAggregateTimeUnits].data.length - 1)
* this.lowestAggregateTimeUnits
label: time.getLabel(maxAverages * this.lowestAggregateTimeUnits),
value: maxAverages * this.lowestAggregateTimeUnits
}
};
};
Expand Down Expand Up @@ -758,7 +585,7 @@ MetricsProvider.prototype.getXAxis =
timeIndex >= -scrollOffset;
timeIndex--
) {
xAxis.push(getTimeIndexLabel(timeIndex, +this.zoomLevelKey));
xAxis.push(time.getLabel(timeIndex * +this.zoomLevelKey));
}

return xAxis;
Expand Down Expand Up @@ -792,7 +619,7 @@ MetricsProvider.prototype.validateTimeLabel =
}

// must be able to convert (this can throw too)
timeValue = convertTimeLabelToMilliseconds(label);
timeValue = time.convertTimeLabelToMilliseconds(label);

// must be a number in range
if (isNaN(timeValue) || !_.inRange(timeValue, 0, timeRange.maxTime.value + 1)) {
Expand Down
Loading