mirror of https://github.com/portainer/portainer
feat(container-stats): display cache in memory usage chart (#2383)
parent
fe6ca042f3
commit
07c1e1bc3e
|
@ -65,6 +65,7 @@ function ContainerViewModel(data) {
|
||||||
function ContainerStatsViewModel(data) {
|
function ContainerStatsViewModel(data) {
|
||||||
this.Date = data.read;
|
this.Date = data.read;
|
||||||
this.MemoryUsage = data.memory_stats.usage - data.memory_stats.stats.cache;
|
this.MemoryUsage = data.memory_stats.usage - data.memory_stats.stats.cache;
|
||||||
|
this.MemoryCache = data.memory_stats.stats.cache;
|
||||||
this.PreviousCPUTotalUsage = data.precpu_stats.cpu_usage.total_usage;
|
this.PreviousCPUTotalUsage = data.precpu_stats.cpu_usage.total_usage;
|
||||||
this.PreviousCPUSystemUsage = data.precpu_stats.system_cpu_usage;
|
this.PreviousCPUSystemUsage = data.precpu_stats.system_cpu_usage;
|
||||||
this.CurrentCPUTotalUsage = data.cpu_stats.cpu_usage.total_usage;
|
this.CurrentCPUTotalUsage = data.cpu_stats.cpu_usage.total_usage;
|
||||||
|
|
|
@ -31,9 +31,8 @@ function ($q, $scope, $transition$, $document, $interval, ContainerService, Char
|
||||||
|
|
||||||
function updateMemoryChart(stats, chart) {
|
function updateMemoryChart(stats, chart) {
|
||||||
var label = moment(stats.Date).format('HH:mm:ss');
|
var label = moment(stats.Date).format('HH:mm:ss');
|
||||||
var value = stats.MemoryUsage;
|
|
||||||
|
|
||||||
ChartService.UpdateMemoryChart(label, value, chart);
|
ChartService.UpdateMemoryChart(label, stats.MemoryUsage, stats.MemoryCache, chart);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCPUChart(stats, chart) {
|
function updateCPUChart(stats, chart) {
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
angular.module('portainer.app')
|
angular.module('portainer.app')
|
||||||
.factory('ChartService', [function ChartService() {
|
.factory('ChartService', [function ChartService() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// Max. number of items to display on a chart
|
// Max. number of items to display on a chart
|
||||||
var CHART_LIMIT = 600;
|
var CHART_LIMIT = 600;
|
||||||
|
|
||||||
var service = {};
|
var service = {};
|
||||||
|
|
||||||
function defaultChartOptions(pos, tooltipCallback, scalesCallback) {
|
function defaultChartOptions(pos, tooltipCallback, scalesCallback, isStacked) {
|
||||||
return {
|
return {
|
||||||
animation: { duration: 0 },
|
animation: { duration: 0 },
|
||||||
responsiveAnimationDuration: 0,
|
responsiveAnimationDuration: 0,
|
||||||
responsive: true,
|
responsive: true,
|
||||||
|
@ -17,7 +17,7 @@ angular.module('portainer.app')
|
||||||
intersect: false,
|
intersect: false,
|
||||||
position: pos,
|
position: pos,
|
||||||
callbacks: {
|
callbacks: {
|
||||||
label: function(tooltipItem, data) {
|
label: function (tooltipItem, data) {
|
||||||
var datasetLabel = data.datasets[tooltipItem.datasetIndex].label;
|
var datasetLabel = data.datasets[tooltipItem.datasetIndex].label;
|
||||||
return tooltipCallback(datasetLabel, tooltipItem.yLabel);
|
return tooltipCallback(datasetLabel, tooltipItem.yLabel);
|
||||||
}
|
}
|
||||||
|
@ -26,142 +26,188 @@ angular.module('portainer.app')
|
||||||
hover: { animationDuration: 0 },
|
hover: { animationDuration: 0 },
|
||||||
scales: {
|
scales: {
|
||||||
yAxes: [{
|
yAxes: [{
|
||||||
ticks: {
|
stacked: isStacked,
|
||||||
beginAtZero: true,
|
ticks: {
|
||||||
callback: scalesCallback
|
beginAtZero: true,
|
||||||
}
|
callback: scalesCallback
|
||||||
|
}
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
function CreateChart (context, label, tooltipCallback, scalesCallback) {
|
|
||||||
return new Chart(context, {
|
|
||||||
type: 'line',
|
|
||||||
data: {
|
|
||||||
labels: [],
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: label,
|
|
||||||
data: [],
|
|
||||||
fill: true,
|
|
||||||
backgroundColor: 'rgba(151,187,205,0.4)',
|
|
||||||
borderColor: 'rgba(151,187,205,0.6)',
|
|
||||||
pointBackgroundColor: 'rgba(151,187,205,1)',
|
|
||||||
pointBorderColor: 'rgba(151,187,205,1)',
|
|
||||||
pointRadius: 2,
|
|
||||||
borderWidth: 2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
options: defaultChartOptions('nearest', tooltipCallback, scalesCallback)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
service.CreateCPUChart = function(context) {
|
|
||||||
return CreateChart(context, 'CPU', percentageBasedTooltipLabel, percentageBasedAxisLabel);
|
|
||||||
};
|
|
||||||
|
|
||||||
service.CreateMemoryChart = function(context) {
|
|
||||||
return CreateChart(context, 'Memory', byteBasedTooltipLabel, byteBasedAxisLabel);
|
|
||||||
};
|
|
||||||
|
|
||||||
service.CreateNetworkChart = function(context) {
|
|
||||||
return new Chart(context, {
|
|
||||||
type: 'line',
|
|
||||||
data: {
|
|
||||||
labels: [],
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: 'RX on eth0',
|
|
||||||
data: [],
|
|
||||||
fill: false,
|
|
||||||
backgroundColor: 'rgba(151,187,205,0.4)',
|
|
||||||
borderColor: 'rgba(151,187,205,0.6)',
|
|
||||||
pointBackgroundColor: 'rgba(151,187,205,1)',
|
|
||||||
pointBorderColor: 'rgba(151,187,205,1)',
|
|
||||||
pointRadius: 2,
|
|
||||||
borderWidth: 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'TX on eth0',
|
|
||||||
data: [],
|
|
||||||
fill: false,
|
|
||||||
backgroundColor: 'rgba(255,180,174,0.4)',
|
|
||||||
borderColor: 'rgba(255,180,174,0.6)',
|
|
||||||
pointBackgroundColor: 'rgba(255,180,174,1)',
|
|
||||||
pointBorderColor: 'rgba(255,180,174,1)',
|
|
||||||
pointRadius: 2,
|
|
||||||
borderWidth: 2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
options: defaultChartOptions('average', byteBasedTooltipLabel, byteBasedAxisLabel)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function UpdateChart(label, value, chart) {
|
|
||||||
chart.data.labels.push(label);
|
|
||||||
chart.data.datasets[0].data.push(value);
|
|
||||||
|
|
||||||
if (chart.data.datasets[0].data.length > CHART_LIMIT) {
|
|
||||||
chart.data.labels.pop();
|
|
||||||
chart.data.datasets[0].data.pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chart.update(0);
|
function CreateChart(context, label, tooltipCallback, scalesCallback) {
|
||||||
}
|
return new Chart(context, {
|
||||||
|
type: 'line',
|
||||||
service.UpdateMemoryChart = UpdateChart;
|
data: {
|
||||||
service.UpdateCPUChart = UpdateChart;
|
labels: [],
|
||||||
|
datasets: [
|
||||||
service.UpdateNetworkChart = function(label, rx, tx, chart) {
|
{
|
||||||
chart.data.labels.push(label);
|
label: label,
|
||||||
chart.data.datasets[0].data.push(rx);
|
data: [],
|
||||||
chart.data.datasets[1].data.push(tx);
|
fill: true,
|
||||||
|
backgroundColor: 'rgba(151,187,205,0.4)',
|
||||||
if (chart.data.datasets[0].data.length > CHART_LIMIT) {
|
borderColor: 'rgba(151,187,205,0.6)',
|
||||||
chart.data.labels.pop();
|
pointBackgroundColor: 'rgba(151,187,205,1)',
|
||||||
chart.data.datasets[0].data.pop();
|
pointBorderColor: 'rgba(151,187,205,1)',
|
||||||
chart.data.datasets[1].data.pop();
|
pointRadius: 2,
|
||||||
|
borderWidth: 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: defaultChartOptions('nearest', tooltipCallback, scalesCallback)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
chart.update(0);
|
function CreateMemoryChart(context, tooltipCallback, scalesCallback) {
|
||||||
};
|
return new Chart(context, {
|
||||||
|
type: 'line',
|
||||||
function byteBasedTooltipLabel(label, value) {
|
data: {
|
||||||
var processedValue = 0;
|
labels: [],
|
||||||
if (value > 5) {
|
datasets: [
|
||||||
processedValue = filesize(value, {base: 10, round: 1});
|
{
|
||||||
} else {
|
label: 'Memory',
|
||||||
processedValue = value.toFixed(1) + 'B';
|
data: [],
|
||||||
|
fill: true,
|
||||||
|
backgroundColor: 'rgba(151,187,205,0.4)',
|
||||||
|
borderColor: 'rgba(151,187,205,0.6)',
|
||||||
|
pointBackgroundColor: 'rgba(151,187,205,1)',
|
||||||
|
pointBorderColor: 'rgba(151,187,205,1)',
|
||||||
|
pointRadius: 2,
|
||||||
|
borderWidth: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Cache',
|
||||||
|
data: [],
|
||||||
|
fill: true,
|
||||||
|
backgroundColor: 'rgba(255,180,174,0.4)',
|
||||||
|
borderColor: 'rgba(255,180,174,0.6)',
|
||||||
|
pointBackgroundColor: 'rgba(255,180,174,1)',
|
||||||
|
pointBorderColor: 'rgba(255,180,174,1)',
|
||||||
|
pointRadius: 2,
|
||||||
|
borderWidth: 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: defaultChartOptions('nearest', tooltipCallback, scalesCallback, true)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return label + ': ' + processedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
function byteBasedAxisLabel(value) {
|
service.CreateCPUChart = function (context) {
|
||||||
if (value > 5) {
|
return CreateChart(context, 'CPU', percentageBasedTooltipLabel, percentageBasedAxisLabel);
|
||||||
return filesize(value, {base: 10, round: 1});
|
};
|
||||||
|
|
||||||
|
service.CreateMemoryChart = function (context) {
|
||||||
|
return CreateMemoryChart(context, byteBasedTooltipLabel, byteBasedAxisLabel);
|
||||||
|
};
|
||||||
|
|
||||||
|
service.CreateNetworkChart = function (context) {
|
||||||
|
return new Chart(context, {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: [],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: 'RX on eth0',
|
||||||
|
data: [],
|
||||||
|
fill: false,
|
||||||
|
backgroundColor: 'rgba(151,187,205,0.4)',
|
||||||
|
borderColor: 'rgba(151,187,205,0.6)',
|
||||||
|
pointBackgroundColor: 'rgba(151,187,205,1)',
|
||||||
|
pointBorderColor: 'rgba(151,187,205,1)',
|
||||||
|
pointRadius: 2,
|
||||||
|
borderWidth: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'TX on eth0',
|
||||||
|
data: [],
|
||||||
|
fill: false,
|
||||||
|
backgroundColor: 'rgba(255,180,174,0.4)',
|
||||||
|
borderColor: 'rgba(255,180,174,0.6)',
|
||||||
|
pointBackgroundColor: 'rgba(255,180,174,1)',
|
||||||
|
pointBorderColor: 'rgba(255,180,174,1)',
|
||||||
|
pointRadius: 2,
|
||||||
|
borderWidth: 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: defaultChartOptions('average', byteBasedTooltipLabel, byteBasedAxisLabel)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function UpdateChart(label, value, chart) {
|
||||||
|
chart.data.labels.push(label);
|
||||||
|
chart.data.datasets[0].data.push(value);
|
||||||
|
|
||||||
|
if (chart.data.datasets[0].data.length > CHART_LIMIT) {
|
||||||
|
chart.data.labels.pop();
|
||||||
|
chart.data.datasets[0].data.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
chart.update(0);
|
||||||
}
|
}
|
||||||
return value.toFixed(1) + 'B';
|
|
||||||
}
|
|
||||||
|
|
||||||
function percentageBasedAxisLabel(value) {
|
service.UpdateMemoryChart = function UpdateChart(label, memoryValue, cacheValue, chart) {
|
||||||
if (value > 1) {
|
chart.data.labels.push(label);
|
||||||
return Math.round(value) + '%';
|
chart.data.datasets[0].data.push(memoryValue);
|
||||||
|
chart.data.datasets[1].data.push(cacheValue);
|
||||||
|
|
||||||
|
if (chart.data.datasets[0].data.length > CHART_LIMIT) {
|
||||||
|
chart.data.labels.pop();
|
||||||
|
chart.data.datasets[0].data.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
chart.update(0);
|
||||||
|
};
|
||||||
|
service.UpdateCPUChart = UpdateChart;
|
||||||
|
|
||||||
|
service.UpdateNetworkChart = function (label, rx, tx, chart) {
|
||||||
|
chart.data.labels.push(label);
|
||||||
|
chart.data.datasets[0].data.push(rx);
|
||||||
|
chart.data.datasets[1].data.push(tx);
|
||||||
|
|
||||||
|
if (chart.data.datasets[0].data.length > CHART_LIMIT) {
|
||||||
|
chart.data.labels.pop();
|
||||||
|
chart.data.datasets[0].data.pop();
|
||||||
|
chart.data.datasets[1].data.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
chart.update(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
function byteBasedTooltipLabel(label, value) {
|
||||||
|
var processedValue = 0;
|
||||||
|
if (value > 5) {
|
||||||
|
processedValue = filesize(value, { base: 10, round: 1 });
|
||||||
|
} else {
|
||||||
|
processedValue = value.toFixed(1) + 'B';
|
||||||
|
}
|
||||||
|
return label + ': ' + processedValue;
|
||||||
}
|
}
|
||||||
return value.toFixed(1) + '%';
|
|
||||||
}
|
|
||||||
|
|
||||||
function percentageBasedTooltipLabel(label, value) {
|
function byteBasedAxisLabel(value) {
|
||||||
var processedValue = 0;
|
if (value > 5) {
|
||||||
if (value > 1) {
|
return filesize(value, { base: 10, round: 1 });
|
||||||
processedValue = Math.round(value);
|
}
|
||||||
} else {
|
return value.toFixed(1) + 'B';
|
||||||
processedValue = value.toFixed(1);
|
|
||||||
}
|
}
|
||||||
return label + ': ' + processedValue + '%';
|
|
||||||
}
|
|
||||||
|
|
||||||
return service;
|
function percentageBasedAxisLabel(value) {
|
||||||
}]);
|
if (value > 1) {
|
||||||
|
return Math.round(value) + '%';
|
||||||
|
}
|
||||||
|
return value.toFixed(1) + '%';
|
||||||
|
}
|
||||||
|
|
||||||
|
function percentageBasedTooltipLabel(label, value) {
|
||||||
|
var processedValue = 0;
|
||||||
|
if (value > 1) {
|
||||||
|
processedValue = Math.round(value);
|
||||||
|
} else {
|
||||||
|
processedValue = value.toFixed(1);
|
||||||
|
}
|
||||||
|
return label + ': ' + processedValue + '%';
|
||||||
|
}
|
||||||
|
|
||||||
|
return service;
|
||||||
|
}]);
|
||||||
|
|
Loading…
Reference in New Issue