Skip to content

Commit 57a2a0b

Browse files
committed
Merge pull request #1347 from shapeblue/4.7-metrics-fixes
ui: improve metrics view implementation- Implement Search boxes in all Metrics views - Fix threshold calculations for host and storage pool metrics view - Consider overcommit ratios for calculation allocated thresholds - Save/pass context while navigating across resources and metrics view cc @remibergsma @DaanHoogland ![screen shot 2016-01-18 at 12 55 42 pm](https://cloud.githubusercontent.com/assets/95203/12390720/dfec51a0-bde2-11e5-8bdd-373f41a9c5d4.png) ![screen shot 2016-01-18 at 12 56 08 pm](https://cloud.githubusercontent.com/assets/95203/12390731/ee572cb0-bde2-11e5-8228-087cc506958e.png) ![screen shot 2016-01-18 at 12 55 55 pm](https://cloud.githubusercontent.com/assets/95203/12390732/ee58163e-bde2-11e5-9d78-befc6cd3f145.png) * pr/1347: ui: improve metrics view implementation Signed-off-by: Remi Bergsma <github@remi.nl>
2 parents f0fca60 + 750c11b commit 57a2a0b

File tree

2 files changed

+127
-48
lines changed

2 files changed

+127
-48
lines changed

ui/scripts/metrics.js

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -575,8 +575,8 @@
575575
label: 'label.metrics.allocated',
576576
thresholdcolor: true,
577577
thresholds: {
578-
notification: 'cpunotificationthreshold',
579-
disable: 'cpudisablethreshold'
578+
notification: 'cpuallocatednotificationthreshold',
579+
disable: 'cpuallocateddisablethreshold'
580580
}
581581
}
582582
}
@@ -600,8 +600,8 @@
600600
label: 'label.metrics.allocated',
601601
thresholdcolor: true,
602602
thresholds: {
603-
notification: 'memnotificationthreshold',
604-
disable: 'memdisablethreshold'
603+
notification: 'memallocatednotificationthreshold',
604+
disable: 'memallocateddisablethreshold'
605605
}
606606
}
607607
}
@@ -656,11 +656,31 @@
656656
items[idx].networkwrite = '';
657657
}
658658

659+
var cpuOverCommit = 1.0;
660+
var memOverCommit = 1.0;
661+
$.ajax({
662+
url: createURL('listClusters'),
663+
data: {clusterid: host.clusterid, listAll: true},
664+
success: function(json) {
665+
if (json.listclustersresponse && json.listclustersresponse.cluster) {
666+
var cluster = json.listclustersresponse.cluster[0];
667+
cpuOverCommit = parseFloat(cluster.cpuovercommitratio);
668+
memOverCommit = parseFloat(cluster.memoryovercommitratio);
669+
}
670+
},
671+
async: false
672+
});
673+
659674
// Threshold color coding
660675
items[idx].cpunotificationthreshold = 0.75 * parseFloat(items[idx].cputotal);
661676
items[idx].cpudisablethreshold = 0.95 * parseFloat(items[idx].cputotal);
677+
items[idx].cpuallocatednotificationthreshold = 0.75 * cpuOverCommit * parseFloat(items[idx].cputotal);
678+
items[idx].cpuallocateddisablethreshold = 0.95 * cpuOverCommit * parseFloat(items[idx].cputotal);
679+
662680
items[idx].memnotificationthreshold = 0.75 * parseFloat(items[idx].memtotal);
663681
items[idx].memdisablethreshold = 0.95 * parseFloat(items[idx].memtotal);
682+
items[idx].memallocatednotificationthreshold = 0.75 * memOverCommit * parseFloat(items[idx].memtotal);
683+
items[idx].memallocateddisablethreshold = 0.95 * memOverCommit * parseFloat(items[idx].memtotal);
664684

665685
$.ajax({
666686
url: createURL('listConfigurations'),
@@ -671,15 +691,19 @@
671691
switch (config.name) {
672692
case 'cluster.cpu.allocated.capacity.disablethreshold':
673693
items[idx].cpudisablethreshold = parseFloat(config.value) * parseFloat(items[idx].cputotal);
694+
items[idx].cpuallocateddisablethreshold = parseFloat(config.value) * cpuOverCommit * parseFloat(items[idx].cputotal);
674695
break;
675696
case 'cluster.cpu.allocated.capacity.notificationthreshold':
676697
items[idx].cpunotificationthreshold = parseFloat(config.value) * parseFloat(items[idx].cputotal);
698+
items[idx].cpuallocatednotificationthreshold = parseFloat(config.value) * cpuOverCommit * parseFloat(items[idx].cputotal);
677699
break;
678700
case 'cluster.memory.allocated.capacity.disablethreshold':
679701
items[idx].memdisablethreshold = parseFloat(config.value) * parseFloat(items[idx].memtotal);
702+
items[idx].memallocateddisablethreshold = parseFloat(config.value) * memOverCommit * parseFloat(items[idx].memtotal);
680703
break;
681704
case 'cluster.memory.allocated.capacity.notificationthreshold':
682705
items[idx].memnotificationthreshold = parseFloat(config.value) * parseFloat(items[idx].memtotal);
706+
items[idx].memallocatednotificationthreshold = parseFloat(config.value) * memOverCommit * parseFloat(items[idx].memtotal);
683707
break;
684708
}
685709
});
@@ -688,20 +712,6 @@
688712
async: false
689713
});
690714

