Skip to content

Commit fe593b3

Browse files
committed
created socket for cpu utilsation and also plotting it on the frontend with bargraph
1 parent 313be2b commit fe593b3

File tree

12 files changed

+156
-18
lines changed

12 files changed

+156
-18
lines changed

backend/package-lock.json

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"typescript": "^5.4.5"
3030
},
3131
"dependencies": {
32+
"@types/pidusage": "^2.0.5",
3233
"cors": "^2.8.5",
3334
"dotenv": "^16.4.5",
3435
"nodemon": "^3.1.3",

backend/src/helpers/helpers.ts

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import os from 'os'
22
import si from 'systeminformation'
33

4-
import { isRamUtil, isSwapUtil } from '../types/types'
4+
import { isCpuUtil, isRamUtil, isSwapUtil, isError } from '../types/types'
55

66
let limit: number = 10
77

88
let idx: number = 0
99

1010
let RAM: isRamUtil[] = []
1111
let SWAP: isSwapUtil[] = []
12+
let CPU: isCpuUtil[] = []
1213

1314
// CALCULATING RAM UTILISATION
1415
export const calculateRamUtil = (): isRamUtil[] => {
@@ -63,4 +64,26 @@ export const calculateSwapUtil = async () => {
6364

6465
}
6566

67+
}
68+
69+
// CALCULATE CPU UTILISATION FOR EACH CORE
70+
export const calculateCpuUtil = async (): Promise<isCpuUtil[] | isError> => {
71+
72+
const cpuInfo = os.cpus()
73+
const numCores = cpuInfo.length
74+
75+
try {
76+
77+
const load = await si.currentLoad()
78+
const coresUsage = load.cpus.map((cpu, index) => ({
79+
core: index,
80+
load: cpu.load
81+
}));
82+
83+
return coresUsage
84+
85+
} catch (error: any) {
86+
return { message: error }
87+
}
88+
6689
}

backend/src/server.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import cors from 'cors';
44
import { Server as socketServer } from 'socket.io';
55
import { createServer } from 'http';
66
import router from './routes/routes'
7-
import { calculateRamUtil } from './helpers/helpers';
7+
import { calculateRamUtil, calculateCpuUtil } from './helpers/helpers';
88

99
// load the .env file
1010
dotenv.config();
@@ -39,6 +39,8 @@ const server = new socketServer(httpServer, {
3939
server.on("connection", (socket) => {
4040
console.log("socket connected");
4141

42+
// ______________MAIN FUNCTIONS______________
43+
4244
// RAM
4345
const ramInterval = setInterval(() => {
4446
try {
@@ -49,9 +51,23 @@ server.on("connection", (socket) => {
4951
}
5052
}, 1000);
5153

54+
// CPU
55+
56+
const cpuInterval = setInterval(async () => {
57+
try{
58+
const cpuUsage = await calculateCpuUtil()
59+
socket.emit("cpuUsage", cpuUsage)
60+
}catch(error){
61+
console.error('Error calculating CPU usage:', error);
62+
}
63+
}, 1000)
64+
65+
// ______________CLEAN UP______________
66+
5267
// CLEAR INTERVALS ON DISCONNECTS
5368
socket.on("disconnect", () => {
5469
clearInterval(ramInterval);
70+
clearInterval(cpuInterval);
5571
console.log("socket disconnected");
5672
});
5773

backend/src/types/types.ts

+9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ export type isSwapUtil = {
88
x: number
99
}
1010

11+
export type isCpuUtil = {
12+
core: number;
13+
load: number
14+
}
15+
1116
export type isRamStat = {
1217
totalRam: number;
1318
minRam: number;
@@ -18,4 +23,8 @@ export type isSwapStat = {
1823
totalSwap: number;
1924
minSwap: number;
2025
freeSwap: number;
26+
}
27+
28+
export type isError = {
29+
message: string;
2130
}

frontend/src/App.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import React from 'react'
22
import RamUtil from './sockets/RamUtil'
3+
import CpuUtil from './sockets/CpuUtil'
34

45
import classes from './App.module.css'
56

67
const App: React.FC = () => {
78
return (
89
<div className={classes.parent}>
910
<RamUtil />
11+
<CpuUtil />
1012
</div>
1113
)
1214
}

frontend/src/graphs/AreaChartGraph.tsx

+2-8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
import React from 'react';
2-
import { AreaChart, XAxis, YAxis, CartesianGrid, Tooltip, Area, LineChart, Legend, Line, ResponsiveContainer } from 'recharts'
2+
import { AreaChartProps } from '../types/types';
3+
import { AreaChart, XAxis, YAxis, CartesianGrid, Tooltip, Area, Legend, ResponsiveContainer } from 'recharts'
34

45
import Wrapper from '../shared/Wrapper';
56

6-
// INTERFACE
7-
interface AreaChartProps {
8-
data: { name: string, x: number }[];
9-
dataLabel : string
10-
}
11-
127
// COMPONENT
138
const AreaChartGraph: React.FC<AreaChartProps> = ({ data, dataLabel}) => {
149
return (
@@ -29,7 +24,6 @@ const AreaChartGraph: React.FC<AreaChartProps> = ({ data, dataLabel}) => {
2924
<Area name={dataLabel} type="monotone" dataKey="x" stroke="#4CAF50" fillOpacity={1} fill="url(#colorUv)" />
3025
</AreaChart>
3126
</ResponsiveContainer>
32-
3327
</Wrapper>
3428
)
3529
}

frontend/src/graphs/BarChartGraph.tsx

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from 'react'
2+
import { BarChartProps } from '../types/types'
3+
import {ResponsiveContainer, BarChart, CartesianGrid, XAxis, YAxis, Tooltip, Legend, Bar} from 'recharts'
4+
5+
import Wrapper from '../shared/Wrapper';
6+
7+
const BarChartGraph: React.FC<BarChartProps> = ({ data, dataLabel }) => {
8+
return (
9+
<Wrapper>
10+
<ResponsiveContainer width="100%" height="100%">
11+
<BarChart data={data} style={{ backgroundColor: '#2b2b3d' }} margin={{ top: 25, right: 25, left: 0, bottom: 0 }}>
12+
<CartesianGrid strokeDasharray="2 2" stroke="rgba(204, 204, 204, 0.5)"/>
13+
<XAxis dataKey="core" stroke="#ccc"/>
14+
<YAxis stroke="#ccc"/>
15+
<Tooltip />
16+
<Legend />
17+
<Bar name={dataLabel} dataKey="load" fill="#8884d8" />
18+
</BarChart>
19+
</ResponsiveContainer>
20+
</Wrapper>
21+
)
22+
}
23+
24+
export default BarChartGraph

frontend/src/sockets/CpuUtil.tsx

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React, { useState, useEffect } from 'react'
2+
import socketIOClient from 'socket.io-client'
3+
4+
import BarChartGraph from '../graphs/BarChartGraph';
5+
import Spinner from '../shared/Spinner';
6+
import { isCpuUtil } from '../types/types';
7+
8+
import classes from './shared.module.css'
9+
10+
const CpuUtil: React.FC = () => {
11+
12+
const [data, setData] = useState<isCpuUtil[]>([])
13+
const [isLoading, setIsLoading] = useState<boolean>(true);
14+
15+
// connect the socket
16+
useEffect(() => {
17+
18+
const socket = socketIOClient("http://192.167.0.119:4001/");
19+
20+
socket.on("cpuUsage", (data: isCpuUtil[]) => {
21+
setData(data);
22+
setIsLoading(false)
23+
});
24+
25+
socket.on("disconnect", () => {
26+
setIsLoading(true)
27+
})
28+
29+
// Clean up the socket connection when the component unmounts
30+
return () => {
31+
setIsLoading(true)
32+
socket.disconnect();
33+
};
34+
35+
}, [])
36+
37+
return (
38+
<div className={classes.parent}>
39+
<h1>CPU Utilization</h1>
40+
{isLoading && <Spinner />}
41+
{!isLoading && <BarChartGraph data={data} dataLabel="CPU Core Utilization"/>}
42+
</div>
43+
)
44+
}
45+
46+
export default CpuUtil

frontend/src/sockets/RamUtil.tsx

+6-8
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,9 @@ import socketIOClient from "socket.io-client";
33

44
import AreaChartGraph from '../graphs/AreaChartGraph';
55
import Spinner from '../shared/Spinner';
6+
import { isRamUtil } from '../types/types';
67

7-
import classes from './RamUtil.module.css'
8-
9-
//INTERFACE
10-
interface isRamUtil {
11-
name: string;
12-
x: number;
13-
}
8+
import classes from './shared.module.css'
149

1510
// COMPONENT
1611
const RamUtil: React.FC = () => {
@@ -26,9 +21,12 @@ const RamUtil: React.FC = () => {
2621
socket.on("ramUsage", (data: isRamUtil[]) => {
2722
setData(data);
2823
setIsLoading(false)
29-
console.log(data)
3024
});
3125

26+
socket.on("disconnect", () => {
27+
setIsLoading(true)
28+
})
29+
3230
// Clean up the socket connection when the component unmounts
3331
return () => {
3432
setIsLoading(true)
File renamed without changes.

frontend/src/types/types.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export interface AreaChartProps {
2+
data: { name: string, x: number }[];
3+
dataLabel : string
4+
}
5+
6+
export interface BarChartProps {
7+
data: {core: number, load: number}[];
8+
dataLabel: string
9+
}
10+
11+
export interface isRamUtil {
12+
name: string;
13+
x: number;
14+
}
15+
16+
export interface isCpuUtil {
17+
core: number;
18+
load: number;
19+
}

0 commit comments

Comments
 (0)