kopia lustrzana https://github.com/Yakifo/amqtt
adding memory and cpu display to test.amqtt.io dashboard
rodzic
57597dfea4
commit
fab7c36d86
|
@ -1,4 +1,17 @@
|
|||
import React from "react";
|
||||
|
||||
export type DataPoint = {
|
||||
timestamp: string; // ISO format
|
||||
value: number;
|
||||
};
|
||||
|
||||
// Define the type for each entry in the topic_map
|
||||
export type TopicEntry<T> = {
|
||||
current: T;
|
||||
update: React.Dispatch<React.SetStateAction<T>>;
|
||||
};
|
||||
|
||||
// Define the topic_map type
|
||||
export type TopicMap = {
|
||||
[topic: string]: TopicEntry<DataPoint[]>;
|
||||
};
|
|
@ -7,7 +7,7 @@ import SessionsChart from './SessionsChart';
|
|||
import {useEffect, useState} from "react";
|
||||
// @ts-ignore
|
||||
import useMqtt from '../../assets/usemqtt';
|
||||
import type {DataPoint} from '../../assets/helpers';
|
||||
import type {DataPoint, TopicMap} from '../../assets/helpers';
|
||||
import {Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow} from "@mui/material";
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'
|
||||
import {faGithub, faPython, faDocker, faDiscord} from "@fortawesome/free-brands-svg-icons";
|
||||
|
@ -23,6 +23,8 @@ export default function MainGrid() {
|
|||
const [clientsConnected, setClientsConnected] = useState<DataPoint[]>([]);
|
||||
const [serverStart, setServerStart] = useState<string>('');
|
||||
const [serverUptime, setServerUptime] = useState<string>('');
|
||||
const [cpuPercent, setCpuPercent] = useState<DataPoint[]>([]);
|
||||
const [memSize, setMemSize] = useState<DataPoint[]>([]);
|
||||
|
||||
function getRandomInt(min: number, max: number) {
|
||||
min = Math.ceil(min);
|
||||
|
@ -65,9 +67,21 @@ export default function MainGrid() {
|
|||
mqttSubscribe('$SYS/broker/uptime/formatted');
|
||||
mqttSubscribe('$SYS/broker/uptime');
|
||||
mqttSubscribe('$SYS/broker/clients/connected');
|
||||
mqttSubscribe('$SYS/broker/cpu/percent');
|
||||
mqttSubscribe('$SYS/broker/heap/size')
|
||||
}
|
||||
}, [isConnected, mqttSubscribe]);
|
||||
|
||||
const topic_map: TopicMap = {
|
||||
'$SYS/broker/messages/publish/sent': { current: sent, update: setSent },
|
||||
'$SYS/broker/messages/publish/received': { current: received, update: setReceived },
|
||||
'$SYS/broker/load/bytes/received': { current: bytesIn, update: setBytesIn },
|
||||
'$SYS/broker/load/bytes/sent': { current: bytesOut, update: setBytesOut },
|
||||
'$SYS/broker/clients/connected': { current: clientsConnected, update: setClientsConnected },
|
||||
'$SYS/broker/cpu/percent': { current: cpuPercent, update: setCpuPercent},
|
||||
'$SYS/broker/heap/size': { current: memSize, update: setMemSize}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
while (messageQueue.current.length > 0) {
|
||||
|
@ -75,37 +89,14 @@ export default function MainGrid() {
|
|||
try {
|
||||
|
||||
const d = payload.message;
|
||||
if (payload.topic === '$SYS/broker/messages/publish/sent') {
|
||||
|
||||
if(payload.topic in topic_map) {
|
||||
const { update } = topic_map[payload.topic];
|
||||
const newPoint: DataPoint = {
|
||||
timestamp: new Date().toISOString(),
|
||||
value: d
|
||||
};
|
||||
setSent(sent => [...sent, newPoint]);
|
||||
} else if (payload.topic === '$SYS/broker/messages/publish/received') {
|
||||
const newPoint: DataPoint = {
|
||||
timestamp: new Date().toISOString(),
|
||||
value: d
|
||||
}
|
||||
setReceived(received => [...received, newPoint]);
|
||||
} else if (payload.topic === '$SYS/broker/load/bytes/received') {
|
||||
const newPoint: DataPoint = {
|
||||
timestamp: new Date().toISOString(),
|
||||
value: d
|
||||
}
|
||||
setBytesIn(bytesIn => [...bytesIn, newPoint]);
|
||||
} else if (payload.topic === '$SYS/broker/load/bytes/sent') {
|
||||
const newPoint: DataPoint = {
|
||||
timestamp: new Date().toISOString(),
|
||||
value: d
|
||||
}
|
||||
setBytesOut(bytesOut => [...bytesOut, newPoint]);
|
||||
} else if (payload.topic === '$SYS/broker/clients/connected') {
|
||||
const newPoint: DataPoint = {
|
||||
timestamp: new Date().toISOString(),
|
||||
value: d
|
||||
}
|
||||
setClientsConnected(clientsConnected => [...clientsConnected, newPoint]);
|
||||
|
||||
update(current => [...current, newPoint])
|
||||
} else if (payload.topic === '$SYS/broker/uptime/formatted') {
|
||||
const dt = new Date(d + "Z");
|
||||
setServerStart(dt.toLocaleString());
|
||||
|
@ -235,10 +226,10 @@ export default function MainGrid() {
|
|||
<strong>up for</strong> {serverUptime}
|
||||
</Grid>
|
||||
<Grid size={{xs: 12, md: 6}}>
|
||||
<SessionsChart title={'Sent Messages'} label={'Messages'} data={sent} isConnected={isConnected}/>
|
||||
<SessionsChart title={'Sent Messages'} label={''} data={sent} isConnected={isConnected}/>
|
||||
</Grid>
|
||||
<Grid size={{xs: 12, md: 6}}>
|
||||
<SessionsChart title={'Received Messages'} label={'Messages'} data={received} isConnected={isConnected}/>
|
||||
<SessionsChart title={'Received Messages'} label={''} data={received} isConnected={isConnected}/>
|
||||
</Grid>
|
||||
<Grid size={{xs: 12, md: 6}}>
|
||||
<SessionsChart title={'Bytes Out'} label={'Bytes'} data={bytesOut} isConnected={isConnected}/>
|
||||
|
@ -249,6 +240,16 @@ export default function MainGrid() {
|
|||
<Grid size={{xs: 12, md: 6}}>
|
||||
<SessionsChart title={'Clients Connected'} label={''} data={clientsConnected} isConnected={isConnected}/>
|
||||
</Grid>
|
||||
<Grid size={{xs: 12, md: 6}}>
|
||||
<Grid container spacing={2} columns={2}>
|
||||
<Grid size={{lg:1}}>
|
||||
<SessionsChart title={'CPU'} label={'%'} data={cpuPercent} decimals={2} isConnected={isConnected}/>
|
||||
</Grid>
|
||||
<Grid size={{lg:1}}>
|
||||
<SessionsChart title={'Memory'} label={'MB'} data={memSize} decimals={1} isConnected={isConnected}/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid container spacing={2} columns={12}>
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import { useTheme } from '@mui/material/styles';
|
||||
import Card from '@mui/material/Card';
|
||||
import CardContent from '@mui/material/CardContent';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Stack from '@mui/material/Stack';
|
||||
import { LineChart } from '@mui/x-charts/LineChart';
|
||||
import CountUp from 'react-countup';
|
||||
import type { DataPoint } from '../../assets/helpers.jsx';
|
||||
import {CircularProgress} from "@mui/material";
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import Card from '@mui/material/Card';
|
||||
import CardContent from '@mui/material/CardContent';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Stack from '@mui/material/Stack';
|
||||
import { LineChart } from '@mui/x-charts/LineChart';
|
||||
import CountUp from 'react-countup';
|
||||
import type { DataPoint } from '../../assets/helpers.jsx';
|
||||
import {CircularProgress} from "@mui/material";
|
||||
|
||||
const currentTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
const currentTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
|
||||
function formatDate(date: Date) {
|
||||
function formatDate(date: Date) {
|
||||
|
||||
return date.toLocaleTimeString('en-US', {
|
||||
timeZone: currentTimeZone,
|
||||
|
@ -19,10 +19,10 @@ function formatDate(date: Date) {
|
|||
second: '2-digit',
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function AreaGradient({ color, id }: { color: string; id: string }) {
|
||||
function AreaGradient({ color, id }: { color: string; id: string }) {
|
||||
return (
|
||||
<defs>
|
||||
<linearGradient id={id} x1="50%" y1="0%" x2="50%" y2="100%">
|
||||
|
@ -31,9 +31,9 @@ function AreaGradient({ color, id }: { color: string; id: string }) {
|
|||
</linearGradient>
|
||||
</defs>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function NoDataDisplay(props: any) {
|
||||
function NoDataDisplay(props: any) {
|
||||
return <>
|
||||
{!props.isConnected ? <div style={{height: 250, width: 600, paddingTop: 50}}>
|
||||
<Typography component="h2" variant="subtitle2" gutterBottom>
|
||||
|
@ -49,9 +49,9 @@ function NoDataDisplay(props: any) {
|
|||
</div>}
|
||||
</>
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function LinearChart(props: any) {
|
||||
function LinearChart(props: any) {
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
|
@ -63,6 +63,8 @@ function LinearChart(props: any) {
|
|||
|
||||
const label: string = props.label || '--';
|
||||
|
||||
const baseline: number = props.baseline || 0;
|
||||
|
||||
return <LineChart
|
||||
colors={colorPalette}
|
||||
xAxis={[
|
||||
|
@ -84,10 +86,12 @@ function LinearChart(props: any) {
|
|||
area: true,
|
||||
stackOrder: 'ascending',
|
||||
data: props.data.map( (dp:DataPoint) => dp.value),
|
||||
baseline: baseline
|
||||
}
|
||||
]}
|
||||
height={175}
|
||||
margin={{ left: 50, right: 20, top: 20, bottom: 20 }}
|
||||
|
||||
margin={{ left: 0, right: 20, top: 20, bottom: 20 }}
|
||||
grid={{ horizontal: true }}
|
||||
sx={{
|
||||
'& .MuiAreaElement-series-organic': {
|
||||
|
@ -109,9 +113,9 @@ function LinearChart(props: any) {
|
|||
|
||||
<AreaGradient color={theme.palette.primary.main} id="direct" />
|
||||
</LineChart>
|
||||
}
|
||||
}
|
||||
|
||||
export default function SessionsChart(props: any) {
|
||||
export default function SessionsChart(props: any) {
|
||||
|
||||
return (
|
||||
<Card variant="outlined" sx={{ width: '100%' }}>
|
||||
|
@ -134,14 +138,17 @@ export default function SessionsChart(props: any) {
|
|||
<CountUp
|
||||
start={props.data[props.data.length - 2].value}
|
||||
end={props.data[props.data.length - 1].value}
|
||||
duration={5}/>}
|
||||
duration={5}
|
||||
decimals={props.decimals}
|
||||
|
||||
/>} {props.label}
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Stack>
|
||||
{ props.data.length < 2 ? <NoDataDisplay isConnected={props.isConnected}/> :
|
||||
<LinearChart {...props} /> }
|
||||
<LinearChart { ...props} baseline={props.data[0].value} /> }
|
||||
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue