DEV Community

alexpaper
alexpaper

Posted on

1 2

NodeJs Socket.io Sys Monitor

I realized this simple system monitor project

Alt Text

I used Nodejs as backend server, ejs to render the frontend single page app, I also utilized socket.io for backend frontend comunication.

This is a simple step by step guide.

If you are interested you can check the youtube links bellow.
CPU-RAM-MON-part-1
CPU-RAM-MON-part-2
CPU-RAM-MON-part-3

First create the project folder:

mkdir nodejs-socket-io-sys-mon
cd nodejs-socket-io-sys-mon
Enter fullscreen mode Exit fullscreen mode

Npm init

npm init
Enter fullscreen mode Exit fullscreen mode

then create the folders structure

mkdir views public public/css public/js
Enter fullscreen mode Exit fullscreen mode

then create the files

touch main.js views/index.ejs public/css/main.css public/js/main.js
Enter fullscreen mode Exit fullscreen mode

Install dependencies

npm i express socket.io node-os-utils ejs
Enter fullscreen mode Exit fullscreen mode

Run Visual studio code

code .
Enter fullscreen mode Exit fullscreen mode

Change/add package.json start scripts

{
    "name": "nodejs-socket-io-sys-mon",
    "version": "1.0.0",
    "description": "",
    "main": "main.js",
    "scripts": {
        "start": "node main.js",
        "dev": "nodemon main.js"
    },
    "author": "",
    "license": "ISC",
    "dependencies": {
        "ejs": "^3.1.5",
        "express": "^4.17.1",
        "node-os-utils": "^1.3.0",
        "os": "^0.1.1",
        "socket.io": "^2.3.0"
    }
}
Enter fullscreen mode Exit fullscreen mode

Start writing the backend code, open main.js

// REQUIRE NPM PACKAGES
const http = require('http');
const express = require('express');
const app = express();
const httpServer = http.createServer(app);
const osUtils = require('node-os-utils');
const os = require('os');
const io = require('socket.io')(httpServer);
// View Engine and static public folder
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/public'));
// Root Route
app.get('/', (req, res) => {
    res.render('index.ejs');
});
// CPU USAGE
const cpu = osUtils.cpu;
// USER and OS
const username = os.userInfo([{ encoding: 'buffer' }]).username;
const osInfo = os.type();
// SOCKET IO
io.on('connection', socket => {
    console.log(`${socket.id} connected`);
    // USE SET INTERVAL TO CHECK RAM USAGE EVERY SECOND
    setInterval(() => {
        // RAM USED tot - free
        let ramUsed = Math.round(os.totalmem()) - Math.round(os.freemem());
        // RAM percentage
        let ram = (ramUsed * 100 / Math.round(os.totalmem())).toFixed(0);
        // console.log(ram + '%')
        // CPU USAGE PERCENTAGE
        cpu.usage().then(cpu => socket.emit('ram-usage', { ram, cpu, username, osInfo }))
    }, 1000);
});

// Run the server
let PORT = 3001;
httpServer.listen(PORT, () => {
    console.log(`Server beating 💓 on port: ${PORT}`)
});
Enter fullscreen mode Exit fullscreen mode

then the frontend index.ejs

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Notification</title>
    <link rel="stylesheet" href="./css/main.css">
    <link rel="icon" type="image/svg" href="./imgs/resources.svg">
</head>

<body>
    <a href="/catalog" class="home"><img class="home-svg" src="./imgs/home.svg" alt=""></a>
    <div class="content">
        <h1>OS Resurces Monitor</h1>
        <div class="user">Hello</div>
        <div class="os">OS Type</div>
        <!-- CPU  -->
        <label class="cpu-label" for="cpu">CPU 0%</label>
        <progress class="cpu-bar" id="cpu" value="10" min='0' max='100'></progress>
        <!-- RAM  -->
        <label class="ram-label" for="ram">RAM 0%</label>
        <progress class="ram-bar" id="ram" value="10" min='0' max='100'></progress>

    </div>

    <footer>width 💙 @gd</footer>
    <!-- SOCKET IO  -->
    <script src="/socket.io/socket.io.js" defer></script>
    <script src="./js/main.js" defer></script>
</body>

</html>
Enter fullscreen mode Exit fullscreen mode

Now edit frontend main.js, add this code

// SOCKET IO
const socket = io();
// SELECT ELEMENTS
const labelRam = document.querySelector('.ram-label');
const progRam = document.querySelector('.ram-bar');
const labelCpu = document.querySelector('.cpu-label');
const progCpu = document.querySelector('.cpu-bar');
const user = document.querySelector('.user');
const os = document.querySelector('.os');

// ON CONNECT EVENT
socket.on('connect', () => {
    console.log('Connected');
});
// ON RAM USAGE EVENT
socket.on('ram-usage', ({ ram, cpu, username, osInfo }) => {
    // SHOW OS USER INFO
    user.innerHTML = `<span>Hello ${username}</span>`;
    os.innerHTML = `<span>OS type: ${osInfo === 'Windows_NT' ? 'Microsoft Windows' : osInfo}</span>`
        // Set ram label
    labelRam.innerHTML = `<span>RAM ${ram} % </span>`;
    // Set Ram bar
    progRam.value = ram;
    // Set cpu label
    labelCpu.innerHTML = `<span>CPU ${cpu} %</span>`
        // Set cpu bar
    progCpu.value = cpu;
    // Check
    if (cpu > 90) {
        notify(cpu)
    }
});

// NOTIFICATION FUNCTION
let notify = (info) => {
    // If granted
    if (Notification.permission === 'granted') {
        new Notification('Title', {
            body: `CPU over ${info} %`
        });
    }
    // If denied
    if (Notification.permission !== 'denied') {
        Notification.requestPermission()
            .then((permission) => {
                if (permission === 'granted') {
                    new Notification('Title', {
                        body: `CPU over ${info} %`
                    });
                };
            });
    };

};
Enter fullscreen mode Exit fullscreen mode

It's almost done, just a little bit of styles...

@import url('https://fonts.googleapis.com/css2?family=Oswald&display=swap');
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Oswald', sans-serif;
    color: #808080;
}

h1 {
    font-size: 4rem;
    padding: 10px;
    margin: 10px auto;
}

.content {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
}

.user,
.os {
    font-size: 1.1rem;
    height: 30px;
}

label {
    margin: 5px auto;
}

progress {
    margin: 10px auto;
}

progress[value] {
    appearance: none;
}

progress[value]::-webkit-progress-value {
    background-image: -webkit-linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, .1) 33%, rgba(0, 0, 0, .1) 66%, transparent 66%), -webkit-linear-gradient(top, rgba(255, 255, 255, .25), rgba(0, 0, 0, .25)), -webkit-linear-gradient(left, #09c, #f44);
}

footer {
    position: fixed;
    bottom: 10px;
    text-align: center;
    padding: 10px;
    left: 50%;
    transform: translate(-50%);
}

.home {
    text-decoration: none;
    position: sticky;
    top: 10px;
    left: 50%;
    transform: translate(-50%);
}

.home .home-svg {
    width: 20px;
    display: inline-block;
}

@media (max-width: 768px) {
    h1 {
        font-size: 3rem;
    }
}
Enter fullscreen mode Exit fullscreen mode

Done.👍
🖖

If you are intrested you can check the youtube links bellow.
CPU-RAM-MON-part-1
CPU-RAM-MON-part-2
CPU-RAM-MON-part-3

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more