add Jump node
This commit is contained in:
136
system-status.js
136
system-status.js
@ -12,8 +12,23 @@ const server = http.createServer(app);
|
||||
const wss = new WebSocket.Server({ server });
|
||||
const docker = new Docker({ socketPath: process.env.DOCKER_SOCKET_PATH });
|
||||
const NETDATA_URL = process.env.NETDATA_URL;
|
||||
const NETDATA_JUMP_URL = process.env.NETDATA_JUMP_URL;
|
||||
const TOTAL_CORES = parseInt(process.env.TOTAL_CORES, 10);
|
||||
|
||||
// Verify environment variables
|
||||
if (!NETDATA_URL) {
|
||||
console.error('NETDATA_URL environment variable is not set.');
|
||||
}
|
||||
if (!NETDATA_JUMP_URL) {
|
||||
console.error('NETDATA_JUMP_URL environment variable is not set.');
|
||||
}
|
||||
if (!process.env.DOCKER_SOCKET_PATH) {
|
||||
console.error('DOCKER_SOCKET_PATH environment variable is not set.');
|
||||
}
|
||||
if (!TOTAL_CORES) {
|
||||
console.error('TOTAL_CORES environment variable is not set or invalid.');
|
||||
}
|
||||
|
||||
// Promisify exec for async/await
|
||||
const execPromise = util.promisify(exec);
|
||||
|
||||
@ -149,24 +164,33 @@ async function getDockerStats() {
|
||||
|
||||
// Fetch Netdata metrics
|
||||
async function getNetdataMetrics() {
|
||||
if (!NETDATA_URL) {
|
||||
console.error('Cannot fetch Netdata metrics: NETDATA_URL is undefined.');
|
||||
return { cpu: [], ram: [], net: [], disk: [], disk_space: [], anomaly: [] };
|
||||
}
|
||||
|
||||
try {
|
||||
const charts = [
|
||||
{ key: 'cpu', url: `${NETDATA_URL}/data?chart=system.cpu&after=-60&points=30`, map: d => ({ time: d[0], user: d[6], system: d[7] }) },
|
||||
{ key: 'ram', url: `${NETDATA_URL}/data?chart=system.ram&after=-60&points=30`, map: d => ({ time: d[0], used: d[2], free: d[3] }) },
|
||||
{ key: 'net', url: `${NETDATA_URL}/data?chart=system.net&after=-60&points=30`, map: d => ({ time: d[0], received: d[1], sent: d[2] }) },
|
||||
{ key: 'disk', url: `${NETDATA_URL}/data?chart=system.io&after=-60&points=30`, map: d => ({ time: d[0], in: d[1], out: d[2] }) },
|
||||
{ key: 'disk_space', url: `${NETDATA_URL}/data?chart=disk_space./&format=json&after=-60&points=30`, map: d => ({ time: d[0], avail: d[1], used: d[2], reserved: d[3] }) },
|
||||
{ key: 'anomaly', url: `${NETDATA_URL}/data?chart=anomaly_detection.dimensions_on_mchost&format=json&after=-60&points=30`, map: d => ({ time: d[0], anomalous: d[1], normal: d[2] }) }
|
||||
{ key: 'cpu', url: `${NETDATA_URL}/api/v1/data?chart=system.cpu&after=-60&points=30`, map: d => ({ time: d[0], user: d[6], system: d[7] }) },
|
||||
{ key: 'ram', url: `${NETDATA_URL}/api/v1/data?chart=system.ram&after=-60&points=30`, map: d => ({ time: d[0], used: d[2], free: d[3] }) },
|
||||
{ key: 'net', url: `${NETDATA_URL}/api/v1/data?chart=system.net&after=-60&points=30`, map: d => ({ time: d[0], received: d[1], sent: d[2] }) },
|
||||
{ key: 'disk', url: `${NETDATA_URL}/api/v1/data?chart=system.io&after=-60&points=30`, map: d => ({ time: d[0], in: d[1], out: d[2] }) },
|
||||
{ key: 'disk_space', url: `${NETDATA_URL}/api/v1/data?chart=disk_space./&format=json&after=-60&points=30`, map: d => ({ time: d[0], avail: d[1], used: d[2], reserved: d[3] }) },
|
||||
{ key: 'anomaly', url: `${NETDATA_URL}/api/v1/data?chart=anomaly_detection.dimensions_on_mchost&format=json&after=-60&points=30`, map: d => ({ time: d[0], anomalous: d[1], normal: d[2] }) }
|
||||
];
|
||||
|
||||
const results = await Promise.all(
|
||||
charts.map(async ({ key, url, map }) => {
|
||||
try {
|
||||
const response = await axios.get(url);
|
||||
const response = await axios.get(url, { timeout: 5000 });
|
||||
if (!response.data || !response.data.data) {
|
||||
console.warn(`No data returned for Netdata chart ${key} from ${url}`);
|
||||
return { key, data: [] };
|
||||
}
|
||||
const data = response.data.data.map(map);
|
||||
return { key, data };
|
||||
} catch (error) {
|
||||
console.warn(`Failed to fetch Netdata chart ${key}:`, error.message);
|
||||
console.warn(`Failed to fetch Netdata chart ${key} from ${url}:`, error.message, error.response ? `Status: ${error.response.status}` : '');
|
||||
return { key, data: [] };
|
||||
}
|
||||
})
|
||||
@ -184,6 +208,61 @@ async function getNetdataMetrics() {
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Jump Node metrics
|
||||
async function getJumpNodeMetrics() {
|
||||
if (!NETDATA_JUMP_URL) {
|
||||
console.error('Cannot fetch Jump Node metrics: NETDATA_JUMP_URL is undefined.');
|
||||
return { cpu: [], ram: [], net: [], disk: [], anomaly: [], disk_space: [], uptime: [] };
|
||||
}
|
||||
|
||||
try {
|
||||
const charts = [
|
||||
{ key: 'cpu', url: `${NETDATA_JUMP_URL}/api/v1/data?chart=system.cpu&after=-60&points=30`, map: d => ({ time: d[0], user: d[6], system: d[7] }) },
|
||||
{ key: 'net', url: `${NETDATA_JUMP_URL}/api/v1/data?chart=system.net&after=-60&points=30`, map: d => ({ time: d[0], received: d[1], sent: d[2] }) },
|
||||
{ key: 'disk', url: `${NETDATA_JUMP_URL}/api/v1/data?chart=system.io&after=-60&points=30`, map: d => ({ time: d[0], in: d[1], out: d[2] }) },
|
||||
{ key: 'anomaly', url: `${NETDATA_JUMP_URL}/api/v1/data?chart=anomaly_detection.dimensions_on_my-mc-link&format=json&after=-60&points=30`, map: d => ({ time: d[0], anomalous: d[1], normal: d[2] }) },
|
||||
{ key: 'disk_space', url: `${NETDATA_JUMP_URL}/api/v1/data?chart=disk_space./&format=json&after=-60&points=30`, map: d => ({ time: d[0], avail: d[1], used: d[2], reserved: d[3] }) },
|
||||
{ key: 'uptime', url: `${NETDATA_JUMP_URL}/api/v1/data?chart=system.uptime&format=json&after=-60&points=30`, map: d => ({ time: d[0], uptime: d[1] }) }
|
||||
];
|
||||
|
||||
const results = await Promise.all(
|
||||
charts.map(async ({ key, url, map }) => {
|
||||
try {
|
||||
const response = await axios.get(url, { timeout: 10000 });
|
||||
if (!response.data || !response.data.data) {
|
||||
console.warn(`No data returned for Jump Node chart ${key} from ${url}`);
|
||||
return { key, data: [] };
|
||||
}
|
||||
const data = response.data.data.map(map);
|
||||
return { key, data };
|
||||
} catch (error) {
|
||||
console.warn(`Failed to fetch Jump Node chart ${key} from ${url}:`, error.message, error.response ? `Status: ${error.response.status}` : '');
|
||||
return { key, data: [] };
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
const metrics = {};
|
||||
results.forEach(({ key, data }) => {
|
||||
metrics[key] = data;
|
||||
});
|
||||
|
||||
// Ensure all keys are present, even if empty
|
||||
return {
|
||||
cpu: metrics.cpu || [],
|
||||
ram: [], // RAM chart removed until verified
|
||||
net: metrics.net || [],
|
||||
disk: metrics.disk || [],
|
||||
anomaly: metrics.anomaly || [],
|
||||
disk_space: metrics.disk_space || [],
|
||||
uptime: metrics.uptime || []
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error fetching Jump Node metrics:', error.message);
|
||||
return { cpu: [], ram: [], net: [], disk: [], anomaly: [], disk_space: [], uptime: [] };
|
||||
}
|
||||
}
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.sendFile(__dirname + '/status.html');
|
||||
});
|
||||
@ -194,13 +273,42 @@ wss.on('connection', (ws) => {
|
||||
|
||||
// Send updates every 1 second
|
||||
const interval = setInterval(async () => {
|
||||
const [dockerStats, netdataMetrics, holesailProcessCount] = await Promise.all([
|
||||
getDockerStats(),
|
||||
getNetdataMetrics(),
|
||||
getHolesailProcessCount()
|
||||
]);
|
||||
let dockerStats = {};
|
||||
let netdataMetrics = { cpu: [], ram: [], net: [], disk: [], disk_space: [], anomaly: [] };
|
||||
let jumpNodeMetrics = { cpu: [], ram: [], net: [], disk: [], anomaly: [], disk_space: [], uptime: [] };
|
||||
let holesailProcessCount = 0;
|
||||
|
||||
ws.send(JSON.stringify({ docker: dockerStats, netdata: netdataMetrics, holesailProcessCount }));
|
||||
try {
|
||||
dockerStats = await getDockerStats();
|
||||
} catch (error) {
|
||||
console.error('Error in getDockerStats:', error.message);
|
||||
}
|
||||
|
||||
try {
|
||||
netdataMetrics = await getNetdataMetrics();
|
||||
} catch (error) {
|
||||
console.error('Error in getNetdataMetrics:', error.message);
|
||||
}
|
||||
|
||||
try {
|
||||
jumpNodeMetrics = await getJumpNodeMetrics();
|
||||
} catch (error) {
|
||||
console.error('Error in getJumpNodeMetrics:', error.message);
|
||||
}
|
||||
|
||||
try {
|
||||
holesailProcessCount = await getHolesailProcessCount();
|
||||
} catch (error) {
|
||||
console.error('Error in getHolesailProcessCount:', error.message);
|
||||
}
|
||||
|
||||
const payload = {
|
||||
docker: dockerStats,
|
||||
netdata: netdataMetrics,
|
||||
jumpNode: jumpNodeMetrics,
|
||||
holesailProcessCount
|
||||
};
|
||||
ws.send(JSON.stringify(payload));
|
||||
}, 1000);
|
||||
|
||||
ws.on('close', () => {
|
||||
|
Reference in New Issue
Block a user