Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI: Improved stats charts #4727

Merged
merged 64 commits into from
Oct 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
a8480fa
An array subclass that enforces a maxLength
DingoEatingFuzz Aug 30, 2018
5c5e44d
An abstract class for capturing nomad stats
DingoEatingFuzz Aug 30, 2018
1df44a6
An implementation of StatsTracker for allocations
DingoEatingFuzz Aug 30, 2018
0082272
Example of usage of the AllocationsStatsTracker
DingoEatingFuzz Aug 30, 2018
d25c0d6
Unit tests for RollingArray
DingoEatingFuzz Aug 31, 2018
405cf82
Unit Tests for AllocationStatsTracker
DingoEatingFuzz Aug 31, 2018
c455a39
A StatsTracker for client-level statistics
DingoEatingFuzz Aug 31, 2018
3c09777
Example usage of the NodeStatsTracker
DingoEatingFuzz Aug 31, 2018
e8c860b
Bring in new d3 dependencies
DingoEatingFuzz Sep 7, 2018
5b927d3
Add chart color swatches based on css colors
DingoEatingFuzz Sep 7, 2018
dc63be2
Add support for non-list tooltips in charts
DingoEatingFuzz Sep 7, 2018
f8c8c3c
Test coverage for NodeStatsTracker
DingoEatingFuzz Aug 31, 2018
1002eeb
Merge pull request #4635 from hashicorp/f-ui-stat-trackers
DingoEatingFuzz Sep 13, 2018
48df4d2
New line chart component
DingoEatingFuzz Sep 7, 2018
5e09491
Styleguide entry for the line chart component
DingoEatingFuzz Sep 7, 2018
bb40cb0
Don't round numbers when the domain is between 0 and 1
DingoEatingFuzz Sep 8, 2018
db6ad98
Make the tooltip animation snappier for line charts
DingoEatingFuzz Sep 8, 2018
0d7c22f
Stats time series
DingoEatingFuzz Sep 8, 2018
b84d755
Avoid race conditions around showing and hiding the line chart tooltip
DingoEatingFuzz Sep 8, 2018
4b67b76
Use "global" gradients via a clipping mask and a rect w/100% height
DingoEatingFuzz Sep 8, 2018
a3e858e
Updates to the styleguide
DingoEatingFuzz Sep 10, 2018
fd80df6
Split the line-chart and stats-time-series freestyle entries
DingoEatingFuzz Sep 10, 2018
40861aa
Unit test coverage for the line chart component
DingoEatingFuzz Sep 11, 2018
efb1301
Unit test coverage for the stats-time-series chart
DingoEatingFuzz Sep 11, 2018
5e2edf8
Merge pull request #4661 from hashicorp/f-ui-line-chart
DingoEatingFuzz Sep 13, 2018
4cd9164
Use addObject to get kvo behaviors
DingoEatingFuzz Sep 13, 2018
48d0220
Use percent for the y-axis binding
DingoEatingFuzz Sep 13, 2018
b80016d
Add stat charts to the client page
DingoEatingFuzz Sep 13, 2018
44b16b2
Full markup for time series metrics
DingoEatingFuzz Sep 13, 2018
48910d8
New primary-metric component
DingoEatingFuzz Sep 13, 2018
76f9c13
Use the new primary-metric component on the client detail page
DingoEatingFuzz Sep 13, 2018
1572e8d
Remove old stat tracking code from the client page
DingoEatingFuzz Sep 13, 2018
9a102b7
Make rollingArray work with mutable array extension methods
DingoEatingFuzz Sep 14, 2018
adc0597
Use the prototype instead of "private" property backups
DingoEatingFuzz Sep 14, 2018
79c8667
Handle the length = 0 and length = 1 cases for activeDatum
DingoEatingFuzz Sep 14, 2018
5834919
Style the primary-metric pattern
DingoEatingFuzz Sep 14, 2018
f84b145
Use the appropriate methods and types in the stat trackers
DingoEatingFuzz Sep 14, 2018
509f42c
Add resource utilization graphs to the allocation index page
DingoEatingFuzz Sep 14, 2018
7c24847
Add resource utilization graphs to the task index page
DingoEatingFuzz Sep 14, 2018
cf9490c
New service to manage stats trackers
DingoEatingFuzz Sep 17, 2018
1a6682d
New LRUMap dep
DingoEatingFuzz Sep 17, 2018
81788cf
Clean up old controller code
DingoEatingFuzz Sep 17, 2018
670b246
Use the new stats tracker service to get stats trackers in primary me…
DingoEatingFuzz Sep 17, 2018
f0208c0
Add request throttling to the abstract stats tracker
DingoEatingFuzz Sep 17, 2018
cf57ddc
Gap support for line charts
DingoEatingFuzz Sep 17, 2018
8de545c
Add cancelation support to stats trackers
DingoEatingFuzz Sep 17, 2018
0ede4c5
Integration tests for the primary-metric component
DingoEatingFuzz Sep 19, 2018
01195a8
Unit tests for the stats trackers service
DingoEatingFuzz Sep 19, 2018
28d8f79
Handle the empty data cases
DingoEatingFuzz Sep 19, 2018
f4ae9e1
Always return valid dates for timestamps
DingoEatingFuzz Sep 19, 2018
866f650
Acceptance test coverage for all the pages with resource utilization …
DingoEatingFuzz Sep 19, 2018
47ec74e
Update stat tracker unit tests
DingoEatingFuzz Sep 20, 2018
f5eaffe
Merge pull request #4704 from hashicorp/f-ui-applied-stat-charts
DingoEatingFuzz Sep 26, 2018
65336cc
Use the StatsTracker method of getting alloc stats in alloc row
DingoEatingFuzz Sep 20, 2018
4d5fa15
Remove no longer used allocation-stats class
DingoEatingFuzz Sep 20, 2018
1e34a6a
Add utilization stats to the task rows on allocation detail
DingoEatingFuzz Sep 21, 2018
9a6d2be
Add a longForm option to format-duration
DingoEatingFuzz Sep 25, 2018
d83d231
Add a11y features to the line-chart component
DingoEatingFuzz Sep 25, 2018
6d4d520
Override the a11y title and description for the stats time series chart
DingoEatingFuzz Sep 25, 2018
2c20678
Add role="tooltip" to tooltips throughout the app
DingoEatingFuzz Oct 17, 2018
fd415fe
Merge pull request #4726 from hashicorp/f-ui-use-stats-trackers-for-r…
DingoEatingFuzz Oct 17, 2018
3517c7c
Be consistent with "time series" instead of "time-series"
DingoEatingFuzz Oct 17, 2018
35b933a
Add more documentation to the format-duration util
DingoEatingFuzz Oct 17, 2018
f02d99a
Merge pull request #4718 from hashicorp/f-ui-a11y-line-chart
DingoEatingFuzz Oct 17, 2018
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
31 changes: 18 additions & 13 deletions ui/app/components/allocation-row.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import Ember from 'ember';
import { inject as service } from '@ember/service';
import Component from '@ember/component';
import { computed } from '@ember/object';
import { alias } from '@ember/object/computed';
import { run } from '@ember/runloop';
import { lazyClick } from '../helpers/lazy-click';
import { task, timeout } from 'ember-concurrency';
import { lazyClick } from '../helpers/lazy-click';
import AllocationStatsTracker from 'nomad-ui/utils/classes/allocation-stats-tracker';

