123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- <template>
- <div>
- <div class="flex-row" style="gap: 16px; align-items: stretch;margin-bottom: 16px">
- <el-card shadow="nover" class="flex1">
- <div class="flex-row">
- <el-descriptions :column="1" border class="flex1">
- <el-descriptions-item label="CPU数">{{ sysInfo.cpuNum }}</el-descriptions-item>
- <el-descriptions-item label="核心数">{{ sysInfo.cpuCores }}</el-descriptions-item>
- <el-descriptions-item label="使用率">{{ sysInfo.cpuUsed }}%</el-descriptions-item>
- <el-descriptions-item label="LA5">{{ sysInfo.cpuAvg5 }}%</el-descriptions-item>
- <el-descriptions-item label="LA15">{{ sysInfo.cpuAvg15 }}%</el-descriptions-item>
- </el-descriptions>
- <div class="flex1">
- <VueUiGauge :dataset="dataset" :config="config" />
- </div>
- </div>
- </el-card>
- <el-card shadow="nover" class="flex1">
- <div class="flex-row">
- <el-descriptions :column="1" border class="flex1">
- <el-descriptions-item label="内存总数">{{ memorySizeFormat(sysInfo.memTotal) }}</el-descriptions-item>
- <el-descriptions-item label="已使用">{{ memorySizeFormat(sysInfo.memUsed) }}</el-descriptions-item>
- <el-descriptions-item label="剩余">{{ memorySizeFormat(sysInfo.available) }}</el-descriptions-item>
- <el-descriptions-item label="系统使用">{{ memorySizeFormat(sysInfo.goUsed) }}</el-descriptions-item>
- <el-descriptions-item label="使用率">{{ sysInfo.memUsage }}%</el-descriptions-item>
- </el-descriptions>
- <div class="flex1">
- <VueUiGauge :dataset="dataset2" :config="config2" />
- </div>
- </div>
- </el-card>
- <el-card shadow="nover" class="flex1">
- <div class="flex-row">
- <el-descriptions :column="1" border class="flex1">
- <el-descriptions-item label="磁盘容量">{{ memorySizeFormat(sysInfo.diskTotal) }}</el-descriptions-item>
- <el-descriptions-item label="已使用">{{ memorySizeFormat(sysInfo.diskUsed) }}</el-descriptions-item>
- <el-descriptions-item label="使用率">{{ sysInfo.diskUsedPercent }}%</el-descriptions-item>
- </el-descriptions>
- <div class="flex1">
- <VueUiGauge :dataset="dataset3" :config="config3" />
- </div>
- </div>
- </el-card>
- </div>
- <div class="flex-row" style="gap: 16px; align-items: stretch;margin-bottom: 16px">
- <el-card shadow="nover" class="flex1">
- <template #header>CPU运行情况</template>
- <VueUiXy :dataset="dataset4" :config="config4" />
- </el-card>
- <el-card shadow="nover" class="flex1">
- <template #header>内存运行情况</template>
- <VueUiXy :dataset="dataset5" :config="config5" />
- </el-card>
- <el-card shadow="nover" class="flex1">
- <template #header>磁盘使用情况</template>
- <VueUiXy :dataset="dataset6" :config="config6" />
- </el-card>
- </div>
- <el-card shadow="nover">
- <template #header>运行环境信息</template>
- <el-descriptions :column="3" border class="flex1">
- <el-descriptions-item label="操作系统">{{ hostData.os }}</el-descriptions-item>
- <el-descriptions-item label="系统架构">{{ goInfoData.arch }}</el-descriptions-item>
- <el-descriptions-item label="架构版本">{{ hostData.kernelArch }}</el-descriptions-item>
- <el-descriptions-item label="启动时间">{{ goInfoData.startTime }}</el-descriptions-item>
- <el-descriptions-item label="语言环境">{{ goInfoData.goName }}</el-descriptions-item>
- <el-descriptions-item label="GO 版本">{{ goInfoData.goVersion }}</el-descriptions-item>
- <el-descriptions-item label="运行时长">{{ timeFormat(goInfoData.runTime) }}</el-descriptions-item>
- <el-descriptions-item label="磁盘占用">{{ goInfoData.goSize }}</el-descriptions-item>
- <el-descriptions-item label="协程数量">{{ goInfoData.goroutine }}</el-descriptions-item>
- <el-descriptions-item label="运行内存">{{ goInfoData.goMem }}</el-descriptions-item>
- <el-descriptions-item label="项目地址">{{ goInfoData.pwd }}</el-descriptions-item>
- <el-descriptions-item label="服务器IP">{{ hostData.intranet_ip }} (内) {{ hostData.public_ip }} (公) </el-descriptions-item>
- </el-descriptions>
- </el-card>
- </div>
- </template>
- <script lang="ts" setup>
- import { ref, toRefs, reactive, onMounted, getCurrentInstance, defineComponent, onUnmounted } from 'vue';
- import * as echarts from 'echarts';
- import 'echarts-wordcloud';
- import dayjs from 'dayjs';
- import { getSSEOrigin } from '/@/utils/origin'
- import { VueUiGauge, VueUiXy } from "vue-data-ui";
- import "vue-data-ui/style.css";
- import { getGaugeData, getLine2Data } from "/@/utils/dataUiOptions";
- import { useThemeChange } from '/@/hooks/useCommon';
- import { deepClone } from '/@/utils/other';
- let interval: any = null;
- let es: any = null;
- const { proxy } = getCurrentInstance() as any;
- const sysInfo: any = reactive<any>({
- });
- const loading = ref(true)
- //#region 线图
- // 获取默认图形配置数据
- const chartData = getGaugeData({
- value: 0
- })
- const config = ref<any>(chartData.config);
- const config2 = ref<any>(chartData.config);
- const config3 = ref<any>(chartData.config);
- const dataset = ref<any>(chartData.dataset);
- const dataset2 = ref<any>(chartData.dataset);
- const dataset3 = ref<any>(chartData.dataset);
- const chartLineData = getLine2Data({
- xAxis: [],
- legend: [],
- datas: [[]]
- })
- const dataset4 = ref<any>(chartLineData.dataset);
- const config4 = ref<any>(chartLineData.config);
- const dataset5 = ref<any>(chartLineData.dataset);
- const config5 = ref<any>(chartLineData.config);
- const dataset6 = ref<any>(chartLineData.dataset);
- const config6 = ref<any>(chartLineData.config);
- // 监听暗黑模式变化,将 vue-data-ui 的 config 传进来,就能自动更新主题
- useThemeChange([config, config2, config3, config4, config5, config6])
- //#endregion
- let myChart4: any;
- let myChart5: any;
- let myChart6: any;
- const hostData = reactive({
- "bootTime": "2022-11-24T11:12:13+08:00",
- "hostId": "8be74718-1a53-4208-be22-9c126d891ddd",
- "hostname": "iZ2zee04uvnkmhvglw9oghZ",
- "intranet_ip": "172.17.47.62",
- "kernelArch": "x86_64",
- "kernelVersion": "3.10.0-1127.19.1.el7.x86_64",
- "os": "linux",
- "platform": "centos",
- "platformFamily": "rhel",
- "platformVersion": "7.7.1908",
- "procs": 138,
- "public_ip": "101.200.198.249",
- "uptime": 6393278,
- "virtualizationRole": "guest",
- "virtualizationSystem": ""
- });
- const goInfoData = reactive({
- "goOs": "-", "arch": "-", "goVersion": "-", "goMem": "-", "goName": "-", "goSize": "-", "goroutine": '-', "pwd": "-", "rootPath": "-",
- "runTime": '', "startTime": "-", "intranet_ip": "-"
- });
- function goInfo(event: { data: any; }) {
- const data = JSON.parse(event.data);
- Object.assign(goInfoData, data);
- loading.value = false
- }
- function hostInfo(event: { data: any; }) {
- const data = JSON.parse(event.data);
- Object.assign(hostData, data);
- loading.value = false
- }
- const myChart4Data: any = {
- name: [],
- value: [],
- }
- const myChart5Data: any = {
- name: [],
- value: [],
- }
- const myChart6Data: any = {
- name: [],
- value: [],
- }
- function setOptChart(dataset: any, config: any, myChartData: any, value: number, color = '') {
- myChartData.name.push(dayjs().format('mm:ss'));
- myChartData.value.push(value);
- if (myChartData.name.length > 10) {
- myChartData.name.shift()
- myChartData.value.shift()
- }
- const chartLineData = getLine2Data({
- xAxis: myChartData.name,
- legend: ['使用率'],
- suffix: '%',
- color,
- datas: [myChartData.value]
- })
- dataset.value = chartLineData.dataset
- config.value = chartLineData.config
- }
- // 页面加载时
- onMounted(() => {
- });
- function startWs() {
- es = new EventSource(getSSEOrigin("/subscribe/sysenv"));
- es.addEventListener("host", displayHost);
- es.addEventListener("mem", displayMem);
- es.addEventListener("cpu", displayCpu);
- es.addEventListener("sysLoad", displaySysLoad);
- es.addEventListener("disk", displayDisk);
- es.addEventListener("go", goInfo);
- es.addEventListener("host", hostInfo);
- }
- startWs();
- function displayHost(event: { data: any; }) {
- const data = JSON.parse(event.data);
- sysInfo.os = data.os
- sysInfo.kernelArch = data.kernelArch
- sysInfo.sysComputerName = data.hostname
- sysInfo.goStartTime = data.bootTime
- sysInfo.goRunTime = data.uptime
- loading.value = false
- }
- function displayMem(event: { data: any; }) {
- const data = JSON.parse(event.data);
- sysInfo.memTotal = data.total
- sysInfo.memUsed = data.used
- sysInfo.available = data.available
- sysInfo.goUsed = data.goUsed
- sysInfo.memUsage = Number(data.usedPercent.toFixed(2))
- dataset2.value = getGaugeData({ value: sysInfo.memUsage }).dataset
- setOptChart(dataset5, config5, myChart5Data, sysInfo.memUsage, '#56B5FF');
- loading.value = false
- }
- function displayCpu(event: { data: any; }) {
- const data = JSON.parse(event.data);
- sysInfo.cpuNum = data.Number
- sysInfo.cpuCores = data.Cores
- sysInfo.cpuUsed = Number(data.UsedPercent[0].toFixed(2))
- dataset.value = getGaugeData({ value: sysInfo.cpuUsed }).dataset
- setOptChart(dataset4, config4, myChart4Data, sysInfo.cpuUsed, '#4FE4F0');
- loading.value = false
- }
- function displaySysLoad(event: { data: any; }) {
- const data = JSON.parse(event.data)
- sysInfo.cpuAvg5 = data.load5.toFixed(2)
- sysInfo.cpuAvg15 = data.load15.toFixed(2)
- loading.value = false
- }
- function displayDisk(event: { data: any; }) {
- const data = JSON.parse(event.data)
- sysInfo.diskTotal = data.total
- sysInfo.diskUsed = data.used
- sysInfo.diskUsedPercent = Number(data.usedPercent.toFixed(2))
- dataset3.value = getGaugeData({ value: sysInfo.diskUsedPercent }).dataset
- setOptChart(dataset6, config6, myChart6Data, sysInfo.diskUsedPercent, '#7387F4');
- loading.value = false
- }
- const memorySizeFormat = (size: any) => {
- if (size === null || size === undefined) return ''
- size = parseFloat(size);
- let rank = 0;
- let rankchar = 'Bytes';
- while (size > 1024 && rankchar != 'TB') {
- size = size / 1024;
- rank++;
- if (rank == 1) {
- rankchar = 'KB';
- } else if (rank == 2) {
- rankchar = 'MB';
- } else if (rank == 3) {
- rankchar = 'GB';
- } else if (rank == 4) {
- rankchar = 'TB';
- }
- }
- return size.toFixed(2) + ' ' + rankchar;
- }
- const timeFormat = (second: any) => {
- if (!second) return '-'
- second = parseFloat(second);
- let rank = 0;
- let rankchar = '秒';
- while ((second > 60 && rankchar != '小时' && rankchar != '天') || (second > 24 && rankchar == '小时')) {
- if (rankchar == '小时') {
- second = second / 24;
- } else {
- second = second / 60;
- }
- rank++;
- if (rank == 1) {
- rankchar = '分';
- } else if (rank == 2) {
- rankchar = '小时';
- } else if (rank == 3) {
- rankchar = '天';
- }
- }
- return second.toFixed(2) + ' ' + rankchar;
- }
- onUnmounted(() => {
- if (interval) {
- clearInterval(interval);
- interval = null;
- }
- if (es) {
- es.close()
- }
- });
- </script>
- <style scoped lang="scss">
- .el-card {
- ::v-deep .el-card__body {
- height: 100%;
- .flex-row {
- height: 100%;
- }
- }
- }
- </style>
|