Documentation

Integration Guide

Learn how to integrate our monitoring solution into your server

WebSocket Integration

To integrate WebSocket functionality, follow the steps below:

Main File


// Main.ts
import express from 'express';
import http from 'http';
import { sysResource_WebsocketData } from './websocketData';

// Create an Express app (optional)
const app = express();
const cors = require('cors')

app.use(express.urlencoded({ extended: false }));

const corsOptions = {
    origin: 'https://sysresource.vercel.app',// your frontend domain or ip
    optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}

app.use(cors(corsOptions));

//Integrating WebSocket

// Create an HTTP server
const server = http.createServer(app);

// Define WebSocket authentication key and data sending interval
const authKey = 'your-secret-key';
const interval = 5000; // Send data every 5 seconds (in milliseconds)

// Pass the HTTP server to the WebSocket handler
sysResource_WebsocketData(server, { key: authKey, interval });

// Start the server
const PORT = 4000;
server.listen(PORT, () => {
    console.log('Server Listening on Port 4000');
});


              
              

websocketData.ts File


// websocketData.ts
const WebSocketServer = require('websocket').server;  // WebSocket server from the 'websocket' package
const os = require('os');
const url = require('url');
let previousCpuInfo = os.cpus();

function calculateCpuUsage() {
    const currentCpuInfo = os.cpus();

    let idleDiff = 0;
    let totalDiff = 0;

    for (let i = 0; i < currentCpuInfo.length; i++) {
        const previous = previousCpuInfo[i].times;
        const current = currentCpuInfo[i].times;

        const prevIdle = previous.idle;
        const prevTotal:any = Object.values(previous).reduce((acc:number, val:number) => acc + val, 0);

        const currIdle = current.idle;
        const currTotal:any = Object.values(current).reduce((acc:number, val:number) => acc + val, 0);

        idleDiff += currIdle - prevIdle;
        totalDiff += currTotal - prevTotal;
    }

    const cpuUsagePercent = 100 - Math.floor((idleDiff / totalDiff) * 100);

    previousCpuInfo = currentCpuInfo;

    return (cpuUsagePercent>=0 && cpuUsagePercent<=100)?cpuUsagePercent:0;
}
// Define a function to start WebSocket server with key-based authentication
export function sysResource_WebsocketData(server, options){
    const { key: authKey, interval } = options;

    // Create a WebSocket server attached to the HTTP server
    const wss = new WebSocketServer({
        httpServer: server  // Attach to the provided HTTP server
    });

    // Handle WebSocket requests and connections
    wss.on('request', (req) => {
        const requestUrl = url.parse(req.httpRequest.url || '', true);
        const params = requestUrl.query;
        // Only allow connections to the /sysresource path
        if (requestUrl.pathname !== '/sysresource') {
            req.reject(404, 'Not Found');
            return;
        }
        // Check if the provided key matches the server's key
        if (params.key !== authKey) {
            // console.log('Client attempted to connect with an invalid key.');
            req.reject(1008, 'Unauthorized');  // Reject the request if the key is invalid
            return;
        }

        // console.log('Client connected via WebSocket with valid key');
        const connection = req.accept(null, req.origin);

        // Function to send system resource data periodically
        const sendSystemResources = () => {
            const data = {
                hostname: os.hostname(),
                cpuUsage:calculateCpuUsage(),
                cpu: os.cpus()[0].model,
                cpuCore: os.cpus().length,
                totalMemory: Math.round(os.totalmem() * 0.000001),
                freeMemory: Math.round(os.freemem() * 0.000001),
                release: os.release(),
                platform: os.platform(),
                uptime: Math.round(os.uptime() / 60),  // in minutes
                type: os.type(),
                machine: os.machine(),
                architecture: os.arch(),
                environment:'NodeJS'
            };
            connection.sendUTF(JSON.stringify(data));
        };

        // Set interval to send data based on the provided interval
        const dataInterval = setInterval(sendSystemResources, interval);

        // Handle WebSocket connection close event
        connection.on('close', () => {
            // console.log('Client disconnected');
            clearInterval(dataInterval);  // Stop sending data when the client disconnects
        });
    });
};
              

This code will start the WebSocket server and send system resource on request in Nodejs.