export default Component.extend({
store: service(),
token: service(),

tagName: 'tr',

Expand All @@ -18,14 +21,21 @@ export default Component.extend({
// Used to determine whether the row should mention the node or the job
context: null,

backoffSequence: computed(() => [500, 800, 1300, 2100, 3400, 5500]),

// Internal state
stats: null,
statsError: false,

enablePolling: computed(() => !Ember.testing),

stats: computed('allocation', function() {
return AllocationStatsTracker.create({
fetch: url => this.get('token').authorizedRequest(url),
allocation: this.get('allocation'),
});
}),

cpu: alias('stats.cpu.lastObject'),
memory: alias('stats.memory.lastObject'),

onClick() {},

click(event) {
Expand All @@ -39,31 +49,26 @@ export default Component.extend({
run.scheduleOnce('afterRender', this, qualifyAllocation);
} else {
this.get('fetchStats').cancelAll();
this.set('stats', null);
}
},

fetchStats: task(function*(allocation) {
const backoffSequence = this.get('backoffSequence').slice();
const maxTiming = backoffSequence.pop();

fetchStats: task(function*() {
do {
try {
const stats = yield allocation.fetchStats();
this.set('stats', stats);
yield this.get('stats.poll').perform();
this.set('statsError', false);
} catch (error) {
this.set('statsError', true);
}
yield timeout(backoffSequence.shift() || maxTiming);
yield timeout(500);
} while (this.get('enablePolling'));
}).drop(),
});

function qualifyAllocation() {
const allocation = this.get('allocation');
return allocation.reload().then(() => {
this.get('fetchStats').perform(allocation);
this.get('fetchStats').perform();

// Make sure that the job record in the store for this allocation
// is complete and not a partial from the list endpoint
Expand Down
76 changes: 76 additions & 0 deletions ui/app/components/freestyle/sg-line-chart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import d3TimeFormat from 'd3-time-format';

export default Component.extend({
timerTicks: 0,

startTimer: function() {
this.set(
'timer',
setInterval(() => {
this.incrementProperty('timerTicks');

const ref = this.get('lineChartLive');
ref.addObject({ ts: Date.now(), val: Math.random() * 30 + 20 });
if (ref.length > 60) {
ref.splice(0, ref.length - 60);
}
}, 500)
);
}.on('init'),

willDestroy() {
clearInterval(this.get('timer'));
},

lineChartData: computed(() => {
return [
{ year: 2010, value: 10 },
{ year: 2011, value: 10 },
{ year: 2012, value: 20 },
{ year: 2013, value: 30 },
{ year: 2014, value: 50 },
{ year: 2015, value: 80 },
{ year: 2016, value: 130 },
{ year: 2017, value: 210 },
{ year: 2018, value: 340 },
];
}),

lineChartMild: computed(() => {
return [
{ year: 2010, value: 100 },
{ year: 2011, value: 90 },
{ year: 2012, value: 120 },
{ year: 2013, value: 130 },
{ year: 2014, value: 115 },
{ year: 2015, value: 105 },
{ year: 2016, value: 90 },
{ year: 2017, value: 85 },
{ year: 2018, value: 90 },
];
}),

lineChartGapData: computed(() => {
return [
{ year: 2010, value: 10 },
{ year: 2011, value: 10 },
{ year: 2012, value: null },
{ year: 2013, value: 30 },
{ year: 2014, value: 50 },
{ year: 2015, value: 80 },
{ year: 2016, value: null },
{ year: 2017, value: 210 },
{ year: 2018, value: 340 },
];
}),

lineChartLive: computed(() => {
return [];
}),

secondsFormat() {
return d3TimeFormat.timeFormat('%H:%M:%S');
},
});
76 changes: 76 additions & 0 deletions ui/app/components/freestyle/sg-stats-time-series.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import d3TimeFormat from 'd3-time-format';
import moment from 'moment';

export default Component.extend({
timerTicks: 0,

startTimer: function() {
this.set(
'timer',
setInterval(() => {
const metricsHigh = this.get('metricsHigh');
const prev = metricsHigh.length ? metricsHigh[metricsHigh.length - 1].value : 0.9;
this.appendTSValue(
metricsHigh,
Math.min(Math.max(prev + Math.random() * 0.05 - 0.025, 0.5), 1)
);

const metricsLow = this.get('metricsLow');
const prev2 = metricsLow.length ? metricsLow[metricsLow.length - 1].value : 0.1;
this.appendTSValue(
metricsLow,
Math.min(Math.max(prev2 + Math.random() * 0.05 - 0.025, 0), 0.5)
);
}, 1000)
);
}.on('init'),

appendTSValue(array, value, maxLength = 300) {
array.addObject({
timestamp: Date.now(),
value,
});

if (array.length > maxLength) {
array.splice(0, array.length - maxLength);
}
},

willDestroy() {
clearInterval(this.get('timer'));
},

metricsHigh: computed(() => {
return [];
}),

metricsLow: computed(() => {
return [];
}),

staticMetrics: computed(() => {
const ts = offset =>
moment()
.subtract(offset, 'm')
.toDate();
return [
{ timestamp: ts(20), value: 0.5 },
{ timestamp: ts(18), value: 0.5 },
{ timestamp: ts(16), value: 0.4 },
{ timestamp: ts(14), value: 0.3 },
{ timestamp: ts(12), value: 0.9 },
{ timestamp: ts(10), value: 0.3 },
{ timestamp: ts(8), value: 0.3 },
{ timestamp: ts(6), value: 0.4 },
{ timestamp: ts(4), value: 0.5 },
{ timestamp: ts(2), value: 0.6 },
{ timestamp: ts(0), value: 0.6 },
];
}),

secondsFormat() {
return d3TimeFormat.timeFormat('%H:%M:%S');
},
});
Loading