node-watch-tower
Version:
Node.js monitoring utility to track uptime, CPU, and memory usage and report to a central admin server.
84 lines (76 loc) • 2.34 kB
JavaScript
const os = require('os');
const axios = require('axios');
class NodeWatchTower {
constructor(config) {
this.adminUrl = "https://prutech.co.in/nodeMonitor/api";
this.interval = 1000*60;
this.token = config.token || null;
this.registered = false;
this.id=config.id || null;
this.start();
}
async start() {
await this.register();
this.sendStatsLoop();
}
async register() {
try {
const res = await axios.post(`${this.adminUrl}/app/register`, {
id: this.id,
hostname: os.hostname(),
pid: process.pid,
token: this.token,
});
if(res.data?.status==1){
this.registered = true;
console.log('\x1b[32m[NodeWatchTower]\x1b[0m ✅ Registered with Admin Monitor');
this.interval = res.data?.data?.heartBeatInterval*1000 || this.interval;
}else{
console.log('\x1b[31m[NodeWatchTower]\x1b[0m ❌ Registration Failed:', res.data.message);
}
} catch (err) {
console.log('\x1b[31m[NodeWatchTower]\x1b[0m ❌ Registration Failed:', err.response.data.message);
}
}
async sendStatsLoop() {
setInterval(async () => {
if (!this.registered) return;
try {
const stats = this.getStats();
await axios.post(`${this.adminUrl}/app/heartbeat`, {
name: this.appName,
stats,
token: this.token,
id:this.id
});
} catch (err) {
console.log('\x1b[31m[NodeWatchTower]\x1b[0m ❌ Heartbeat failed:', err.message);
}
}, this.interval);
}
getStats() {
const memory = process.memoryUsage();
return {
timestamp: new Date(),
cpu: this.getCpuLoad(),
memory: {
rss: (memory.rss / 1024 / 1024).toFixed(2),
heapUsed: (memory.heapUsed / 1024 / 1024).toFixed(2),
heapTotal: (memory.heapTotal / 1024 / 1024).toFixed(2),
},
uptime: process.uptime(),
};
}
getCpuLoad() {
const cpus = os.cpus();
let idle = 0, total = 0;
cpus.forEach(core => {
for (let type in core.times) {
total += core.times[type];
}
idle += core.times.idle;
});
return Math.round(100 - (idle / total) * 100);
}
}
module.exports = NodeWatchTower;