django-vue-admin/dvadmin-ui/src/views/vadmin/monitor/server/index.vue

486 lines
14 KiB
Vue
Executable File
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="app-container">
<!-- 监控控制 -->
<div class="server-monitor-control">
<!-- 监控启用开关 -->
<div class="control-server-monitor same-block">
开启监控
<el-switch
v-model="isOpeningMonitor"
active-color="#13ce66"
inactive-color="#ff4949"
title="控制所有监控项"
@change="changeMonitorStatus"
>
</el-switch>
</div>
<!-- 更新频率设置 -->
<div class="monitor-update-interval same-block">
监控频率:
<el-input-number v-model="monitorUpdateInterval"
label=""
class="monitor-update-interval-blank"
controls-position="right"
:min="minMonitorUpdateInterval"
@input="handleIntervalChange"
></el-input-number>
<el-select v-model="intervalType"
class="monitor-update-interval-unit"
@change="selectIntervalType"
>
<el-option
v-for="item in Object.keys(INTERVAL_ID_TO_TYPE_MAPPING)"
:key="INTERVAL_ID_TO_TYPE_MAPPING[item].type"
:label="INTERVAL_ID_TO_TYPE_MAPPING[item].name"
:value="INTERVAL_ID_TO_TYPE_MAPPING[item].name">
</el-option>
</el-select>
</div>
<!-- 监控日志保存时间 -->
<div class="monitor-log-save-time same-block">
保存天数:
<el-input v-model="monitorLogSavingDays" class=" same-block" style="width: 120px;"></el-input>
<el-button type="primary"
class="same-block"
title="只有提交更改才会生效"
@click="updateMonitorStatusSettingsInfo"
>更改
</el-button>
</div>
<!-- 清空记录 -->
<div class="clean-monitor-log same-block">
<el-button class="same-block"
type="warning"
title="清空所有监控记录"
@click="cleanMonitorLogsInfo"
>清空记录
</el-button>
</div>
</div>
<div class="server-monitor-top">
<!-- 左侧服务器信息 -->
<el-card class="box-card server-information">
<div slot="header" class="clearfix">
<div class="server-info-item">服务器</div>
<el-select filterable
v-model="currentServerName"
class="server-info-item"
placeholder="请选择服务器"
@change="chooseServerInfo"
>
<el-option
v-for="(item,index) in allServerInfo"
:key="item.id"
:label="item.name"
:value="index"
>
</el-option>
</el-select>
<el-button type="primary"
class="server-info-item"
title="只有提交更改才会生效"
@click="updateServerInfo"
>更改
</el-button>
</div>
<div class="server-info-detail">
<div v-for="(key,index) in currentServerInfoKeys" :key="index" class="server-info-detail-line text item">
<div class="server-info-detail-item">
<div style="width: 30%;display: inline-block;">{{ SERVER_KEY_TO_NAME_MAPPING[key] }}:</div>
<div v-if="CHANGEABLE_SERVER_FIELDS.indexOf(key) > -1" style="display: inline-block;">
<el-input style="display: inline-block; width: 90%;" v-model="currentServer[key]"></el-input>
</div>
<div v-else style="display: inline-block; "> {{ currentServer[key] }}</div>
</div>
</div>
</div>
</el-card>
<!-- 右侧仪表盘 -->
<el-card class="box-card information-instrument-panel"
v-for="(key, index) of Object.keys(instrumentBoardData)"
:key="`${index}-${key}`">
<instrument-board
:show-top-title="true"
:show-sub-title="true"
:ring-graph-key="key"
:instrument-board-data="instrumentBoardData[key]"
:top-title-key-to-name-mapping="INSTRUMENT_BOARD_KEY_TO_NAME_MAPPING"
></instrument-board>
</el-card>
</div>
<!-- 下方折线图 -->
<div class="server-monitor-bottom">
<!-- 折线图 -->
<el-card class="box-card server-monitor-line-chart" v-for="(key, index) in Object.keys(lineChartData)"
:key="`${index}-${key}`">
<line-chart :line-chart-key="key"
:server-info="currentServer"
:chart-title="CHART_KEY_NAME_MAPPING[key]"
:chart-data="lineChartData[key]"
></line-chart>
</el-card>
</div>
</div>
</template>
<script>
import {
cleanMonitorLog,
getMonitorLogs,
getMonitorStatusInfo,
getServerLatestLog,
getServerList,
updateMonitorStatusInfo,
updateServerInfo
} from '@/api/vadmin/monitor/server'
import InstrumentBoard from '@/views/vadmin/monitor/server/components/InstrumentBoard'
import LineChart from '@/views/vadmin/monitor/server/components/LineChart'
import moment from 'moment'
const debounce = require('lodash/debounce')
// 要展示的信息key -> name
const SERVER_KEY_TO_NAME_MAPPING = {
ip: '服务器IP',
name: '服务器名称',
os: '操作系统',
remark: '备注'
}
// 更新频率类型映射
const INTERVAL_ID_TO_TYPE_MAPPING = {
0: {
type: 0,
name: '秒',
key: 'seconds',
second: 1
},
1: {
type: 1,
name: '分钟',
key: 'minutes',
second: 60
},
2: {
type: 2,
name: '小时',
key: 'hours',
second: 60 * 60
},
3: {
type: 3,
name: '天',
key: 'days',
second: 24 * 60 * 60
}
}
const defaultUpdateInterval = INTERVAL_ID_TO_TYPE_MAPPING['0']
// 图表字段映射
const CHART_KEY_NAME_MAPPING = {
cpu: 'CPU',
memory: '内存',
disk: '磁盘'
}
// 仪表盘字段映射
const INSTRUMENT_BOARD_KEY_TO_NAME_MAPPING = {
cpu: 'CPU使用率',
memory: '内存使用率',
}
// 服务器信息可修改字段
const CHANGEABLE_SERVER_FIELDS = ['name', 'remark']
export default {
name: 'Server',
components: {
InstrumentBoard,
LineChart
},
data() {
return {
SERVER_KEY_TO_NAME_MAPPING,
INTERVAL_ID_TO_TYPE_MAPPING,
CHART_KEY_NAME_MAPPING,
CHANGEABLE_SERVER_FIELDS,
INSTRUMENT_BOARD_KEY_TO_NAME_MAPPING,
timeRange: [
`${moment().format('YYYY-MM-DD')} 00:00:00`,
`${moment().format('YYYY-MM-DD')} 23:59:59`
],
// 加载层信息
loading: [],
// 所有服务器信息
allServerInfo: [],
// 当前展示的服务器名称
currentServerName: '',
// 当前展示的服务器信息
currentServer: {},
// 当前展示的服务器信息索引,更新服务器信息时用
currentServerIndex: 0,
// 开启监控控制按钮
isOpeningMonitor: false,
// 数据更新频率
monitorUpdateInterval: 60,
// 最小更新频率值
minMonitorUpdateInterval: 0,
// 更新频率类型
intervalType: defaultUpdateInterval.name,
// 更新频率单位对应秒
intervalTypeUnits: defaultUpdateInterval.second,
// 监控日志保存天数
monitorLogSavingDays: 30,
// 折线图数据
lineChartData: {},
// 仪表盘数据
instrumentBoardData: {}
}
},
computed: {
currentServerInfoKeys() {
return Object.keys(this.currentServer).filter(key => {
if (SERVER_KEY_TO_NAME_MAPPING[key]) {
return { [key]: SERVER_KEY_TO_NAME_MAPPING[key] }
}
})
},
intervalNameToSecondMapping() {
let intervalNameToSecondMapping = {}
Object.values(INTERVAL_ID_TO_TYPE_MAPPING).forEach(item => {
intervalNameToSecondMapping[item.name] = item.second
})
return intervalNameToSecondMapping
},
monitorStatusInfo() {
return {
enabled: this.isOpeningMonitor ? 1 : 0,
save_days: this.monitorLogSavingDays,
interval: this.monitorUpdateInterval * this.intervalTypeUnits
}
}
},
watch: {
currentServer(newServerInfo) {
if (newServerInfo) {
// 更新最新监控信息
this.getServerLatestLogInfo(newServerInfo.id)
// 获取监控日志信息
this.getCurrentServerMonitorLogs()
}
}
},
created() {
this.openLoading()
// 获取所有服务器信息
this.getServerList(this.currentServerIndex)
// 获取服务器监控频率设置
this.getMonitorStatusSettingsInfo()
},
methods: {
/** 查询所有服务器基础信息 */
getServerList(serverIndex) {
getServerList({ pageNum: 'all' }).then(response => {
this.allServerInfo = response.data
if (this.allServerInfo.length > 0) {
this.currentServer = this.allServerInfo[serverIndex || this.currentServerIndex]
this.currentServerName = this.currentServer.name
}
this.loading.close()
})
},
/**修改服务器信息*/
updateServerInfo() {
updateServerInfo(this.currentServer.id, this.currentServer).then(() => {
this.msgSuccess('修改服务器信息成功!')
}).catch(error => {
this.$message.error(error.msg || '提交修改服务器信息出错!')
})
},
/** 获取服务器最新监控信息 */
getServerLatestLogInfo(serverId) {
getServerLatestLog(serverId).then(results => {
this.instrumentBoardData = results.data
}).catch(error => {
this.msgError(error.msg || '获取服务器最新监控信息错误!')
})
},
/** 获取监控日志信息 */
getCurrentServerMonitorLogs() {
getMonitorLogs(this.currentServer.id, { as: { 'create_datetime__range': this.timeRange } }).then(results => {
this.lineChartData = results.data
}).catch(error => {
this.msgError(error.msg || '获取监控日志信息出错误!')
})
},
/** 清除监控日志 */
cleanMonitorLogsInfo() {
cleanMonitorLog().then(results => {
this.msgSuccess(results.msg || '清除记录成功!')
}).catch(error => {
this.$message.warning(error.msg || '清除记录失败,请重试!')
})
},
/** 获取监控配置信息 */
getMonitorStatusSettingsInfo() {
getMonitorStatusInfo().then(results => {
let { enabled, interval, save_days } = results.data
this.isOpeningMonitor = enabled
this.monitorLogSavingDays = parseInt(save_days)
this.formatInterval(parseInt(interval))
}).catch(error => {
this.msgError(error.msg || '获取服务器监控配置信息出错误!')
})
},
/** 更新监控配置信息 */
updateMonitorStatusSettingsInfo() {
updateMonitorStatusInfo(this.monitorStatusInfo).then(() => {
this.msgSuccess('更新配置成功!')
}).catch((error) => {
this.msgError(error.msg || '更新服务器监控配置信息出错误!')
})
},
// 打开加载层
openLoading() {
this.loading = this.$loading({
lock: true,
text: '拼命读取中',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
},
// 选择展示的服务器信息
chooseServerInfo(index) {
this.currentServerIndex = index
this.currentServer = this.allServerInfo[index]
this.currentServerName = this.currentServer.name
},
// 更改更新频率(周期)数值
handleIntervalChange: debounce(function(value) {
this.monitorUpdateInterval = value
}, 500),
// 选择更新频率(周期) 单位
selectIntervalType(value) {
this.intervalType = value
this.intervalTypeUnits = this.intervalNameToSecondMapping[value]
},
// 修改监控状态
changeMonitorStatus(value) {
this.isOpeningMonitor = value
},
// 监控周期时间转换
formatInterval(intervalTime) {
let biggerInterval = 0
for (let interval of Object.values(INTERVAL_ID_TO_TYPE_MAPPING)) {
if (interval.second > biggerInterval && interval.second < intervalTime) {
biggerInterval = interval.second
this.monitorUpdateInterval = intervalTime / interval.second
this.intervalType = interval.name
this.intervalTypeUnits = interval.second
}
}
},
}
}
</script>
<style scoped>
.el-button--medium {
margin: 2px;
padding: 10px 10px;
}
.server-monitor-top {
padding: 0 10px;
text-align: justify-all;
}
.server-monitor-bottom {
text-align: left;
}
.server-information {
width: 20%;
min-width: 400px;
min-height: 300px;
display: inline-block;
}
.information-instrument-panel {
display: inline-block;
min-height: 300px;
min-width: 400px;
margin: 0 10px;
}
.server-info-item {
display: inline-block;
margin: 0 5px;
}
.server-info-detail {
min-height: 200px;
}
.server-info-detail-line {
margin: 5px;
min-height: 20px;
}
.server-info-detail-item {
text-align: justify;
line-height: 40px;
margin: 4px 0;
overflow: auto;
}
.server-monitor-control {
width: 100%;
height: 60px;
line-height: 60px;
padding: 0 20px;
}
.monitor-update-interval {
margin: 0 20px;
}
.same-block {
display: inline-block;
}
.monitor-update-interval-blank {
width: 100px;
margin: 0 2px;
}
.monitor-update-interval-unit {
width: 80px;
margin: 0 2px;
}
.monitor-log-save-time {
width: 280px;
margin: 0 2px;
}
.clean-monitor-log {
}
.server-monitor-line-chart {
height: 400px;
width: 45%;
min-width: 500px;
margin: 10px;
display: inline-block;
}
</style>