API Function

Use the following API function to fetch system resource details:


// Main.ts
import express from 'express';
import { sysresource_APIData } from './APIData';

// Create an Express app
const app = express();
const cors = require('cors')

app.use(express.urlencoded({ extended: false }));

//Define Cors for communcation
const corsOptions = {
    origin: 'https://sysresource.vercel.app',// your frontend domain or ip
    optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
app.use(cors(corsOptions));


// Define a route for the API
app.get('/sysresource/:key', (req, res) => {
    const { key } = req.params;
    const secretKey = 'your-secret-key';
    const data = sysresource_APIData({ paramKey: key, key: secretKey });
    if(data.success) {
        res.status(200).send(data.data);
    } else {
        res.status(401).send(data.error);
    }
});

// Start the server
const PORT = 4000;
server.listen(PORT, () => {
    console.log('Server Listening on PORT 4000');
});

              

APIData.ts File


//APIData.ts
const os = require('os');

interface sysresource_APIDataOptions {
    paramKey:string;
    key: string;
}
interface SystemInfo {
    hostname: string;
    cpuUsage: number;
    cpu: string;
    cpuCore: number;
    totalMemory: number;  // in MB
    freeMemory: number;   // in MB
    release: string;
    platform: string;
    uptime: number;  // in minutes
    type: string;
    machine: string;
    architecture: string;
}

let previousCpuInfo = os.cpus();

function calculateCpuUsage() {
    const currentCpuInfo = os.cpus();

    let idleDiff = 0;
    let totalDiff = 0;

    for (let i = 0; i < currentCpuInfo.length; i++) {
        const previous = previousCpuInfo[i].times;
        const current = currentCpuInfo[i].times;

        const prevIdle = previous.idle;
        const prevTotal:any = Object.values(previous).reduce((acc:number, val:number) => acc + val, 0);

        const currIdle = current.idle;
        const currTotal:any = Object.values(current).reduce((acc:number, val:number) => acc + val, 0);

        idleDiff += currIdle - prevIdle;
        totalDiff += currTotal - prevTotal;
    }

    const cpuUsagePercent = 100 - Math.floor((idleDiff / totalDiff) * 100);

    previousCpuInfo = currentCpuInfo;

    return (cpuUsagePercent>=0 && cpuUsagePercent<=100)?cpuUsagePercent:0;
}

export function sysresource_APIData(options:sysresource_APIDataOptions):{
    success:boolean;
    error:string|null;
    data:SystemInfo | null} {
    const { paramKey, key: authKey } = options;
    if(paramKey !== authKey) {
        return {
            success: false, error: 'Unauthorized key',data: null}
    }
    const data = {
        hostname: os.hostname(),
        cpuUsage:calculateCpuUsage(),
        cpu: os.cpus()[0].model,
        cpuCore: os.cpus().length,
        totalMemory: Math.round(os.totalmem() * 0.000001),
        freeMemory: Math.round(os.freemem() * 0.000001),
        release: os.release(),
        platform: os.platform(),
        uptime: Math.round(os.uptime() / 60),  // in minutes
        type: os.type(),
        machine: os.machine(),
        architecture: os.arch(),
        environment:'NodeJS'
    };
    return {success:true,error:null,data:data}
}
              

The /sysresource/your-secret-key endpoint provides CPU usage, memory details, and other system statistics. Make sure to include your API key in the authorization parameters.

WebSocket vs API: Pros and Cons

WebSocket

  • Pros:
    • Real-time data: Provides continuous updates as soon as the server sends them.
    • Efficient for long-lasting connections where constant data flow is needed.
  • Cons:
    • Maintains an active connection, which can consume resources and be harder to scale.
    • The interval between updates can only be configured from the backend.
    • If the connection drops, you must handle reconnections and potential data loss.

API (RESTful)

  • Pros:
    • Stateless: No need to maintain an active connection, requests are made only when necessary.
    • Client-side control: The client can determine how often to fetch data by adjusting the request intervals.
    • Easier to scale as its based on HTTP requests.
  • Cons:
    • Not real-time: Updates only happen when the client makes a request.
    • Increased network overhead if requests are made frequently to simulate real-time behavior.