2021-06-14 00:29:41 +00:00
|
|
|
import angular from 'angular';
|
|
|
|
import moment from 'moment';
|
|
|
|
import filesizeParser from 'filesize-parser';
|
|
|
|
import KubernetesResourceReservationHelper from 'Kubernetes/helpers/resourceReservationHelper';
|
|
|
|
import { PORTAINER_FADEOUT } from '@/constants';
|
2023-07-24 00:16:29 +00:00
|
|
|
import { getMetricsForNode } from '@/react/kubernetes/services/service.ts';
|
2021-06-14 00:29:41 +00:00
|
|
|
|
|
|
|
class KubernetesNodeStatsController {
|
|
|
|
/* @ngInject */
|
2023-07-24 00:16:29 +00:00
|
|
|
constructor($async, $state, $interval, $document, Notifications, KubernetesNodeService, ChartService) {
|
2021-06-14 00:29:41 +00:00
|
|
|
this.$async = $async;
|
|
|
|
this.$state = $state;
|
|
|
|
this.$interval = $interval;
|
|
|
|
this.$document = $document;
|
|
|
|
this.Notifications = Notifications;
|
|
|
|
this.KubernetesNodeService = KubernetesNodeService;
|
|
|
|
this.ChartService = ChartService;
|
|
|
|
|
|
|
|
this.onInit = this.onInit.bind(this);
|
2023-07-26 23:46:38 +00:00
|
|
|
this.initCharts = this.initCharts.bind(this);
|
2021-06-14 00:29:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
changeUpdateRepeater() {
|
|
|
|
var cpuChart = this.cpuChart;
|
|
|
|
var memoryChart = this.memoryChart;
|
|
|
|
|
|
|
|
this.stopRepeater();
|
|
|
|
this.setUpdateRepeater(cpuChart, memoryChart);
|
|
|
|
$('#refreshRateChange').show();
|
|
|
|
$('#refreshRateChange').fadeOut(PORTAINER_FADEOUT);
|
|
|
|
}
|
|
|
|
|
|
|
|
updateCPUChart() {
|
|
|
|
const label = moment(this.stats.read).format('HH:mm:ss');
|
|
|
|
this.ChartService.UpdateCPUChart(label, this.stats.CPUUsage, this.cpuChart);
|
|
|
|
}
|
|
|
|
|
|
|
|
updateMemoryChart() {
|
|
|
|
const label = moment(this.stats.read).format('HH:mm:ss');
|
|
|
|
this.ChartService.UpdateMemoryChart(label, this.stats.MemoryUsage, 0, this.memoryChart);
|
|
|
|
}
|
|
|
|
|
|
|
|
stopRepeater() {
|
|
|
|
var repeater = this.repeater;
|
|
|
|
if (angular.isDefined(repeater)) {
|
|
|
|
this.$interval.cancel(repeater);
|
|
|
|
this.repeater = undefined;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setUpdateRepeater() {
|
|
|
|
const refreshRate = this.state.refreshRate;
|
|
|
|
|
|
|
|
this.repeater = this.$interval(async () => {
|
|
|
|
try {
|
|
|
|
await this.getStats();
|
|
|
|
this.updateCPUChart();
|
|
|
|
this.updateMemoryChart();
|
|
|
|
} catch (error) {
|
|
|
|
this.stopRepeater();
|
|
|
|
this.Notifications.error('Failure', error);
|
|
|
|
}
|
|
|
|
}, refreshRate * 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
initCharts() {
|
2023-07-26 23:46:38 +00:00
|
|
|
const findCharts = setInterval(() => {
|
|
|
|
let cpuChartCtx = $('#cpuChart');
|
|
|
|
let memoryChartCtx = $('#memoryChart');
|
|
|
|
if (cpuChartCtx.length !== 0 && memoryChartCtx.length !== 0) {
|
|
|
|
const cpuChart = this.ChartService.CreateCPUChart(cpuChartCtx);
|
|
|
|
this.cpuChart = cpuChart;
|
|
|
|
const memoryChart = this.ChartService.CreateMemoryChart(memoryChartCtx);
|
|
|
|
this.memoryChart = memoryChart;
|
|
|
|
this.updateCPUChart();
|
|
|
|
this.updateMemoryChart();
|
|
|
|
this.setUpdateRepeater();
|
|
|
|
clearInterval(findCharts);
|
|
|
|
}
|
|
|
|
}, 200);
|
2021-06-14 00:29:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
getStats() {
|
|
|
|
return this.$async(async () => {
|
|
|
|
try {
|
2023-07-24 00:16:29 +00:00
|
|
|
const stats = await getMetricsForNode(this.$state.params.endpointId, this.state.transition.nodeName);
|
2021-06-14 00:29:41 +00:00
|
|
|
if (stats) {
|
|
|
|
const memory = filesizeParser(stats.usage.memory);
|
|
|
|
const cpu = KubernetesResourceReservationHelper.parseCPU(stats.usage.cpu);
|
|
|
|
this.stats = {
|
2023-07-26 23:46:38 +00:00
|
|
|
read: stats.metadata.creationTimestamp,
|
2021-06-14 00:29:41 +00:00
|
|
|
MemoryUsage: memory,
|
|
|
|
CPUUsage: (cpu / this.nodeCPU) * 100,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
this.Notifications.error('Failure', err, 'Unable to retrieve node stats');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
$onDestroy() {
|
|
|
|
this.stopRepeater();
|
|
|
|
}
|
|
|
|
|
|
|
|
async onInit() {
|
|
|
|
this.state = {
|
|
|
|
autoRefresh: false,
|
|
|
|
refreshRate: '30',
|
|
|
|
viewReady: false,
|
|
|
|
transition: {
|
|
|
|
nodeName: this.$transition$.params().name,
|
|
|
|
},
|
|
|
|
getMetrics: true,
|
|
|
|
};
|
|
|
|
|
|
|
|
try {
|
2023-07-24 00:16:29 +00:00
|
|
|
const nodeMetrics = await getMetricsForNode(this.$state.params.endpointId, this.state.transition.nodeName);
|
2021-06-14 00:29:41 +00:00
|
|
|
|
|
|
|
if (nodeMetrics) {
|
|
|
|
const node = await this.KubernetesNodeService.get(this.state.transition.nodeName);
|
|
|
|
this.nodeCPU = node.CPU || 1;
|
|
|
|
|
|
|
|
await this.getStats();
|
|
|
|
} else {
|
|
|
|
this.state.getMetrics = false;
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
this.state.getMetrics = false;
|
|
|
|
this.Notifications.error('Failure', err, 'Unable to retrieve node stats');
|
|
|
|
} finally {
|
|
|
|
this.state.viewReady = true;
|
2023-07-26 23:46:38 +00:00
|
|
|
if (this.state.getMetrics) {
|
|
|
|
this.$document.ready(() => {
|
|
|
|
this.initCharts();
|
|
|
|
});
|
|
|
|
}
|
2021-06-14 00:29:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$onInit() {
|
|
|
|
return this.$async(this.onInit);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default KubernetesNodeStatsController;
|
|
|
|
angular.module('portainer.kubernetes').controller('KubernetesNodeStatsController', KubernetesNodeStatsController);
|