I realized this simple system monitor project
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
Npm init
npm init
then create the folders structure
mkdir views public public/css public/js
then create the files
touch main.js views/index.ejs public/css/main.css public/js/main.js
Install dependencies
npm i express socket.io node-os-utils ejs
Run Visual studio code
code .
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"
}
}
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}`)
});
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>
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} %`
});
};
});
};
};
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;
}
}
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
Top comments (0)