fix(metrics): node chart race condition EE-5447 (#9252)

pull/9268/head
Dakota Walsh 2023-07-27 11:46:46 +12:00 committed by GitHub
parent fc89066846
commit 88de50649f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 197 additions and 188 deletions

View File

@ -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>

View File

@ -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() {

View File

@ -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>

View File

@ -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();
});
}
} }
} }

View File

@ -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;