mirror of https://github.com/portainer/portainer
fix(metrics): node chart race condition EE-5447 (#9249)
parent
ca617e2ac9
commit
400d95c1a5
|
@ -26,15 +26,14 @@
|
||||||
|
|
||||||
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
||||||
|
|
||||||
<div ng-if="ctrl.state.viewReady">
|
<information-panel ng-if="!ctrl.state.getMetrics" title-text="Unable to retrieve container metrics">
|
||||||
<information-panel ng-if="!ctrl.state.getMetrics" title-text="Unable to retrieve container metrics">
|
|
||||||
<span class="small text-warning vertical-center">
|
<span class="small text-warning vertical-center">
|
||||||
<pr-icon icon="'alert-triangle'" mode="'warning'"></pr-icon>
|
<pr-icon icon="'alert-triangle'" mode="'warning'"></pr-icon>
|
||||||
Portainer was unable to retrieve any metrics associated to that container. Please contact your administrator to ensure that the Kubernetes metrics feature is properly
|
Portainer was unable to retrieve any metrics associated to that container. Please contact your administrator to ensure that the Kubernetes metrics feature is properly
|
||||||
configured.
|
configured.
|
||||||
</span>
|
</span>
|
||||||
</information-panel>
|
</information-panel>
|
||||||
<div class="row" ng-if="ctrl.state.getMetrics">
|
<div class="row" ng-if="ctrl.state.getMetrics">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<rd-widget>
|
<rd-widget>
|
||||||
<div class="toolBar px-5 pt-5">
|
<div class="toolBar px-5 pt-5">
|
||||||
|
@ -79,9 +78,9 @@
|
||||||
</rd-widget-body>
|
</rd-widget-body>
|
||||||
</rd-widget>
|
</rd-widget>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" ng-if="ctrl.state.getMetrics">
|
<div class="row" ng-if="ctrl.state.getMetrics">
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||||
<rd-widget>
|
<rd-widget>
|
||||||
<div class="toolBar px-5 pt-5">
|
<div class="toolBar px-5 pt-5">
|
||||||
|
@ -116,5 +115,4 @@
|
||||||
</rd-widget-body>
|
</rd-widget-body>
|
||||||
</rd-widget>
|
</rd-widget>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -19,6 +19,7 @@ class KubernetesApplicationStatsController {
|
||||||
this.ChartService = ChartService;
|
this.ChartService = ChartService;
|
||||||
|
|
||||||
this.onInit = this.onInit.bind(this);
|
this.onInit = this.onInit.bind(this);
|
||||||
|
this.initCharts = this.initCharts.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeUpdateRepeater() {
|
changeUpdateRepeater() {
|
||||||
|
@ -68,17 +69,26 @@ class KubernetesApplicationStatsController {
|
||||||
}
|
}
|
||||||
|
|
||||||
initCharts() {
|
initCharts() {
|
||||||
const cpuChartCtx = $('#cpuChart');
|
let i = 0;
|
||||||
|
const findCharts = setInterval(() => {
|
||||||
|
let cpuChartCtx = $('#cpuChart');
|
||||||
|
let memoryChartCtx = $('#memoryChart');
|
||||||
|
if (cpuChartCtx.length !== 0 && memoryChartCtx.length !== 0) {
|
||||||
const cpuChart = this.ChartService.CreateCPUChart(cpuChartCtx);
|
const cpuChart = this.ChartService.CreateCPUChart(cpuChartCtx);
|
||||||
this.cpuChart = cpuChart;
|
this.cpuChart = cpuChart;
|
||||||
|
|
||||||
const memoryChartCtx = $('#memoryChart');
|
|
||||||
const memoryChart = this.ChartService.CreateMemoryChart(memoryChartCtx);
|
const memoryChart = this.ChartService.CreateMemoryChart(memoryChartCtx);
|
||||||
this.memoryChart = memoryChart;
|
this.memoryChart = memoryChart;
|
||||||
|
|
||||||
this.updateCPUChart();
|
this.updateCPUChart();
|
||||||
this.updateMemoryChart();
|
this.updateMemoryChart();
|
||||||
this.setUpdateRepeater();
|
this.setUpdateRepeater();
|
||||||
|
clearInterval(findCharts);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
if (i >= 10) {
|
||||||
|
clearInterval(findCharts);
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
getStats() {
|
getStats() {
|
||||||
|
|
|
@ -15,14 +15,13 @@
|
||||||
|
|
||||||
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
||||||
|
|
||||||
<div ng-if="ctrl.state.viewReady">
|
<information-panel ng-if="!ctrl.state.getMetrics" title-text="Unable to retrieve node metrics">
|
||||||
<information-panel ng-if="!ctrl.state.getMetrics" title-text="Unable to retrieve node metrics">
|
|
||||||
<span class="small text-muted vertical-center">
|
<span class="small text-muted vertical-center">
|
||||||
<pr-icon icon="'alert-triangle'" mode="'primary'"></pr-icon>
|
<pr-icon icon="'alert-triangle'" mode="'primary'"></pr-icon>
|
||||||
Portainer was unable to retrieve any metrics associated to that node. Please contact your administrator to ensure that the Kubernetes metrics feature is properly configured.
|
Portainer was unable to retrieve any metrics associated to that node. Please contact your administrator to ensure that the Kubernetes metrics feature is properly configured.
|
||||||
</span>
|
</span>
|
||||||
</information-panel>
|
</information-panel>
|
||||||
<div class="row" ng-if="ctrl.state.getMetrics">
|
<div class="row" ng-if="ctrl.state.getMetrics">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<rd-widget>
|
<rd-widget>
|
||||||
<div class="toolBar px-5 pt-5">
|
<div class="toolBar px-5 pt-5">
|
||||||
|
@ -59,9 +58,9 @@
|
||||||
</rd-widget-body>
|
</rd-widget-body>
|
||||||
</rd-widget>
|
</rd-widget>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" ng-show="ctrl.state.getMetrics">
|
<div class="row" ng-show="ctrl.state.getMetrics">
|
||||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||||
<rd-widget>
|
<rd-widget>
|
||||||
<div class="toolBar px-5 pt-5">
|
<div class="toolBar px-5 pt-5">
|
||||||
|
@ -96,5 +95,4 @@
|
||||||
</rd-widget-body>
|
</rd-widget-body>
|
||||||
</rd-widget>
|
</rd-widget>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,6 +17,7 @@ class KubernetesNodeStatsController {
|
||||||
this.ChartService = ChartService;
|
this.ChartService = ChartService;
|
||||||
|
|
||||||
this.onInit = this.onInit.bind(this);
|
this.onInit = this.onInit.bind(this);
|
||||||
|
this.initCharts = this.initCharts.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeUpdateRepeater() {
|
changeUpdateRepeater() {
|
||||||
|
@ -63,17 +64,20 @@ class KubernetesNodeStatsController {
|
||||||
}
|
}
|
||||||
|
|
||||||
initCharts() {
|
initCharts() {
|
||||||
const cpuChartCtx = $('#cpuChart');
|
const findCharts = setInterval(() => {
|
||||||
|
let cpuChartCtx = $('#cpuChart');
|
||||||
|
let memoryChartCtx = $('#memoryChart');
|
||||||
|
if (cpuChartCtx.length !== 0 && memoryChartCtx.length !== 0) {
|
||||||
const cpuChart = this.ChartService.CreateCPUChart(cpuChartCtx);
|
const cpuChart = this.ChartService.CreateCPUChart(cpuChartCtx);
|
||||||
this.cpuChart = cpuChart;
|
this.cpuChart = cpuChart;
|
||||||
|
|
||||||
const memoryChartCtx = $('#memoryChart');
|
|
||||||
const memoryChart = this.ChartService.CreateMemoryChart(memoryChartCtx);
|
const memoryChart = this.ChartService.CreateMemoryChart(memoryChartCtx);
|
||||||
this.memoryChart = memoryChart;
|
this.memoryChart = memoryChart;
|
||||||
|
|
||||||
this.updateCPUChart();
|
this.updateCPUChart();
|
||||||
this.updateMemoryChart();
|
this.updateMemoryChart();
|
||||||
this.setUpdateRepeater();
|
this.setUpdateRepeater();
|
||||||
|
clearInterval(findCharts);
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
getStats() {
|
getStats() {
|
||||||
|
@ -84,7 +88,7 @@ class KubernetesNodeStatsController {
|
||||||
const memory = filesizeParser(stats.usage.memory);
|
const memory = filesizeParser(stats.usage.memory);
|
||||||
const cpu = KubernetesResourceReservationHelper.parseCPU(stats.usage.cpu);
|
const cpu = KubernetesResourceReservationHelper.parseCPU(stats.usage.cpu);
|
||||||
this.stats = {
|
this.stats = {
|
||||||
read: stats.creationTimestamp,
|
read: stats.metadata.creationTimestamp,
|
||||||
MemoryUsage: memory,
|
MemoryUsage: memory,
|
||||||
CPUUsage: (cpu / this.nodeCPU) * 100,
|
CPUUsage: (cpu / this.nodeCPU) * 100,
|
||||||
};
|
};
|
||||||
|
@ -118,12 +122,6 @@ class KubernetesNodeStatsController {
|
||||||
this.nodeCPU = node.CPU || 1;
|
this.nodeCPU = node.CPU || 1;
|
||||||
|
|
||||||
await this.getStats();
|
await this.getStats();
|
||||||
|
|
||||||
if (this.state.getMetrics) {
|
|
||||||
this.$document.ready(() => {
|
|
||||||
this.initCharts();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.state.getMetrics = false;
|
this.state.getMetrics = false;
|
||||||
}
|
}
|
||||||
|
@ -132,6 +130,11 @@ class KubernetesNodeStatsController {
|
||||||
this.Notifications.error('Failure', err, 'Unable to retrieve node stats');
|
this.Notifications.error('Failure', err, 'Unable to retrieve node stats');
|
||||||
} finally {
|
} finally {
|
||||||
this.state.viewReady = true;
|
this.state.viewReady = true;
|
||||||
|
if (this.state.getMetrics) {
|
||||||
|
this.$document.ready(() => {
|
||||||
|
this.initCharts();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ class KubernetesConfigureController {
|
||||||
await getMetricsForAllNodes(this.endpoint.Id);
|
await getMetricsForAllNodes(this.endpoint.Id);
|
||||||
this.state.metrics.isServerRunning = true;
|
this.state.metrics.isServerRunning = true;
|
||||||
this.state.metrics.pending = false;
|
this.state.metrics.pending = false;
|
||||||
this.state.metrics.userClick = false;
|
this.state.metrics.userClick = true;
|
||||||
this.formValues.UseServerMetrics = true;
|
this.formValues.UseServerMetrics = true;
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
this.state.metrics.isServerRunning = false;
|
this.state.metrics.isServerRunning = false;
|
||||||
|
|
Loading…
Reference in New Issue