691-
var cpuOverCommit = 1.0;
692-
var memOverCommit = 1.0;
693-
$.ajax({
694-
url: createURL('listClusters'),
695-
data: {clusterid: host.clusterid, listAll: true},
696-
success: function(json) {
697-
if (json.listclustersresponse && json.listclustersresponse.cluster) {
698-
var cluster = json.listclustersresponse.cluster[0];
699-
cpuOverCommit = cluster.cpuovercommitratio;
700-
memOverCommit = cluster.memoryovercommitratio;
701-
}
702-
},
703-
async: false
704-
});
705715

706716
items[idx].cputotal = items[idx].cputotal + ' Ghz (x' + cpuOverCommit + ')';
707717
items[idx].memtotal = items[idx].memtotal + ' (x' + memOverCommit + ')';
@@ -1081,13 +1091,13 @@
10811091
$.each(json.listconfigurationsresponse.configuration, function(i, config) {
10821092
switch (config.name) {
10831093
case 'cluster.storage.allocated.capacity.notificationthreshold':
1084-
items[idx].storageallocatednotificationthreshold = parseFloat(config.value) * parseFloat(items[idx].disksizetotal);
1094+
items[idx].storageallocatednotificationthreshold = parseFloat(config.value) * items[idx].overprovisionfactor * parseFloat(items[idx].disksizetotal);
10851095
break;
10861096
case 'cluster.storage.capacity.notificationthreshold':
10871097
items[idx].storagenotificationthreshold = parseFloat(config.value) * parseFloat(items[idx].disksizetotal);
10881098
break;
10891099
case 'pool.storage.allocated.capacity.disablethreshold':
1090-
items[idx].storageallocateddisablethreshold = parseFloat(config.value) * parseFloat(items[idx].disksizetotal);
1100+
items[idx].storageallocateddisablethreshold = parseFloat(config.value) * items[idx].overprovisionfactor * parseFloat(items[idx].disksizetotal);
10911101
break;
10921102
case 'pool.storage.capacity.disablethreshold':
10931103
items[idx].storagedisablethreshold = parseFloat(config.value) * parseFloat(items[idx].disksizetotal);

ui/scripts/ui-custom/metricsView.js

Lines changed: 97 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,79 @@
1717
(function($, cloudStack) {
1818

1919
cloudStack.uiCustom.metricsView = function(args) {
20-
return function() {
20+
return function(ctxArgs) {
21+
2122
var metricsListView = cloudStack.sections.metrics.listView;
2223
var metricsLabel = _l('label.metrics');
24+
var context = {};
25+
if (ctxArgs && ctxArgs.hasOwnProperty('context')) {
26+
context = ctxArgs.context;
27+
}
2328

2429
if (args.resource == 'zones') {
25-
metricsListView = cloudStack.sections.metrics.zones.listView;
2630
metricsLabel = _l('label.zones') + ' ' + metricsLabel;
31+
metricsListView = cloudStack.sections.metrics.zones.listView;
32+
2733
} else if (args.resource == 'clusters') {
28-
metricsListView = cloudStack.sections.metrics.clusters.listView;
2934
metricsLabel = _l('label.clusters') + ' ' + metricsLabel;
35+
metricsListView = cloudStack.sections.metrics.clusters.listView;
36+
3037
} else if (args.resource == 'hosts') {
31-
metricsListView = cloudStack.sections.metrics.hosts.listView;
3238
metricsLabel = _l('label.hosts') + ' ' + metricsLabel;
39+
metricsListView = cloudStack.sections.metrics.hosts.listView;
40+
41+
if (context && !context.filterBy) {
42+
if (context.hasOwnProperty('clusters') && context.clusters[0]) {
43+
context.filterBy = 'clusterid';
44+
context.id = context.clusters[0].id;
45+
}
46+
if (context.hasOwnProperty('instances') && context.instances[0]) {
47+
context.filterBy = 'virtualmachineid';
48+
context.id = context.instances[0].id;
49+
}
50+
}
3351
} else if (args.resource == 'storagepool') {
34-
metricsListView = cloudStack.sections.metrics.storagepool.listView;
3552
metricsLabel = _l('label.primary.storage') + ' ' + metricsLabel;
53+
metricsListView = cloudStack.sections.metrics.storagepool.listView;
54+
3655
} else if (args.resource == 'vms') {
37-
metricsListView = cloudStack.sections.metrics.instances.listView;
3856
metricsLabel = _l('label.instances') + ' ' + metricsLabel;
57+
metricsListView = cloudStack.sections.metrics.instances.listView;
58+
metricsListView.advSearchFields = cloudStack.sections.instances.listView.advSearchFields;
59+
60+
if (context && !context.filterBy) {
61+
if (context.hasOwnProperty('hosts') && context.hosts[0]) {
62+
context.filterBy = 'hostid';
63+
context.id = context.hosts[0].id;
64+
}
65+
}
3966
} else if (args.resource == 'volumes') {
40-
metricsListView = cloudStack.sections.metrics.volumes.listView;
4167
metricsLabel = _l('label.volumes') + ' ' + metricsLabel;
68+
metricsListView = cloudStack.sections.metrics.volumes.listView;
69+
metricsListView.advSearchFields = cloudStack.sections.storage.sections.volumes.listView.advSearchFields;
70+
metricsListView.groupableColumns = false;
71+
72+
if (context && !context.filterBy) {
73+
if (context.hasOwnProperty('instances') && context.instances[0]) {
74+
context.filterBy = 'virtualmachineid';
75+
context.id = context.instances[0].id;
76+
}
77+
if (context.hasOwnProperty('primarystorages') && context.primarystorages[0]) {
78+
context.filterBy = 'storageid';
79+
context.id = context.primarystorages[0].id;
80+
}
81+
}
82+
}
83+
84+
if (context.metricsFilterData) {
85+
delete context.metricsFilterData;
86+
}
87+
88+
if (context.filterBy) {
89+
context.metricsFilterData = {
90+
key: context.filterBy,
91+
value: context.id
92+
};
4293
}
4394

4495
// list view refresh button
@@ -56,24 +107,40 @@
56107
}
57108
};
58109

59-
metricsListView.hideSearchBar = true;
110+
metricsListView.hideSearchBar = false;
60111
metricsListView.needsRefresh = true;
61112
metricsListView.noSplit = true;
62113
metricsListView.horizontalOverflow = true;
63114
metricsListView.groupableColumns = true;
64115

65-
if (args.resource == 'volumes') {
66-
metricsListView.groupableColumns = false;
67-
}
116+
if (args.resource != 'vms' && args.resource != 'volumes' && args.resource != 'zones') {
117+
metricsListView.advSearchFields = {
118+
name: {
119+
label: 'label.name'
120+
},
121+
zoneid: {
122+
label: 'label.zone',
123+
select: function(args) {
124+
$.ajax({
125+
url: createURL('listZones'),
126+
data: {
127+
listAll: true
128+
},
129+
success: function(json) {
130+
var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : [];
68131

69-
var metricsContext = cloudStack.context;
70-
if (metricsContext.metricsFilterData) {
71-
delete metricsContext.metricsFilterData;
72-
}
73-
if (args.filterBy) {
74-
metricsContext.metricsFilterData = {
75-
key: args.filterBy,
76-
value: args.id
132+
args.response.success({
133+
data: $.map(zones, function(zone) {
134+
return {
135+
id: zone.id,
136+
description: zone.name
137+
};
138+
})
139+
});
140+
}
141+
});
142+
}
143+
}
77144
};
78145
}
79146

@@ -84,7 +151,7 @@
84151
complete: function($newPanel) {
85152
$newPanel.listView({
86153
$browser: $browser,
87-
context: metricsContext,
154+
context: context,
88155
listView: metricsListView
89156
});
90157
// Make metrics tables horizontally scrollable
@@ -105,31 +172,33 @@
105172
}
106173
}
107174
$browser.cloudBrowser('removeLastPanel', {});
108-
var refreshedPanel = cloudStack.uiCustom.metricsView(args)();
175+
var refreshedPanel = cloudStack.uiCustom.metricsView(args)(ctxArgs);
109176
if (wasSorted && thClassName) {
110177
refreshedPanel.find('th.' + thClassName).filter(function() {
111178
return $(this).index() == thIndex;
112179
}).addClass('sorted').addClass(sortClassName);
113180
}
114181
});
115182

116-
var filterMetricView = metricsListView.browseBy;
117-
if (filterMetricView) {
183+
var browseBy = metricsListView.browseBy;
184+
if (browseBy) {
118185
$newPanel.bind('click', function(event) {
119186
event.stopPropagation();
120187
var $target = $(event.target);
121188
var id = $target.closest('tr').data('list-view-item-id');
122189
var jsonObj = $target.closest('tr').data('jsonObj');
123-
if (filterMetricView.filterKey && jsonObj) {
124-
if (jsonObj.hasOwnProperty(filterMetricView.filterKey)) {
125-
id = jsonObj[filterMetricView.filterKey];
190+
if (browseBy.filterKey && jsonObj) {
191+
if (jsonObj.hasOwnProperty(browseBy.filterKey)) {
192+
id = jsonObj[browseBy.filterKey];
126193
} else {
127194
return; // return if provided key is missing
128195
}
129196
}
130197
if (id && ($target.hasClass('first') || $target.parent().hasClass('first')) && ($target.is('td') || $target.parent().is('td'))) {
131-
filterMetricView.id = id;
132-
cloudStack.uiCustom.metricsView(filterMetricView)();
198+
context.id = id;
199+
context.filterBy = browseBy.filterBy;
200+
ctxArgs.context = context;
201+
cloudStack.uiCustom.metricsView({resource: browseBy.resource})(ctxArgs);
133202
}
134203
});
135204
}

0 commit comments

Comments
 (0)