feat: 添加服务监控
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import { http } from "@/utils/http";
|
||||
import type { OperationLogInfo, UserLoginLogInfo } from "types/monitor";
|
||||
import type {
|
||||
OperationLogInfo,
|
||||
SystemMonitorInfo,
|
||||
UserLoginLogInfo
|
||||
} from "types/monitor";
|
||||
import { filterEmptyObject } from "./utils";
|
||||
|
||||
// --------------------------登录日志相关--------------------------------------
|
||||
@@ -46,3 +50,12 @@ export const getUserOperationsAPI = (params: {
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// ------------------------服务相关----------------------------------------
|
||||
|
||||
/**
|
||||
* 获取服务器信息
|
||||
*/
|
||||
export const getSystemMonitorInfoAPI = () => {
|
||||
return http.request<SystemMonitorInfo>("get", "/api/server");
|
||||
};
|
||||
|
||||
298
src/views/monitor/server/index.vue
Normal file
298
src/views/monitor/server/index.vue
Normal file
@@ -0,0 +1,298 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<el-row :gutter="30">
|
||||
<re-col :value="12" :xs="24" :sm="24">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="flex items-center justify-center">
|
||||
<IconifyIconOffline :icon="cpuIcon" />
|
||||
<span class="header-title">CPU</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-descriptions
|
||||
:column="2"
|
||||
border
|
||||
direction="vertical"
|
||||
:data="cpuData"
|
||||
class="centered-descriptions"
|
||||
>
|
||||
<el-descriptions-item
|
||||
v-for="item in cpuData"
|
||||
:key="item.attribute"
|
||||
:label="item.attribute"
|
||||
align="center"
|
||||
>
|
||||
{{ item.value }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</re-col>
|
||||
|
||||
<re-col :value="12" :xs="24" :sm="24">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="flex items-center justify-center">
|
||||
<IconifyIconOffline :icon="ticketsIcon" />
|
||||
<span class="header-title">内存</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-descriptions
|
||||
:column="4"
|
||||
border
|
||||
direction="vertical"
|
||||
:data="memoryData"
|
||||
class="centered-descriptions"
|
||||
>
|
||||
<el-descriptions-item
|
||||
v-for="item in memoryData"
|
||||
:key="item.attribute"
|
||||
:label="item.attribute"
|
||||
align="center"
|
||||
>
|
||||
{{ item.memory }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
v-for="item in memoryData"
|
||||
:key="item.attribute + '_python'"
|
||||
:label="'Python' + item.attribute"
|
||||
align="center"
|
||||
>
|
||||
{{ item.python }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</re-col>
|
||||
|
||||
<re-col :value="24" :xs="24" :sm="24">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="flex items-center justify-center">
|
||||
<IconifyIconOffline :icon="monitorIcon" />
|
||||
<span class="header-title">服务器信息</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-descriptions
|
||||
:column="4"
|
||||
direction="vertical"
|
||||
border
|
||||
:data="systemData"
|
||||
class="centered-descriptions"
|
||||
>
|
||||
<el-descriptions-item
|
||||
v-for="item in systemData"
|
||||
:key="item.attribute"
|
||||
:label="item.attribute"
|
||||
align="center"
|
||||
>
|
||||
{{ item.value }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</re-col>
|
||||
|
||||
<re-col :value="24" :xs="24" :sm="24">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="flex items-center justify-center">
|
||||
<IconifyIconOffline :icon="coffeeCupIcon" />
|
||||
<span class="header-title">Python解释器信息</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-descriptions
|
||||
:column="3"
|
||||
direction="vertical"
|
||||
border
|
||||
:data="pythonData"
|
||||
class="centered-descriptions"
|
||||
>
|
||||
<el-descriptions-item
|
||||
v-for="item in pythonData"
|
||||
:key="item.attribute"
|
||||
:label="item.attribute"
|
||||
align="center"
|
||||
>
|
||||
{{ item.value }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</re-col>
|
||||
|
||||
<re-col :value="24" :xs="24" :sm="24">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="flex items-center justify-center">
|
||||
<IconifyIconOffline :icon="messageBoxIcon" />
|
||||
<span class="header-title">磁盘信息</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="diskData" style="width: 100%">
|
||||
<el-table-column align="center" prop="dirName" label="盘符路径" />
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="sysTypeName"
|
||||
label="文件系统"
|
||||
/>
|
||||
<el-table-column align="center" prop="typeName" label="盘符名称" />
|
||||
<el-table-column align="center" prop="total" label="总大小" />
|
||||
<el-table-column align="center" prop="free" label="可用大小" />
|
||||
<el-table-column align="center" prop="used" label="已用大小" />
|
||||
<el-table-column align="center" prop="usage" label="已用百分比">
|
||||
<template #default="{ row }">
|
||||
<div :class="{ 'text-danger': Number(row.usage) > 80 }">
|
||||
{{ row.usage }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</re-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: "MonitorSystem"
|
||||
});
|
||||
import ReCol from "@/components/ReCol";
|
||||
import { reactive, onMounted, computed } from "vue";
|
||||
import { getSystemMonitorInfoAPI } from "@/api/monitor";
|
||||
import { SystemMonitorInfo } from "types/monitor";
|
||||
import cpuIcon from "@iconify-icons/ep/cpu";
|
||||
import ticketsIcon from "@iconify-icons/ep/tickets";
|
||||
import monitorIcon from "@iconify-icons/ep/monitor";
|
||||
import coffeeCupIcon from "@iconify-icons/ep/coffee-cup";
|
||||
import messageBoxIcon from "@iconify-icons/ep/message-box";
|
||||
|
||||
const server = reactive<SystemMonitorInfo>({
|
||||
cpu: {
|
||||
cpuNum: 0,
|
||||
free: 0,
|
||||
sys: 0,
|
||||
used: 0
|
||||
},
|
||||
memory: {
|
||||
free: "",
|
||||
usage: 0,
|
||||
total: "",
|
||||
used: ""
|
||||
},
|
||||
python: {
|
||||
free: "",
|
||||
usage: 0,
|
||||
total: "",
|
||||
used: "",
|
||||
name: "",
|
||||
version: "",
|
||||
startTime: "",
|
||||
runTime: "",
|
||||
home: ""
|
||||
},
|
||||
system: {
|
||||
computerIp: "",
|
||||
computerName: "",
|
||||
osArch: "",
|
||||
osName: "",
|
||||
userDir: ""
|
||||
},
|
||||
systemFiles: []
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const res = await getSystemMonitorInfoAPI();
|
||||
if (res.success) {
|
||||
Object.assign(server, res.data);
|
||||
}
|
||||
});
|
||||
|
||||
const cpuData = computed(() => [
|
||||
{ attribute: "核心数", value: server.cpu.cpuNum || "-" },
|
||||
{ attribute: "用户使用率", value: `${server.cpu.used || "-"}%` },
|
||||
{ attribute: "系统使用率", value: `${server.cpu.sys || "-"}%` },
|
||||
{ attribute: "当前空闲率", value: `${server.cpu.free || "-"}%` }
|
||||
]);
|
||||
|
||||
const memoryData = computed(() => [
|
||||
{
|
||||
attribute: "总内存",
|
||||
memory: server.memory.total || "-",
|
||||
python: server.python.total || "-"
|
||||
},
|
||||
{
|
||||
attribute: "已用内存",
|
||||
memory: server.memory.used || "-",
|
||||
python: server.python.used || "-"
|
||||
},
|
||||
{
|
||||
attribute: "剩余内存",
|
||||
memory: server.memory.free || "-",
|
||||
python: server.python.free || "-"
|
||||
},
|
||||
{
|
||||
attribute: "使用率",
|
||||
memory: `${server.memory.usage || "-"}%`,
|
||||
python: `${server.python.usage || "-"}%`
|
||||
}
|
||||
]);
|
||||
|
||||
const systemData = computed(() => [
|
||||
{ attribute: "服务器名称", value: server.system.computerName || "-" },
|
||||
{ attribute: "操作系统", value: server.system.osName || "-" },
|
||||
{ attribute: "服务器IP", value: server.system.computerIp || "-" },
|
||||
{ attribute: "系统架构", value: server.system.osArch || "-" }
|
||||
]);
|
||||
|
||||
const pythonData = computed(() => [
|
||||
{ attribute: "Python名称", value: server.python.name || "-" },
|
||||
{ attribute: "Python版本", value: server.python.version || "-" },
|
||||
{ attribute: "启动时间", value: server.python.startTime || "-" },
|
||||
{ attribute: "运行时长", value: server.python.runTime || "-" },
|
||||
{ attribute: "安装路径", value: server.python.home || "-" },
|
||||
{ attribute: "项目路径", value: server.system.userDir || "-" }
|
||||
]);
|
||||
|
||||
const diskData = computed(() =>
|
||||
(server.systemFiles || []).map(sysFile => ({
|
||||
dirName: sysFile.dirName,
|
||||
sysTypeName: sysFile.sysTypeName,
|
||||
typeName: sysFile.typeName,
|
||||
total: sysFile.total,
|
||||
free: sysFile.free,
|
||||
used: sysFile.used,
|
||||
usage: sysFile.usage
|
||||
}))
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
margin-left: 0.5em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.centered-descriptions {
|
||||
:deep(.el-descriptions-item__container) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
:deep(.el-descriptions-item__label) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
:deep(.el-descriptions-item__content) {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user