add load averages
This commit is contained in:
170
status.html
170
status.html
@@ -1,3 +1,4 @@
|
|||||||
|
<!-- status.html -->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
@@ -184,6 +185,20 @@
|
|||||||
<h2
|
<h2
|
||||||
class="text-3xl minecraft-font mb-8 text-center bg-gradient-to-r from-teal-400 to-blue-500 bg-clip-text text-transparent">
|
class="text-3xl minecraft-font mb-8 text-center bg-gradient-to-r from-teal-400 to-blue-500 bg-clip-text text-transparent">
|
||||||
Host System Metrics</h2>
|
Host System Metrics</h2>
|
||||||
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
|
||||||
|
<div class="feature-card tilt-card">
|
||||||
|
<h3 class="text-xl minecraft-font mb-3 text-teal-400">Load Avg (1m)</h3>
|
||||||
|
<p class="text-lg opacity-90" id="host-load1">0</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card tilt-card">
|
||||||
|
<h3 class="text-xl minecraft-font mb-3 text-teal-400">Load Avg (5m)</h3>
|
||||||
|
<p class="text-lg opacity-90" id="host-load5">0</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card tilt-card">
|
||||||
|
<h3 class="text-xl minecraft-font mb-3 text-teal-400">Load Avg (15m)</h3>
|
||||||
|
<p class="text-lg opacity-90" id="host-load15">0</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-xl minecraft-font mb-6 text-teal-400 text-center">CPU Usage</h3>
|
<h3 class="text-xl minecraft-font mb-6 text-teal-400 text-center">CPU Usage</h3>
|
||||||
@@ -201,6 +216,10 @@
|
|||||||
<h3 class="text-xl minecraft-font mb-6 text-teal-400 text-center">Disk I/O</h3>
|
<h3 class="text-xl minecraft-font mb-6 text-teal-400 text-center">Disk I/O</h3>
|
||||||
<canvas id="disk-chart" class="mb-8"></canvas>
|
<canvas id="disk-chart" class="mb-8"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="text-xl minecraft-font mb-6 text-teal-400 text-center">Load Averages</h3>
|
||||||
|
<canvas id="load-chart" class="mb-8"></canvas>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -209,7 +228,7 @@
|
|||||||
class="text-3xl minecraft-font mb-8 text-center bg-gradient-to-r from-teal-400 to-blue-500 bg-clip-text text-transparent">
|
class="text-3xl minecraft-font mb-8 text-center bg-gradient-to-r from-teal-400 to-blue-500 bg-clip-text text-transparent">
|
||||||
Jump Node Stats</h2>
|
Jump Node Stats</h2>
|
||||||
<div id="jump-no-data" class="no-data" style="display: none;">No Jump Node data available</div>
|
<div id="jump-no-data" class="no-data" style="display: none;">No Jump Node data available</div>
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 mb-6">
|
||||||
<div class="feature-card tilt-card">
|
<div class="feature-card tilt-card">
|
||||||
<h3 class="text-xl minecraft-font mb-3 text-teal-400">Uptime</h3>
|
<h3 class="text-xl minecraft-font mb-3 text-teal-400">Uptime</h3>
|
||||||
<p class="text-lg opacity-90" id="jump-uptime">0 days</p>
|
<p class="text-lg opacity-90" id="jump-uptime">0 days</p>
|
||||||
@@ -227,6 +246,20 @@
|
|||||||
<p class="text-lg opacity-90" id="jump-free-disk">0 GB</p>
|
<p class="text-lg opacity-90" id="jump-free-disk">0 GB</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex justify-center gap-6 mb-8">
|
||||||
|
<div class="feature-card tilt-card">
|
||||||
|
<h3 class="text-xl minecraft-font mb-3 text-teal-400">Load Avg (1m)</h3>
|
||||||
|
<p class="text-lg opacity-90" id="jump-load1">0</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card tilt-card">
|
||||||
|
<h3 class="text-xl minecraft-font mb-3 text-teal-400">Load Avg (5m)</h3>
|
||||||
|
<p class="text-lg opacity-90" id="jump-load5">0</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card tilt-card">
|
||||||
|
<h3 class="text-xl minecraft-font mb-3 text-teal-400">Load Avg (15m)</h3>
|
||||||
|
<p class="text-lg opacity-90" id="jump-load15">0</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-xl minecraft-font mb-6 text-teal-400 text-center">CPU Usage</h3>
|
<h3 class="text-xl minecraft-font mb-6 text-teal-400 text-center">CPU Usage</h3>
|
||||||
@@ -240,6 +273,10 @@
|
|||||||
<h3 class="text-xl minecraft-font mb-6 text-teal-400 text-center">Disk I/O</h3>
|
<h3 class="text-xl minecraft-font mb-6 text-teal-400 text-center">Disk I/O</h3>
|
||||||
<canvas id="jump-disk-chart" class="mb-8"></canvas>
|
<canvas id="jump-disk-chart" class="mb-8"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="text-xl minecraft-font mb-6 text-teal-400 text-center">Load Averages</h3>
|
||||||
|
<canvas id="jump-load-chart" class="mb-8"></canvas>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
@@ -254,13 +291,16 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
const ws = new WebSocket('wss://' + window.location.host);
|
const ws = new WebSocket('wss://' + window.location.host);
|
||||||
const charts = {};
|
const socket = ws
|
||||||
|
let charts = {};
|
||||||
let dockerNetHistory = [];
|
let dockerNetHistory = [];
|
||||||
let netHistory = [];
|
let netHistory = [];
|
||||||
let diskHistory = [];
|
let diskHistory = [];
|
||||||
let jumpNetHistory = [];
|
let jumpNetHistory = [];
|
||||||
let jumpDiskHistory = [];
|
let jumpDiskHistory = [];
|
||||||
const MAX_POINTS = 10;
|
let hostLoadHistory = [];
|
||||||
|
let jumpLoadHistory = [];
|
||||||
|
const MAX_POINTS = 30; // Match to points in API query
|
||||||
const SMOOTHING_WINDOW = 3;
|
const SMOOTHING_WINDOW = 3;
|
||||||
|
|
||||||
// Helper to smooth data
|
// Helper to smooth data
|
||||||
@@ -300,9 +340,11 @@
|
|||||||
ram: document.getElementById('ram-chart'),
|
ram: document.getElementById('ram-chart'),
|
||||||
net: document.getElementById('net-chart'),
|
net: document.getElementById('net-chart'),
|
||||||
disk: document.getElementById('disk-chart'),
|
disk: document.getElementById('disk-chart'),
|
||||||
|
load: document.getElementById('load-chart'),
|
||||||
jumpCpu: document.getElementById('jump-cpu-chart'),
|
jumpCpu: document.getElementById('jump-cpu-chart'),
|
||||||
jumpNet: document.getElementById('jump-net-chart'),
|
jumpNet: document.getElementById('jump-net-chart'),
|
||||||
jumpDisk: document.getElementById('jump-disk-chart')
|
jumpDisk: document.getElementById('jump-disk-chart'),
|
||||||
|
jumpLoad: document.getElementById('jump-load-chart')
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const [key, canvas] of Object.entries(canvases)) {
|
for (const [key, canvas] of Object.entries(canvases)) {
|
||||||
@@ -440,6 +482,28 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
charts.load = new Chart(canvases.load.getContext('2d'), {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: [],
|
||||||
|
datasets: [
|
||||||
|
{ label: '1m', data: [], borderColor: '#38bdf8', borderWidth: 2, fill: false, tension: 0 },
|
||||||
|
{ label: '5m', data: [], borderColor: '#fb7185', borderWidth: 2, fill: false, tension: 0 },
|
||||||
|
{ label: '15m', data: [], borderColor: '#10b981', borderWidth: 2, fill: false, tension: 0 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
...commonOptions,
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
...commonOptions.scales.y,
|
||||||
|
title: { display: true, text: 'Load', color: '#e5e7eb' }
|
||||||
|
},
|
||||||
|
x: commonOptions.scales.x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
charts.jumpCpu = new Chart(canvases.jumpCpu.getContext('2d'), {
|
charts.jumpCpu = new Chart(canvases.jumpCpu.getContext('2d'), {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: {
|
data: {
|
||||||
@@ -508,6 +572,28 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
charts.jumpLoad = new Chart(canvases.jumpLoad.getContext('2d'), {
|
||||||
|
type: 'line',
|
||||||
|
data: {
|
||||||
|
labels: [],
|
||||||
|
datasets: [
|
||||||
|
{ label: '1m', data: [], borderColor: '#38bdf8', borderWidth: 2, fill: false, tension: 0 },
|
||||||
|
{ label: '5m', data: [], borderColor: '#fb7185', borderWidth: 2, fill: false, tension: 0 },
|
||||||
|
{ label: '15m', data: [], borderColor: '#10b981', borderWidth: 2, fill: false, tension: 0 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
...commonOptions,
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
...commonOptions.scales.y,
|
||||||
|
title: { display: true, text: 'Load', color: '#e5e7eb' }
|
||||||
|
},
|
||||||
|
x: commonOptions.scales.x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
console.log('Charts initialized successfully.');
|
console.log('Charts initialized successfully.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,11 +614,11 @@
|
|||||||
}
|
}
|
||||||
if (!data.netdata) {
|
if (!data.netdata) {
|
||||||
console.warn('Missing netdata data.');
|
console.warn('Missing netdata data.');
|
||||||
data.netdata = { cpu: [], ram: [], net: [], disk: [], disk_space: [], anomaly: [] };
|
data.netdata = { cpu: [], ram: [], net: [], disk: [], disk_space: [], anomaly: [], load: [] };
|
||||||
}
|
}
|
||||||
if (!data.jumpNode) {
|
if (!data.jumpNode) {
|
||||||
console.warn('Missing jump node data.');
|
console.warn('Missing jump node data.');
|
||||||
data.jumpNode = { cpu: [], ram: [], net: [], disk: [], anomaly: [], disk_space: [], uptime: [] };
|
data.jumpNode = { cpu: [], ram: [], net: [], disk: [], anomaly: [], disk_space: [], uptime: [], load: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show/hide no-data message for Jump Node
|
// Show/hide no-data message for Jump Node
|
||||||
@@ -543,7 +629,8 @@
|
|||||||
(data.jumpNode.disk && data.jumpNode.disk.length > 0) ||
|
(data.jumpNode.disk && data.jumpNode.disk.length > 0) ||
|
||||||
(data.jumpNode.anomaly && data.jumpNode.anomaly.length > 0) ||
|
(data.jumpNode.anomaly && data.jumpNode.anomaly.length > 0) ||
|
||||||
(data.jumpNode.disk_space && data.jumpNode.disk_space.length > 0) ||
|
(data.jumpNode.disk_space && data.jumpNode.disk_space.length > 0) ||
|
||||||
(data.jumpNode.uptime && data.jumpNode.uptime.length > 0)
|
(data.jumpNode.uptime && data.jumpNode.uptime.length > 0) ||
|
||||||
|
(data.jumpNode.load && data.jumpNode.load.length > 0)
|
||||||
);
|
);
|
||||||
jumpNoData.style.display = hasJumpData ? 'none' : 'block';
|
jumpNoData.style.display = hasJumpData ? 'none' : 'block';
|
||||||
|
|
||||||
@@ -565,6 +652,13 @@
|
|||||||
const latestAnomaly = anomalyData.length > 0 ? anomalyData[anomalyData.length - 1] : null;
|
const latestAnomaly = anomalyData.length > 0 ? anomalyData[anomalyData.length - 1] : null;
|
||||||
document.getElementById('ai-fault-count').textContent = latestAnomaly ? `${latestAnomaly.anomalous}` : '0';
|
document.getElementById('ai-fault-count').textContent = latestAnomaly ? `${latestAnomaly.anomalous}` : '0';
|
||||||
|
|
||||||
|
// Update Host Load Averages
|
||||||
|
const loadData = data.netdata.load || [];
|
||||||
|
const latestLoad = loadData.length > 0 ? loadData[loadData.length - 1] : null;
|
||||||
|
document.getElementById('host-load1').textContent = latestLoad ? latestLoad.load1.toFixed(2) : '0';
|
||||||
|
document.getElementById('host-load5').textContent = latestLoad ? latestLoad.load5.toFixed(2) : '0';
|
||||||
|
document.getElementById('host-load15').textContent = latestLoad ? latestLoad.load15.toFixed(2) : '0';
|
||||||
|
|
||||||
// Update Jump Node stats
|
// Update Jump Node stats
|
||||||
const jumpDiskSpaceData = data.jumpNode.disk_space || [];
|
const jumpDiskSpaceData = data.jumpNode.disk_space || [];
|
||||||
const latestJumpDiskSpace = jumpDiskSpaceData.length > 0 ? jumpDiskSpaceData[jumpDiskSpaceData.length - 1] : null;
|
const latestJumpDiskSpace = jumpDiskSpaceData.length > 0 ? jumpDiskSpaceData[jumpDiskSpaceData.length - 1] : null;
|
||||||
@@ -579,6 +673,13 @@
|
|||||||
const latestJumpUptime = jumpUptimeData.length > 0 ? jumpUptimeData[jumpUptimeData.length - 1] : null;
|
const latestJumpUptime = jumpUptimeData.length > 0 ? jumpUptimeData[jumpUptimeData.length - 1] : null;
|
||||||
document.getElementById('jump-uptime').textContent = latestJumpUptime ? formatUptime(latestJumpUptime.uptime) : '0 days';
|
document.getElementById('jump-uptime').textContent = latestJumpUptime ? formatUptime(latestJumpUptime.uptime) : '0 days';
|
||||||
|
|
||||||
|
// Update Jump Load Averages
|
||||||
|
const jumpLoadData = data.jumpNode.load || [];
|
||||||
|
const latestJumpLoad = jumpLoadData.length > 0 ? jumpLoadData[jumpLoadData.length - 1] : null;
|
||||||
|
document.getElementById('jump-load1').textContent = latestJumpLoad ? latestJumpLoad.load1.toFixed(2) : '0';
|
||||||
|
document.getElementById('jump-load5').textContent = latestJumpLoad ? latestJumpLoad.load5.toFixed(2) : '0';
|
||||||
|
document.getElementById('jump-load15').textContent = latestJumpLoad ? latestJumpLoad.load15.toFixed(2) : '0';
|
||||||
|
|
||||||
// Update container tables
|
// Update container tables
|
||||||
const cpuTable = document.getElementById('cpu-table');
|
const cpuTable = document.getElementById('cpu-table');
|
||||||
const memoryTable = document.getElementById('memory-table');
|
const memoryTable = document.getElementById('memory-table');
|
||||||
@@ -638,7 +739,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Jump Node network and disk history
|
// Update Host Load history
|
||||||
|
if (data.netdata.load?.length) {
|
||||||
|
const latestLoad = data.netdata.load[data.netdata.load.length - 1];
|
||||||
|
hostLoadHistory.push({
|
||||||
|
time: latestLoad.time,
|
||||||
|
load1: latestLoad.load1,
|
||||||
|
load5: latestLoad.load5,
|
||||||
|
load15: latestLoad.load15
|
||||||
|
});
|
||||||
|
if (hostLoadHistory.length > MAX_POINTS) {
|
||||||
|
hostLoadHistory.shift();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update Jump Node network, disk, and load history
|
||||||
if (data.jumpNode.net?.length) {
|
if (data.jumpNode.net?.length) {
|
||||||
const latestNet = data.jumpNode.net[data.jumpNode.net.length - 1];
|
const latestNet = data.jumpNode.net[data.jumpNode.net.length - 1];
|
||||||
jumpNetHistory.push({
|
jumpNetHistory.push({
|
||||||
@@ -667,6 +782,21 @@
|
|||||||
console.debug('No jump node disk data available.');
|
console.debug('No jump node disk data available.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.jumpNode.load?.length) {
|
||||||
|
const latestLoad = data.jumpNode.load[data.jumpNode.load.length - 1];
|
||||||
|
jumpLoadHistory.push({
|
||||||
|
time: latestLoad.time,
|
||||||
|
load1: latestLoad.load1,
|
||||||
|
load5: latestLoad.load5,
|
||||||
|
load15: latestLoad.load15
|
||||||
|
});
|
||||||
|
if (jumpLoadHistory.length > MAX_POINTS) {
|
||||||
|
jumpLoadHistory.shift();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.debug('No jump node load data available.');
|
||||||
|
}
|
||||||
|
|
||||||
// Update charts with smoothing and dynamic units
|
// Update charts with smoothing and dynamic units
|
||||||
const defaultLabels = Array(MAX_POINTS).fill(0).map((_, i) => i);
|
const defaultLabels = Array(MAX_POINTS).fill(0).map((_, i) => i);
|
||||||
const defaultData = Array(MAX_POINTS).fill(0);
|
const defaultData = Array(MAX_POINTS).fill(0);
|
||||||
@@ -728,6 +858,17 @@
|
|||||||
charts.disk.update();
|
charts.disk.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (charts.load) {
|
||||||
|
const load1Data = smoothData(hostLoadHistory.map(d => d.load1), SMOOTHING_WINDOW);
|
||||||
|
const load5Data = smoothData(hostLoadHistory.map(d => d.load5), SMOOTHING_WINDOW);
|
||||||
|
const load15Data = smoothData(hostLoadHistory.map(d => d.load15), SMOOTHING_WINDOW);
|
||||||
|
charts.load.data.labels = hostLoadHistory.length ? hostLoadHistory.map((_, i) => i) : defaultLabels;
|
||||||
|
charts.load.data.datasets[0].data = load1Data.length ? load1Data : defaultData;
|
||||||
|
charts.load.data.datasets[1].data = load5Data.length ? load5Data : defaultData;
|
||||||
|
charts.load.data.datasets[2].data = load15Data.length ? load15Data : defaultData;
|
||||||
|
charts.load.update();
|
||||||
|
}
|
||||||
|
|
||||||
if (charts.jumpCpu) {
|
if (charts.jumpCpu) {
|
||||||
const userData = smoothData(data.jumpNode.cpu?.map(d => d.user) || [], SMOOTHING_WINDOW);
|
const userData = smoothData(data.jumpNode.cpu?.map(d => d.user) || [], SMOOTHING_WINDOW);
|
||||||
const systemData = smoothData(data.jumpNode.cpu?.map(d => d.system) || [], SMOOTHING_WINDOW);
|
const systemData = smoothData(data.jumpNode.cpu?.map(d => d.system) || [], SMOOTHING_WINDOW);
|
||||||
@@ -768,6 +909,19 @@
|
|||||||
} else {
|
} else {
|
||||||
console.debug('Jump Disk chart not initialized.');
|
console.debug('Jump Disk chart not initialized.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (charts.jumpLoad) {
|
||||||
|
const load1Data = smoothData(jumpLoadHistory.map(d => d.load1), SMOOTHING_WINDOW);
|
||||||
|
const load5Data = smoothData(jumpLoadHistory.map(d => d.load5), SMOOTHING_WINDOW);
|
||||||
|
const load15Data = smoothData(jumpLoadHistory.map(d => d.load15), SMOOTHING_WINDOW);
|
||||||
|
charts.jumpLoad.data.labels = jumpLoadHistory.length ? jumpLoadHistory.map((_, i) => i) : defaultLabels;
|
||||||
|
charts.jumpLoad.data.datasets[0].data = load1Data.length ? load1Data : defaultData;
|
||||||
|
charts.jumpLoad.data.datasets[1].data = load5Data.length ? load5Data : defaultData;
|
||||||
|
charts.jumpLoad.data.datasets[2].data = load15Data.length ? load15Data : defaultData;
|
||||||
|
charts.jumpLoad.update();
|
||||||
|
} else {
|
||||||
|
console.debug('Jump Load chart not initialized.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
ws.onmessage = (event) => {
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// server.js
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const http = require('http');
|
const http = require('http');
|
||||||
const WebSocket = require('ws');
|
const WebSocket = require('ws');
|
||||||
@@ -166,7 +167,7 @@ async function getDockerStats() {
|
|||||||
async function getNetdataMetrics() {
|
async function getNetdataMetrics() {
|
||||||
if (!NETDATA_URL) {
|
if (!NETDATA_URL) {
|
||||||
console.error('Cannot fetch Netdata metrics: NETDATA_URL is undefined.');
|
console.error('Cannot fetch Netdata metrics: NETDATA_URL is undefined.');
|
||||||
return { cpu: [], ram: [], net: [], disk: [], disk_space: [], anomaly: [] };
|
return { cpu: [], ram: [], net: [], disk: [], disk_space: [], anomaly: [], load: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -176,7 +177,8 @@ async function getNetdataMetrics() {
|
|||||||
{ key: 'net', url: `${NETDATA_URL}/api/v3/data?contexts=system.net&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], received: d[1], sent: d[2] }) },
|
{ key: 'net', url: `${NETDATA_URL}/api/v3/data?contexts=system.net&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], received: d[1], sent: d[2] }) },
|
||||||
{ key: 'disk', url: `${NETDATA_URL}/api/v3/data?contexts=system.io&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], in: d[1], out: d[2] }) },
|
{ key: 'disk', url: `${NETDATA_URL}/api/v3/data?contexts=system.io&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], in: d[1], out: d[2] }) },
|
||||||
{ key: 'disk_space', url: `${NETDATA_URL}/api/v3/data?contexts=disk.space&labels=mount_point:%2F&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], avail: d[1], used: d[2], reserved: d[3] }) },
|
{ key: 'disk_space', url: `${NETDATA_URL}/api/v3/data?contexts=disk.space&labels=mount_point:%2F&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], avail: d[1], used: d[2], reserved: d[3] }) },
|
||||||
{ key: 'anomaly', url: `${NETDATA_URL}/api/v3/data?contexts=anomaly_detection.dimensions&scope_nodes=mchost&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], anomalous: d[1], normal: d[2] }) }
|
{ key: 'anomaly', url: `${NETDATA_URL}/api/v3/data?contexts=anomaly_detection.dimensions&scope_nodes=mchost&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], anomalous: d[1], normal: d[2] }) },
|
||||||
|
{ key: 'load', url: `${NETDATA_URL}/api/v3/data?contexts=system.load&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], load1: d[1], load5: d[2], load15: d[3] }) }
|
||||||
];
|
];
|
||||||
|
|
||||||
const results = await Promise.all(
|
const results = await Promise.all(
|
||||||
@@ -204,7 +206,7 @@ async function getNetdataMetrics() {
|
|||||||
return metrics;
|
return metrics;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching Netdata metrics:', error.message);
|
console.error('Error fetching Netdata metrics:', error.message);
|
||||||
return { cpu: [], ram: [], net: [], disk: [], disk_space: [], anomaly: [] };
|
return { cpu: [], ram: [], net: [], disk: [], disk_space: [], anomaly: [], load: [] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,7 +214,7 @@ async function getNetdataMetrics() {
|
|||||||
async function getJumpNodeMetrics() {
|
async function getJumpNodeMetrics() {
|
||||||
if (!NETDATA_JUMP_URL) {
|
if (!NETDATA_JUMP_URL) {
|
||||||
console.error('Cannot fetch Jump Node metrics: NETDATA_JUMP_URL is undefined.');
|
console.error('Cannot fetch Jump Node metrics: NETDATA_JUMP_URL is undefined.');
|
||||||
return { cpu: [], ram: [], net: [], disk: [], anomaly: [], disk_space: [], uptime: [] };
|
return { cpu: [], ram: [], net: [], disk: [], anomaly: [], disk_space: [], uptime: [], load: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -222,7 +224,8 @@ async function getJumpNodeMetrics() {
|
|||||||
{ key: 'disk', url: `${NETDATA_JUMP_URL}/api/v3/data?contexts=system.io&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], in: d[1], out: d[2] }) },
|
{ key: 'disk', url: `${NETDATA_JUMP_URL}/api/v3/data?contexts=system.io&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], in: d[1], out: d[2] }) },
|
||||||
{ key: 'anomaly', url: `${NETDATA_JUMP_URL}/api/v3/data?contexts=anomaly_detection.dimensions&scope_nodes=my-mc-link&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], anomalous: d[1], normal: d[2] }) },
|
{ key: 'anomaly', url: `${NETDATA_JUMP_URL}/api/v3/data?contexts=anomaly_detection.dimensions&scope_nodes=my-mc-link&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], anomalous: d[1], normal: d[2] }) },
|
||||||
{ key: 'disk_space', url: `${NETDATA_JUMP_URL}/api/v3/data?contexts=disk.space&labels=mount_point:%2F&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], avail: d[1], used: d[2], reserved: d[3] }) },
|
{ key: 'disk_space', url: `${NETDATA_JUMP_URL}/api/v3/data?contexts=disk.space&labels=mount_point:%2F&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], avail: d[1], used: d[2], reserved: d[3] }) },
|
||||||
{ key: 'uptime', url: `${NETDATA_JUMP_URL}/api/v3/data?contexts=system.uptime&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], uptime: d[1] }) }
|
{ key: 'uptime', url: `${NETDATA_JUMP_URL}/api/v3/data?contexts=system.uptime&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], uptime: d[1] }) },
|
||||||
|
{ key: 'load', url: `${NETDATA_JUMP_URL}/api/v3/data?contexts=system.load&group_by=dimension&group=average&after=-60&points=30&format=json`, map: d => ({ time: d[0], load1: d[1], load5: d[2], load15: d[3] }) }
|
||||||
];
|
];
|
||||||
|
|
||||||
const results = await Promise.all(
|
const results = await Promise.all(
|
||||||
@@ -255,11 +258,12 @@ async function getJumpNodeMetrics() {
|
|||||||
disk: metrics.disk || [],
|
disk: metrics.disk || [],
|
||||||
anomaly: metrics.anomaly || [],
|
anomaly: metrics.anomaly || [],
|
||||||
disk_space: metrics.disk_space || [],
|
disk_space: metrics.disk_space || [],
|
||||||
uptime: metrics.uptime || []
|
uptime: metrics.uptime || [],
|
||||||
|
load: metrics.load || []
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching Jump Node metrics:', error.message);
|
console.error('Error fetching Jump Node metrics:', error.message);
|
||||||
return { cpu: [], ram: [], net: [], disk: [], anomaly: [], disk_space: [], uptime: [] };
|
return { cpu: [], ram: [], net: [], disk: [], anomaly: [], disk_space: [], uptime: [], load: [] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,8 +278,8 @@ wss.on('connection', (ws) => {
|
|||||||
// Send updates every 1 second
|
// Send updates every 1 second
|
||||||
const interval = setInterval(async () => {
|
const interval = setInterval(async () => {
|
||||||
let dockerStats = {};
|
let dockerStats = {};
|
||||||
let netdataMetrics = { cpu: [], ram: [], net: [], disk: [], disk_space: [], anomaly: [] };
|
let netdataMetrics = { cpu: [], ram: [], net: [], disk: [], disk_space: [], anomaly: [], load: [] };
|
||||||
let jumpNodeMetrics = { cpu: [], ram: [], net: [], disk: [], anomaly: [], disk_space: [], uptime: [] };
|
let jumpNodeMetrics = { cpu: [], ram: [], net: [], disk: [], anomaly: [], disk_space: [], uptime: [], load: [] };
|
||||||
let holesailProcessCount = 0;
|
let holesailProcessCount = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Reference in New Issue
Block a user