Files
next-terminal/web/src/components/dashboard/Monitoring.js
2022-10-23 20:05:13 +08:00

354 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from 'react';
import {Space, Tooltip} from "antd";
import {DualAxes, Liquid} from '@ant-design/plots';
import {ProCard, StatisticCard} from '@ant-design/pro-components';
import dayjs from "dayjs";
import {renderSize} from "../../utils/utils";
import {Area} from "@ant-design/charts";
import './Monitoring.css'
import {renderWeekDay} from "../../utils/week";
import {useQuery} from "react-query";
import monitorApi from "../../api/monitor";
const {Statistic} = StatisticCard;
const renderLoad = (percent) => {
if (percent >= 0.9) {
return '堵塞';
} else if (percent >= 0.8) {
return '缓慢';
} else if (percent >= 0.7) {
return '正常';
} else {
return '流畅';
}
}
const initData = {
loadStat: {
load1: 0, load5: 0, load15: 0, percent: 0
},
mem: {
total: 0,
available: 0,
usedPercent: 0
},
cpu: {
count: 0,
usedPercent: 0,
info: [{
'modelName': ''
}]
},
disk: {
total: 0,
available: 0,
usedPercent: 0
},
diskIO: [], netIO: [], cpuStat: [], memStat: [],
}
const Monitoring = () => {
let monitorQuery = useQuery('getMonitorData', monitorApi.getData, {
initialData: initData,
refetchInterval: 5
});
let loadPercent = monitorQuery.data?.loadStat['percent'];
let loadColor = '#5B8FF9';
if (loadPercent > 0.9) {
loadColor = '#F4664A';
} else if (loadPercent > 0.8) {
loadColor = '#001D70';
} else if (loadPercent > 0.7) {
loadColor = '#0047A5';
}
const loadStatConfig = {
height: 100,
width: 100,
shape: function (x, y, width, height) {
const r = width / 4;
const dx = x - width / 2;
const dy = y - height / 2;
return [
['M', dx, dy + r * 2],
['A', r, r, 0, 0, 1, x, dy + r],
['A', r, r, 0, 0, 1, dx + width, dy + r * 2],
['L', x, dy + height],
['L', dx, dy + r * 2],
['Z'],
];
},
percent: loadPercent,
outline: {
border: 4, distance: 4,
},
wave: {
length: 64,
},
theme: {
styleSheet: {
brandColor: loadColor,
},
},
statistic: {
title: false, content: false
},
pattern: {
type: 'square',
},
};
let cpuPercent = monitorQuery.data?.cpu['usedPercent'] / 100;
let cpuColor = '#5B8FF9';
if (cpuPercent > 0.9) {
cpuColor = '#F4664A';
} else if (cpuPercent > 0.8) {
cpuColor = '#001D70';
}
const cpuStatConfig = {
height: 100,
width: 100,
shape: 'diamond',
percent: cpuPercent,
outline: {
border: 4, distance: 4,
},
wave: {
length: 64,
},
theme: {
styleSheet: {
brandColor: cpuColor,
},
},
pattern: {
type: 'line',
},
statistic: {
title: false, content: false
}
};
let memPercent = monitorQuery.data?.mem['usedPercent'] / 100;
let memColor = '#5B8FF9';
if (memPercent > 0.75) {
memColor = '#F4664A';
}
const memStatConfig = {
height: 100,
width: 100,
percent: memPercent,
outline: {
border: 4, distance: 4,
},
wave: {
length: 64,
},
theme: {
styleSheet: {
brandColor: memColor,
},
},
statistic: {
title: false, content: false
},
pattern: {
type: 'dot',
},
};
let diskPercent = monitorQuery.data?.disk['usedPercent'] / 100;
let diskColor = '#5B8FF9';
if (diskPercent > 0.9) {
diskColor = '#F4664A';
} else if (diskPercent > 0.8) {
diskColor = '#001D70';
}
const diskStatConfig = {
height: 100,
width: 100,
shape: 'rect',
percent: diskPercent,
outline: {
border: 4, distance: 4,
},
wave: {
length: 64,
},
theme: {
styleSheet: {
brandColor: diskColor,
},
},
pattern: {
type: 'line',
},
statistic: {
title: false, content: false
}
};
const diskIOConfig = {
height: 150,
data: [monitorQuery.data['diskIO'], monitorQuery.data['diskIO']],
xField: 'time',
yField: ['read', 'write'],
meta: {
read: {
alias: '读取MB/s',
}, write: {
alias: '写入MB/s'
}
},
geometryOptions: [{
geometry: 'line', color: '#5B8FF9', smooth: true,
}, {
geometry: 'line', color: '#5AD8A6', smooth: true,
},],
};
const netIOConfig = {
height: 150,
data: [monitorQuery.data['netIO'], monitorQuery.data['netIO']],
xField: 'time',
yField: ['read', 'write'],
meta: {
read: {
alias: '接收MB/s',
}, write: {
alias: '发送MB/s'
}
},
geometryOptions: [{
geometry: 'line', color: '#5B8FF9', smooth: true,
}, {
geometry: 'line', color: '#5AD8A6', smooth: true,
},],
};
const cpuConfig = {
height: 150, data: monitorQuery.data['cpuStat'], xField: 'time', yField: 'value', smooth: true, areaStyle: {
fill: '#d6e3fd',
},
};
const memConfig = {
height: 150, data: monitorQuery.data['memStat'], xField: 'time', yField: 'value', smooth: true, areaStyle: {
fill: '#d6e3fd',
},
};
const cpuModelName = monitorQuery.data['cpu']['info'][0]['modelName'].length > 10 ? monitorQuery.data['cpu']['info'][0]['modelName'].substring(0, 10) + '...' : monitorQuery.data['cpu']['info'][0]['modelName'];
return (<>
<div style={{margin: 16}}>
<ProCard
title="系统监控"
extra={dayjs().format("YYYY[年]MM[月]DD[日]") + ' ' + renderWeekDay(dayjs().day())}
split={'horizontal'}
headerBordered
bordered
>
<ProCard split={'vertical'}>
<ProCard>
<StatisticCard
statistic={{
title: '负载',
value: renderLoad(monitorQuery.data['loadStat']['percent']),
description: <Space direction="vertical" size={1}>
<Statistic title="Load1" value={monitorQuery.data['loadStat']['load1'].toFixed(2)}/>
<Statistic title="Load5" value={monitorQuery.data['loadStat']['load5'].toFixed(2)}/>
<Statistic title="Load15"
value={monitorQuery.data['loadStat']['load15'].toFixed(2)}/>
</Space>,
}}
chart={<Liquid {...loadStatConfig} />}
chartPlacement="left"
/>
<StatisticCard
statistic={{
title: 'CPU',
value: monitorQuery.data['cpu']['count'],
suffix: '个',
description: <Space direction="vertical" size={1}>
<Statistic title="利用率"
value={monitorQuery.data['cpu']['usedPercent'].toFixed(2) + '%'}/>
<Statistic title="物理核数"
value={monitorQuery.data['cpu']['phyCount'] + ' 个'}/>
<Tooltip title={monitorQuery.data['cpu']['info'][0]['modelName']}>
<Statistic title="型号" value={cpuModelName}/>
</Tooltip>
</Space>,
}}
chart={<Liquid {...cpuStatConfig} />}
chartPlacement="left"
/>
</ProCard>
<ProCard>
<StatisticCard
statistic={{
title: '内存',
value: renderSize(monitorQuery.data['mem']['total']),
description: <Space direction="vertical" size={1}>
<Statistic title="利用率"
value={monitorQuery.data['mem']['usedPercent'].toFixed(2) + '%'}/>
<Statistic title="可用的"
value={renderSize(monitorQuery.data['mem']['available'])}/>
<Statistic title="已使用" value={renderSize(monitorQuery.data['mem']['used'])}/>
</Space>,
}}
chart={<Liquid {...memStatConfig} />}
chartPlacement="left"
/>
<StatisticCard
statistic={{
title: '硬盘',
value: renderSize(monitorQuery.data['disk']['total']),
description: <Space direction="vertical" size={1}>
<Statistic title="利用率"
value={monitorQuery.data['disk']['usedPercent'].toFixed(2) + '%'}/>
<Statistic title="剩余的"
value={renderSize(monitorQuery.data['disk']['available'])}/>
<Statistic title="已使用" value={renderSize(monitorQuery.data['disk']['used'])}/>
</Space>,
}}
chart={<Liquid {...diskStatConfig} />}
chartPlacement="left"
/>
</ProCard>
</ProCard>
<ProCard split={'vertical'}>
<ProCard title="CPU负载">
<Area {...cpuConfig} />
</ProCard>
<ProCard title="内存负载">
<Area {...memConfig} />
</ProCard>
</ProCard>
<ProCard split={'vertical'}>
<ProCard title="网络吞吐">
<DualAxes onlyChangeData={true} {...netIOConfig} />
</ProCard>
<ProCard title="磁盘IO">
<DualAxes onlyChangeData={true} {...diskIOConfig} />
</ProCard>
</ProCard>
</ProCard>
</div>
</>);
}
export default Monitoring;