Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
TangShan_DD | 992953331a |
|
@ -110,6 +110,8 @@ export function resourceTypeMonitorFilter(value) {
|
|||
MONITOR_HUAWEI_VM: '华为云ECS',
|
||||
MONITOR_SMARTX_VM: 'SMARTX云主机',
|
||||
MONITOR_SMARTX_HOST: 'SMARTX宿主机',
|
||||
MONITOR_CLOUDTOWER_HOST: 'CloudTower宿主机',
|
||||
MONITOR_CLOUDTOWER_VM: 'CloudTower云主机',
|
||||
MONITOR_STORAGE_DELL_STORAGE: 'Dell存储设备',
|
||||
MONITOR_STORAGE_DELL_DISK: 'Dell磁盘',
|
||||
MONITOR_STORAGE_DELL_VOLUME: 'Dell存储卷',
|
||||
|
|
|
@ -18,6 +18,8 @@ const monitor = {
|
|||
MonitorCloudHuawei: () => import('views/compute/cloud/huawei/index.vue'), // 华为云
|
||||
MonitorCloudH3C: () => import('views/compute/cloud/h3c/index.vue'), // 华三云
|
||||
MonitorCloudSmart: () => import('views/compute/cloud/smart/index.vue'), // smartx
|
||||
MonitorCloudCloudTower: () => import('views/compute/cloud/cloudTower/index.vue'), // cloudtower
|
||||
|
||||
MonitorContainerDetail: () => import('views/compute/cloud/vcenter/platformMonitorDetail.vue'), // 告警详情
|
||||
MonitorDetailList: () => import('views/compute/cloud/vcenter/platformMonitorDetail.vue'), // 告警详情
|
||||
MonitorFocusList: () => import('views/storage/huawei/list.vue'), // 集中式存储列表
|
||||
|
@ -43,6 +45,9 @@ const monitor = {
|
|||
mOneVmMonitor: () => import('views/compute/cloud/platformMonitor/manageone_vm.vue'),
|
||||
SmartxServerMonitor: () => import('views/compute/cloud/platformMonitor/smartx_host.vue'),
|
||||
SmartxVmMonitor: () => import('views/compute/cloud/platformMonitor/smartx_vm.vue'),
|
||||
CloudTowerServerMonitor: () => import('views/compute/cloud/platformMonitor/cloudTower_host.vue'),
|
||||
CloudTowerVmMonitor: () => import('views/compute/cloud/platformMonitor/cloudTower_vm.vue'),
|
||||
VmMonitor: () => import('views/compute/cloud/platformMonitor/cloudTower_vm.vue'),
|
||||
monitorDatabaseDetail: () => import('views/compute/cloud/vcenter/platformMonitorDetail.vue'),
|
||||
huaweiStorageList: () => import('views/storage/huawei/list.vue'),
|
||||
// 新添加的数据库监控组件
|
||||
|
|
|
@ -314,3 +314,10 @@ export function getSmartHosts(params) {
|
|||
params: params
|
||||
})
|
||||
}
|
||||
|
||||
// 主机详情
|
||||
export function getHostDetail(id, vendorType) {
|
||||
return request.get(`/cms/v1/hosts/${id}`, {
|
||||
params: wrapperParams({ type: vendorType })
|
||||
})
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ export default {
|
|||
label: '所属平台',
|
||||
value: 'vendorId',
|
||||
data: [],
|
||||
service: { api: conditionCloudVendor, params: { condition: JSON.stringify({ condition: 'listByTypes', types: ['OPENSTACK', 'VMWARE', 'FUSIONCLOUD', 'HMC', 'MANAGEONE', 'KUBERNETES', 'TIANYI', 'HUAWEI', 'H3C', 'ALIYUN', 'SMARTX'] }) }, attr: 'data' }
|
||||
service: { api: conditionCloudVendor, params: { condition: JSON.stringify({ condition: 'listByTypes', types: ['OPENSTACK', 'VMWARE', 'FUSIONCLOUD', 'HMC', 'MANAGEONE', 'KUBERNETES', 'TIANYI', 'HUAWEI', 'H3C', 'ALIYUN', 'SMARTX', 'CLOUDTOWER'] }) }, attr: 'data' }
|
||||
},
|
||||
{ type: 'Select', label: '告警级别', value: 'level', data: alarmLevelData, props: { value: 'value' } },
|
||||
{ type: 'DateRange', value: 'gmtTrigger', label: '' },
|
||||
|
|
|
@ -147,7 +147,7 @@ export default {
|
|||
label: '所属平台',
|
||||
value: 'vendorId',
|
||||
data: [],
|
||||
service: { api: conditionCloudVendor, params: { condition: JSON.stringify({ condition: 'listByTypes', types: ['OPENSTACK', 'VMWARE', 'FUSIONCLOUD', 'HMC', 'MANAGEONE', 'KUBERNETES', 'TIANYI', 'HUAWEI', 'H3C', 'ALIYUN', 'SMARTX'] }) }, attr: 'data' }
|
||||
service: { api: conditionCloudVendor, params: { condition: JSON.stringify({ condition: 'listByTypes', types: ['OPENSTACK', 'VMWARE', 'FUSIONCLOUD', 'HMC', 'MANAGEONE', 'KUBERNETES', 'TIANYI', 'HUAWEI', 'H3C', 'ALIYUN', 'SMARTX', 'CLOUDTOWER'] }) }, attr: 'data' }
|
||||
},
|
||||
{ type: 'Select', label: '告警级别', value: 'level', data: alarmLevelData, props: { value: 'value' } },
|
||||
{ type: 'DateRange', value: 'gmtTrigger', label: '' },
|
||||
|
|
|
@ -434,7 +434,14 @@ export default {
|
|||
this.type = ''
|
||||
this.activeName = 'list'
|
||||
this.detailData = Object.assign({}, row)
|
||||
if (this.detailData.resourceType == 'MONITOR_VCENTER_HOST' || this.detailData.resourceType == 'MONITOR_OPENSTACK_HOST' || this.detailData.resourceType == 'MONITOR_FUSIONCLOUD_HOST' || this.detailData.resourceType == 'MONITOR_H3C_HOST' || this.detailData.resourceType == 'MONITOR_SMARTX_HOST') {
|
||||
if (
|
||||
this.detailData.resourceType == 'MONITOR_VCENTER_HOST' ||
|
||||
this.detailData.resourceType == 'MONITOR_OPENSTACK_HOST' ||
|
||||
this.detailData.resourceType == 'MONITOR_FUSIONCLOUD_HOST' ||
|
||||
this.detailData.resourceType == 'MONITOR_H3C_HOST' ||
|
||||
this.detailData.resourceType == 'MONITOR_SMARTX_HOST' ||
|
||||
this.detailData.resourceType == 'MONITOR_CLOUDTOWER_HOST'
|
||||
) {
|
||||
this.type = 'HOST'
|
||||
}
|
||||
const arr = []
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
<div v-else-if="record.vendorType == 'JDCLOUD'">
|
||||
<div v-for="(item, index) in record.privateIpsList" :key="index">(内网){{ item }}</div>
|
||||
</div>
|
||||
<div v-else-if="record.vendorType == 'SMARTX' || record.vendorType == 'CLOUDTOWER'">
|
||||
<div>{{ record.managerIp ? '(内网)' + record.managerIp : '--' }}</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-for="(item, index) in record.privateIpsList" :key="index">(内网){{ item }}</div>
|
||||
</div>
|
||||
|
@ -109,7 +112,7 @@ export default {
|
|||
{ type: 'Select', label: '所属平台', value: 'vendorId', data: [], service: { api: getCloudVendor, params: { simple: true, params: this.$tools.handleSearchParam({ type: getVendorType(this.resourceType) }) }, attr: 'data.rows' } },
|
||||
{ type: 'Const', value: 'vendorType', initValue: getVendorType(this.resourceType) },
|
||||
{ type: 'Const', value: 'id', initValue: this.resourceIds && this.status == 'detail' ? this.resourceIds.join(',') : '', sign: 'IN' },
|
||||
{ type: 'Const', value: 'isTemplate', initValue: getVendorType(this.resourceType) == 'VMWARE' || getVendorType(this.resourceType) == 'H3C' || getVendorType(this.resourceType) == 'SMARTX' ? false : '' }
|
||||
{ type: 'Const', value: 'isTemplate', initValue: getVendorType(this.resourceType) == 'VMWARE' || getVendorType(this.resourceType) == 'H3C' || getVendorType(this.resourceType) == 'SMARTX' || getVendorType(this.resourceType) == 'CLOUDTOWER' ? false : '' }
|
||||
],
|
||||
list: [],
|
||||
total: 0,
|
||||
|
|
|
@ -46,7 +46,7 @@ export default defineComponent({
|
|||
const data = await conditionCloudVendor({
|
||||
condition: JSON.stringify({
|
||||
condition: 'listByTypes',
|
||||
types: ['OPENSTACK', 'VMWARE', 'SMARTX']
|
||||
types: ['OPENSTACK', 'VMWARE', 'SMARTX', 'CLOUDTOWER']
|
||||
})
|
||||
})
|
||||
if (data.success) {
|
||||
|
@ -62,7 +62,13 @@ export default defineComponent({
|
|||
async function getCountData(vendorId: number) {
|
||||
const res = await getPortal({ vendorId, code: 'resUsed' })
|
||||
if (res.success) {
|
||||
countData.value = res.data
|
||||
const vendorType = unref(vendorList).find(({ id }) => id === vendorId).type
|
||||
countData.value = res.data.filter((item) => {
|
||||
if (['CLOUDTOWER', 'INSPURRAIL', 'FUSIONSPHERE'].includes(vendorType)) {
|
||||
if (item.name === '磁盘') return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
return {
|
||||
|
|
|
@ -57,7 +57,7 @@ export default {
|
|||
const data = await conditionCloudVendor({
|
||||
condition: JSON.stringify({
|
||||
condition: 'listByTypes',
|
||||
types: ['OPENSTACK', 'VMWARE', 'SMARTX']
|
||||
types: ['OPENSTACK', 'VMWARE', 'SMARTX', 'CLOUDTOWER']
|
||||
})
|
||||
})
|
||||
if (data.success) {
|
||||
|
|
|
@ -322,7 +322,12 @@ export default {
|
|||
vendor: this.vendorType
|
||||
}).then((data) => {
|
||||
if (data.success) {
|
||||
this.resUsedData = data.data
|
||||
this.resUsedData = data.data.filter((item) => {
|
||||
if (['CLOUDTOWER', 'INSPURRAIL', 'FUSIONSPHERE'].includes(this.vendorType)) {
|
||||
if (item.name === '磁盘') return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
this.detailData.cpuTotal = data.data[0].total
|
||||
this.detailData.memTotal = data.data[1].total
|
||||
this.detailData.diskTotal = data.data[2].total
|
||||
|
|
|
@ -368,7 +368,13 @@ export default {
|
|||
},
|
||||
getDetail(row) {
|
||||
this.detailData = Object.assign({}, row)
|
||||
if (this.detailData.resourceType == 'MONITOR_VCENTER_HOST' || this.detailData.resourceType == 'MONITOR_OPENSTACK_HOST' || this.detailData.resourceType == 'MONITOR_FUSIONCLOUD_HOST' || this.detailData.resourceType == 'MONITOR_H3C_HOST') {
|
||||
if (
|
||||
this.detailData.resourceType == 'MONITOR_VCENTER_HOST' ||
|
||||
this.detailData.resourceType == 'MONITOR_CLOUDTOWER_HOST' ||
|
||||
this.detailData.resourceType == 'MONITOR_OPENSTACK_HOST' ||
|
||||
this.detailData.resourceType == 'MONITOR_FUSIONCLOUD_HOST' ||
|
||||
this.detailData.resourceType == 'MONITOR_H3C_HOST'
|
||||
) {
|
||||
this.type = 'HOST'
|
||||
}
|
||||
const arr = []
|
||||
|
|
|
@ -0,0 +1,357 @@
|
|||
<template>
|
||||
<div>
|
||||
<AdvanceTable title="当前告警" :search-configs="searchConfigs" :data="list" :params="params" :columns="columns" :get-list="getList" :total="total" :loading="loading" @select="handleSelectItem" @select-all="handleSelectAll" ref="currentMonitorTable">
|
||||
<template v-slot:action>
|
||||
<el-button type="ghost" @click="handleConfirm()" :disabled="!selectList.length">
|
||||
批量确认
|
||||
</el-button>
|
||||
<el-button type="ghost" @click="handleBatchClear()" :disabled="!selectList.length">
|
||||
批量清除
|
||||
</el-button>
|
||||
</template>
|
||||
<template #name="val, record">
|
||||
<span class="detail-href" @click="getDetail(record.id)">{{val}}</span>
|
||||
</template>
|
||||
<template #level="val">
|
||||
<level-icon :color="alarmLevelColorFilter(val)">
|
||||
{{alarmLevelFilter(val)}}
|
||||
</level-icon>
|
||||
</template>
|
||||
<template #targetName="val, record">
|
||||
<div v-if="record.type == 'MONITOR_ALIYUN_VM'">
|
||||
<!-- <div v-for="(item, index) in parseTarget(val)" :key="index">{{item}}</div> -->
|
||||
<span>{{parseTarget(val)}}</span>
|
||||
</div>
|
||||
<div v-else>{{val}}</div>
|
||||
</template>
|
||||
<template #resource="val, record">
|
||||
{{resourceTypeMonitorFilter(record.type)}}<span v-if="record.type == 'VM'">({{record.osCategory}})</span>
|
||||
</template>
|
||||
<template #confirmed="val, record">
|
||||
{{record.confirmed?'已确认':'未确认'}},{{record.solved?'已清除':'未清除'}}
|
||||
</template>
|
||||
<template #operate="val, record">
|
||||
<el-button type="text" @click="handleConfirm(record.id)" :disabled="record.confirmed">
|
||||
<i class="el-icon-check"></i> 确认
|
||||
</el-button>
|
||||
<div class="action-divider"></div>
|
||||
<el-button type="text" @click="handleClear(record.id)" :disabled="record.solved">
|
||||
<i class="el-icon-delete"></i> 清除
|
||||
</el-button>
|
||||
</template>
|
||||
</AdvanceTable>
|
||||
<el-dialog title="告警解决" :close-on-click-modal="false" v-if="solveFormVisible" :visible.sync="solveFormVisible">
|
||||
<el-form :model="solveData" label-width="100px" ref="solveData">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="解决结果:" prop="dealResult">
|
||||
<el-input type="textarea" v-model="solveData.dealResult" auto-complete="off"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click.native="solveFormVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click.native="solveSubmit">确定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<common-detail-right v-if="detailFlag" :title="detailData.name" @goBack="goBack">
|
||||
<template v-slot:item_container>
|
||||
<common-detail-item label="告警名称">{{detailData.name}}</common-detail-item>
|
||||
<common-detail-item label="告警级别">
|
||||
<level-icon :color="alarmLevelColorFilter(detailData.level)">
|
||||
{{alarmLevelFilter(detailData.level)}}
|
||||
</level-icon>
|
||||
</common-detail-item>
|
||||
<common-detail-item label="告警源">
|
||||
<div v-if="detailData.type == 'MONITOR_ALIYUN_VM'">
|
||||
{{parseTarget(detailData.targetName)}}
|
||||
<!-- <div v-for="(item, index) in JSON.parse(detailData.targetName)" :key="index">{{item}}</div> -->
|
||||
</div>
|
||||
<div v-else>{{detailData.targetName}}</div>
|
||||
</common-detail-item>
|
||||
<common-detail-item label="资源类型">
|
||||
{{resourceTypeMonitorFilter(detailData.type)}}<span v-if="detailData.type == 'VM'">({{detailData.osCategory}})
|
||||
</span>
|
||||
</common-detail-item>
|
||||
<common-detail-item label="告警状态">{{detailData.status1}}</common-detail-item>
|
||||
<common-detail-item label="告警内容">{{detailData.remark}}</common-detail-item>
|
||||
<common-detail-item label="告警触发时间">{{detailData.gmtTrigger}}</common-detail-item>
|
||||
<common-detail-item label="已持续时长">{{detailData.duration}}</common-detail-item>
|
||||
<common-detail-item label="确认人">{{detailData.confirmer}}</common-detail-item>
|
||||
<common-detail-item label="确认时间">{{detailData.gmtConfirm}}</common-detail-item>
|
||||
</template>
|
||||
</common-detail-right>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { alarmLevelFilter, alarmLevelColorFilter, resourceTypeMonitorFilter } from '@/filters/index'
|
||||
import { getAlarmList, alarmConfirm, alarmSolve, getAlarmDetail } from 'services/monitor'
|
||||
import levelIcon from 'views/components/statusIcon'
|
||||
const columns = [
|
||||
{
|
||||
type: 'selection',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
label: '名称',
|
||||
prop: 'name',
|
||||
scopedSlots: { customRender: 'name' }
|
||||
},
|
||||
{
|
||||
label: '告警级别',
|
||||
prop: 'level',
|
||||
scopedSlots: { customRender: 'level' }
|
||||
},
|
||||
{
|
||||
label: '告警源',
|
||||
prop: 'targetName',
|
||||
scopedSlots: { customRender: 'targetName' }
|
||||
},
|
||||
{
|
||||
label: '资源类型',
|
||||
prop: 'resource',
|
||||
scopedSlots: { customRender: 'resource' }
|
||||
},
|
||||
{
|
||||
label: '告警状态',
|
||||
prop: 'confirmed',
|
||||
scopedSlots: { customRender: 'confirmed' }
|
||||
},
|
||||
{
|
||||
label: '告警内容',
|
||||
prop: 'remark'
|
||||
},
|
||||
{
|
||||
label: '告警触发时间',
|
||||
prop: 'gmtTrigger'
|
||||
},
|
||||
{
|
||||
label: '已持续时长',
|
||||
prop: 'duration'
|
||||
},
|
||||
{
|
||||
label: '确认人',
|
||||
prop: 'confirmer'
|
||||
},
|
||||
{
|
||||
label: '确认时间',
|
||||
prop: 'gmtConfirm'
|
||||
},
|
||||
{
|
||||
label: '操作',
|
||||
disabled: true,
|
||||
prop: 'id',
|
||||
width: '160px',
|
||||
scopedSlots: { customRender: 'operate' }
|
||||
}
|
||||
]
|
||||
const alarmLevelData = [
|
||||
{ name: '提示告警', value: 'REMIND' },
|
||||
{ name: '次要告警', value: 'SECONDARY' },
|
||||
{ name: '重要告警', value: 'PRIMARY' },
|
||||
{ name: '紧急告警', value: 'URGENT' }
|
||||
]
|
||||
export default {
|
||||
components: {
|
||||
levelIcon
|
||||
},
|
||||
props: {
|
||||
target: {
|
||||
type: Number
|
||||
},
|
||||
typeName: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
alarmLevelFilter,
|
||||
alarmLevelColorFilter,
|
||||
resourceTypeMonitorFilter,
|
||||
columns,
|
||||
loading: false,
|
||||
alarmLevelData,
|
||||
searchConfigs: [
|
||||
{ type: 'Input', label: '告警源', value: 'targetName' },
|
||||
{ type: 'Select', label: '告警级别', value: 'level', data: alarmLevelData, props: { value: 'value' } },
|
||||
{ type: 'DateRange', value: 'gmtTrigger', label: '' },
|
||||
{ type: 'Const', value: 'type', initValue: this.typeName },
|
||||
{ type: 'Const', value: 'target', initValue: this.target },
|
||||
{ type: 'Const', value: 'eventAlarm', initValue: 0 },
|
||||
{ type: 'Const', value: 'status', initValue: 'SOLVED', sign: 'UEQ' }
|
||||
],
|
||||
id: '',
|
||||
params: {
|
||||
page: 1,
|
||||
rows: 10
|
||||
},
|
||||
total: 0,
|
||||
list: [],
|
||||
idList: [],
|
||||
selectList: [],
|
||||
solveFormVisible: false,
|
||||
solveData: {},
|
||||
detailFlag: false,
|
||||
detailData: {}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.id = this.$route.query.id;
|
||||
},
|
||||
beforeDestroy () {
|
||||
},
|
||||
methods: {
|
||||
getList () {
|
||||
this.loading = true
|
||||
getAlarmList(this.params).then(data => {
|
||||
this.loading = false
|
||||
if (data.success) {
|
||||
this.list = data.data.rows
|
||||
this.total = data.data.total
|
||||
this.list.forEach((item) => {
|
||||
const self = this;
|
||||
setTimeout(function () {
|
||||
if (self.idList.indexOf(item.id) > -1) self.$refs.currentMonitorTable.toggleRowSelection(item, true)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 查询
|
||||
handleSearch (params) {
|
||||
this.params.page = 1
|
||||
this.params.params = params
|
||||
this.getList()
|
||||
},
|
||||
handleSelectItem (selection, row) {
|
||||
this.refreshId()
|
||||
if (this.idList.indexOf(row.id) > -1) {
|
||||
for (let j = 0; j < this.selectList.length; j++) {
|
||||
const item = this.selectList[j]
|
||||
if (item.id == row.id) {
|
||||
this.selectList.splice(j, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.selectList.push(row)
|
||||
}
|
||||
},
|
||||
handleSelectAll (selection) {
|
||||
this.refreshId()
|
||||
if (selection.length) { // 全选情况下
|
||||
this.list.forEach(item => {
|
||||
if (this.idList.indexOf(item.id) == -1) {
|
||||
this.selectList.push(item)
|
||||
}
|
||||
})
|
||||
} else { // 全不选情况下
|
||||
this.list.forEach(item => {
|
||||
if (this.idList.indexOf(item.id) > -1) {
|
||||
for (let j = 0; j < this.selectList.length; j++) {
|
||||
const row = this.selectList[j]
|
||||
if (item.id == row.id) {
|
||||
this.selectList.splice(j, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
refreshId () {
|
||||
this.idList = []
|
||||
this.selectList.forEach(item => {
|
||||
this.idList.push(item.id)
|
||||
})
|
||||
},
|
||||
handleConfirm (id) {
|
||||
this.refreshId()
|
||||
let list = []
|
||||
if (id) {
|
||||
list.push(id)
|
||||
} else {
|
||||
list = this.idList
|
||||
}
|
||||
this.$confirm('确定要确认告警吗?', '提示', {
|
||||
confirmButtonText: '确认',
|
||||
confirmButtonClass: 'el-button--primary',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
alarmConfirm({
|
||||
ids: list
|
||||
}).then(data => {
|
||||
if (data.success) {
|
||||
this.$message.success({
|
||||
message: data.message
|
||||
})
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
})
|
||||
},
|
||||
handleClear (id) {
|
||||
this.solveData = {
|
||||
ids: [id],
|
||||
dealResult: ''
|
||||
}
|
||||
this.solveFormVisible = true;
|
||||
},
|
||||
handleBatchClear () {
|
||||
this.refreshId();
|
||||
this.solveData = {
|
||||
ids: this.idList
|
||||
}
|
||||
this.solveFormVisible = true;
|
||||
},
|
||||
solveSubmit () {
|
||||
this.$refs.solveData.validate((valid) => {
|
||||
if (valid) {
|
||||
alarmSolve(this.solveData).then(data => {
|
||||
if (data.success) {
|
||||
this.$message.success({
|
||||
message: data.message
|
||||
})
|
||||
this.solveFormVisible = false
|
||||
this.selectList = []
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
getDetail (id) {
|
||||
getAlarmDetail(id).then(data => {
|
||||
if (data.success) {
|
||||
this.detailData = data.data
|
||||
let str1, str2;
|
||||
if (this.detailData.confirmed) {
|
||||
str1 = '已确认'
|
||||
} else {
|
||||
str1 = '未确认'
|
||||
}
|
||||
if (this.detailData.solved) {
|
||||
str2 = '已清除'
|
||||
} else {
|
||||
str2 = '未清除'
|
||||
}
|
||||
this.detailData.status1 = str1 + ',' + str2
|
||||
this.detailFlag = true
|
||||
}
|
||||
})
|
||||
},
|
||||
goBack () {
|
||||
this.detailFlag = false
|
||||
},
|
||||
parseTarget(data) {
|
||||
// TODO: 不知道是否要处理
|
||||
return data
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
|
@ -0,0 +1,301 @@
|
|||
<template>
|
||||
<div>
|
||||
<AdvanceTable title="历史告警" :search-configs="searchConfigs" :data="list" :params="params" :columns="columns" :get-list="getList" :total="total" :loading="loading" @select="handleSelectItem" @select-all="handleSelectAll" ref="historyMonitorTable">
|
||||
<template v-slot:action>
|
||||
<el-button type="ghost" @click="handleConfirm()" :disabled="!selectList.length">
|
||||
批量确认
|
||||
</el-button>
|
||||
</template>
|
||||
<template #name="val, record">
|
||||
<span class="detail-href" @click="getDetail(record.id)">{{val}}</span>
|
||||
</template>
|
||||
<template #level="val">
|
||||
<level-icon :color="alarmLevelColorFilter(val)">
|
||||
{{alarmLevelFilter(val)}}
|
||||
</level-icon>
|
||||
</template>
|
||||
<template #targetName="val">
|
||||
<!-- <div v-if="record.type == 'MONITOR_ALIYUN_VM'">
|
||||
<div v-for="(item, index) in JSON.parse(val)" :key="index">{{item}}</div>
|
||||
</div> -->
|
||||
<div>{{val}}</div>
|
||||
</template>
|
||||
<template #resource="val, record">
|
||||
{{resourceTypeMonitorFilter(record.type)}}<span v-if="record.type == 'VM'">({{record.osCategory}})</span>
|
||||
</template>
|
||||
<template #confirmed="val, record">
|
||||
{{record.confirmed?'已确认':'未确认'}},{{record.solved?'已清除':'未清除'}}
|
||||
</template>
|
||||
<template #operate="val, record">
|
||||
<el-button type="text" @click="handleConfirm(record.id)" :disabled="record.confirmed">
|
||||
<i class="el-icon-check"></i> 确认
|
||||
</el-button>
|
||||
</template>
|
||||
</AdvanceTable>
|
||||
<common-detail-right v-if="detailFlag" :title="detailData.name" @goBack="goBack">
|
||||
<template v-slot:item_container>
|
||||
<common-detail-item label="告警名称">{{detailData.name}}</common-detail-item>
|
||||
<common-detail-item label="告警级别">
|
||||
<level-icon :color="alarmLevelColorFilter(detailData.level)">
|
||||
{{alarmLevelFilter(detailData.level)}}
|
||||
</level-icon>
|
||||
</common-detail-item>
|
||||
<common-detail-item label="告警源">
|
||||
<!-- <div v-if="detailData.type == 'MONITOR_ALIYUN_VM'">
|
||||
<div v-for="(item, index) in JSON.parse(detailData.targetName)" :key="index">{{item}}</div>
|
||||
</div> -->
|
||||
<div>{{detailData.targetName}}</div>
|
||||
</common-detail-item>
|
||||
<common-detail-item label="资源类型">
|
||||
{{resourceTypeMonitorFilter(detailData.type)}}<span v-if="detailData.type == 'VM'">({{detailData.osCategory}})
|
||||
</span>
|
||||
</common-detail-item>
|
||||
<common-detail-item label="告警状态">{{detailData.status1}}</common-detail-item>
|
||||
<common-detail-item label="告警内容">{{detailData.remark}}</common-detail-item>
|
||||
<common-detail-item label="告警触发时间">{{detailData.gmtTrigger}}</common-detail-item>
|
||||
<common-detail-item label="已持续时长">{{detailData.duration}}</common-detail-item>
|
||||
<common-detail-item label="确认人">{{detailData.confirmer}}</common-detail-item>
|
||||
<common-detail-item label="确认时间">{{detailData.gmtConfirm}}</common-detail-item>
|
||||
<common-detail-item label="解决人">{{detailData.solver}}</common-detail-item>
|
||||
<common-detail-item label="解决时间">{{detailData.gmtSolve}}</common-detail-item>
|
||||
<common-detail-item label="解决详情">{{detailData.dealResult}}</common-detail-item>
|
||||
</template>
|
||||
</common-detail-right>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { alarmLevelFilter, alarmLevelColorFilter, resourceTypeMonitorFilter } from '@/filters/index'
|
||||
import { getAlarmList, getAlarmDetail, alarmConfirm } from 'services/monitor'
|
||||
import levelIcon from 'views/components/statusIcon'
|
||||
const columns = [
|
||||
{
|
||||
type: 'selection',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
label: '名称',
|
||||
prop: 'name',
|
||||
scopedSlots: { customRender: 'name' }
|
||||
},
|
||||
{
|
||||
label: '告警级别',
|
||||
prop: 'level',
|
||||
scopedSlots: { customRender: 'level' }
|
||||
},
|
||||
{
|
||||
label: '告警源',
|
||||
prop: 'targetName',
|
||||
scopedSlots: { customRender: 'targetName' }
|
||||
},
|
||||
{
|
||||
label: '资源类型',
|
||||
prop: 'resource',
|
||||
scopedSlots: { customRender: 'resource' }
|
||||
},
|
||||
{
|
||||
label: '告警状态',
|
||||
prop: 'confirmed',
|
||||
scopedSlots: { customRender: 'confirmed' }
|
||||
},
|
||||
{
|
||||
label: '告警内容',
|
||||
prop: 'remark'
|
||||
},
|
||||
{
|
||||
label: '告警触发时间',
|
||||
prop: 'gmtTrigger'
|
||||
},
|
||||
{
|
||||
label: '已持续时长',
|
||||
prop: 'duration'
|
||||
},
|
||||
{
|
||||
label: '确认人',
|
||||
prop: 'confirmer'
|
||||
},
|
||||
{
|
||||
label: '确认时间',
|
||||
prop: 'gmtConfirm'
|
||||
},
|
||||
{
|
||||
label: '操作',
|
||||
disabled: true,
|
||||
prop: 'id',
|
||||
width: '160px',
|
||||
scopedSlots: { customRender: 'operate' }
|
||||
}
|
||||
]
|
||||
|
||||
const alarmLevelData = [
|
||||
{ name: '提示告警', value: 'REMIND' },
|
||||
{ name: '次要告警', value: 'SECONDARY' },
|
||||
{ name: '重要告警', value: 'PRIMARY' },
|
||||
{ name: '紧急告警', value: 'URGENT' }
|
||||
]
|
||||
export default {
|
||||
components: {
|
||||
levelIcon
|
||||
},
|
||||
props: {
|
||||
target: {
|
||||
type: Number
|
||||
},
|
||||
typeName: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
alarmLevelFilter,
|
||||
alarmLevelColorFilter,
|
||||
resourceTypeMonitorFilter,
|
||||
columns,
|
||||
loading: false,
|
||||
alarmLevelData,
|
||||
searchConfigs: [
|
||||
{ type: 'Input', label: '告警源', value: 'targetName' },
|
||||
{ type: 'Select', label: '告警级别', value: 'level', data: alarmLevelData, props: { value: 'value' } },
|
||||
{ type: 'DateRange', value: 'gmtTrigger', label: '' },
|
||||
{ type: 'Const', value: 'type', initValue: this.typeName },
|
||||
{ type: 'Const', value: 'target', initValue: this.target },
|
||||
{ type: 'Const', value: 'eventAlarm', initValue: 0 },
|
||||
{ type: 'Const', value: 'status', initValue: 'SOLVED' }
|
||||
],
|
||||
id: '',
|
||||
params: {
|
||||
page: 1,
|
||||
rows: 10
|
||||
},
|
||||
total: 0,
|
||||
list: [],
|
||||
idList: [],
|
||||
selectList: [],
|
||||
detailFlag: false,
|
||||
detailData: {}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.id = this.$route.query.id;
|
||||
},
|
||||
beforeDestroy () {
|
||||
},
|
||||
methods: {
|
||||
getList () {
|
||||
this.loading = true
|
||||
getAlarmList(this.params).then(data => {
|
||||
this.loading = false
|
||||
if (data.success) {
|
||||
this.list = data.data.rows
|
||||
this.total = data.data.total
|
||||
this.list.forEach((item) => {
|
||||
const self = this;
|
||||
setTimeout(function () {
|
||||
if (self.idList.indexOf(item.id) > -1) self.$refs.historyMonitorTable.toggleRowSelection(item, true)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 查询
|
||||
handleSearch (params) {
|
||||
this.params.page = 1
|
||||
this.params.params = params
|
||||
this.getList()
|
||||
},
|
||||
handleSelectItem (selection, row) {
|
||||
this.refreshId()
|
||||
if (this.idList.indexOf(row.id) > -1) {
|
||||
for (let j = 0; j < this.selectList.length; j++) {
|
||||
const item = this.selectList[j]
|
||||
if (item.id == row.id) {
|
||||
this.selectList.splice(j, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.selectList.push(row)
|
||||
}
|
||||
},
|
||||
handleSelectAll (selection) {
|
||||
this.refreshId()
|
||||
if (selection.length) { // 全选情况下
|
||||
this.list.forEach(item => {
|
||||
if (this.idList.indexOf(item.id) == -1) {
|
||||
this.selectList.push(item)
|
||||
}
|
||||
})
|
||||
} else { // 全不选情况下
|
||||
this.list.forEach(item => {
|
||||
if (this.idList.indexOf(item.id) > -1) {
|
||||
for (let j = 0; j < this.selectList.length; j++) {
|
||||
const row = this.selectList[j]
|
||||
if (item.id == row.id) {
|
||||
this.selectList.splice(j, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
refreshId () {
|
||||
this.idList = []
|
||||
this.selectList.forEach(item => {
|
||||
this.idList.push(item.id)
|
||||
})
|
||||
},
|
||||
handleConfirm (id) {
|
||||
this.refreshId()
|
||||
let list = []
|
||||
if (id) {
|
||||
list.push(id)
|
||||
} else {
|
||||
list = this.idList
|
||||
}
|
||||
this.$confirm('确定要确认告警吗?', '提示', {
|
||||
confirmButtonText: '确认',
|
||||
confirmButtonClass: 'el-button--primary',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
alarmConfirm({
|
||||
ids: list
|
||||
}).then(data => {
|
||||
if (data.success) {
|
||||
this.$message.success({
|
||||
message: data.message
|
||||
})
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
})
|
||||
},
|
||||
getDetail (id) {
|
||||
getAlarmDetail(id).then(data => {
|
||||
if (data.success) {
|
||||
this.detailData = data.data
|
||||
let str1, str2;
|
||||
if (this.detailData.confirmed) {
|
||||
str1 = '已确认'
|
||||
} else {
|
||||
str1 = '未确认'
|
||||
}
|
||||
if (this.detailData.solved) {
|
||||
str2 = '已清除'
|
||||
} else {
|
||||
str2 = '未清除'
|
||||
}
|
||||
this.detailData.status1 = str1 + ',' + str2
|
||||
this.detailFlag = true
|
||||
}
|
||||
})
|
||||
},
|
||||
goBack () {
|
||||
this.detailFlag = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
|
@ -0,0 +1,257 @@
|
|||
<template>
|
||||
<div>
|
||||
<AdvanceTable title="" :search-configs="searchConfigs" :data="list" :params="params" :columns="columns" :get-list="getList" :total="total" :loading="loading" @select="handleSelectItem" @select-all="handleSelectAll" ref="resourceMonitorTable">
|
||||
<template #name="val, record">
|
||||
<span class="detail-href" @click="getDetail(record)">{{ val }}</span>
|
||||
</template>
|
||||
<template #cpuUsage="cpuUsage">
|
||||
<el-progress class="progress" :color="customColorMethod" text-inside :stroke-width="16" :percentage="cpuUsage ? cpuUsage : 0"></el-progress>
|
||||
</template>
|
||||
<template #memUsage="memUsage">
|
||||
<el-progress class="progress" :color="customColorMethod" text-inside :stroke-width="16" :percentage="memUsage ? memUsage : 0"></el-progress>
|
||||
</template>
|
||||
<template #onOffStatus="onOffStatus">
|
||||
<status-icon :type="statusOnColorFilter(onOffStatus)">
|
||||
{{ onOffStatus }}
|
||||
</status-icon>
|
||||
</template>
|
||||
<template #responseTime="responseTime">
|
||||
<span v-if="responseTime">{{ responseTime }}ms</span>
|
||||
<span v-else>未知</span>
|
||||
</template>
|
||||
<template #operate="val, record">
|
||||
<el-button type="text" @click="handleMonitorDetail(record.id, record.name)"> 告警详情</el-button>
|
||||
<div class="action-divider"></div>
|
||||
<el-dropdown trigger="click">
|
||||
<span class="el-dropdown-link"> 更多<i class="el-icon-arrow-down el-icon--right"></i> </span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="handleLink(record.id)"> 关联规则 </el-dropdown-item>
|
||||
<el-dropdown-item @click.native="handlePolicy(record)">
|
||||
{{ `${record.alarmEnable ? '屏蔽' : '开启'}告警` }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</AdvanceTable>
|
||||
<add-policy v-if="addFlag" :resourceType="resourceType" @cancle="cancle" :add-link-flag="addFlag" :resourceId="resourceId" :ruleGroupIds="ruleGroupIds"></add-policy>
|
||||
<common-detail v-if="detailFlag" :title="detailData.name" @goBack="goBack">
|
||||
<div slot="custom_content">
|
||||
<detail :detail-id="detailId" :detail-name="detailData.name"></detail>
|
||||
</div>
|
||||
</common-detail>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { statusOnColorFilter } from '@/filters/index'
|
||||
import { getPolicyHosts, getRuleGroupBind } from 'services/monitor/index.js'
|
||||
import detail from './host_detail.vue'
|
||||
import { customColorMethod, handleStart } from 'views/data'
|
||||
import addPolicy from 'views/components/linkPolicy.vue'
|
||||
const columns = [
|
||||
{
|
||||
type: 'selection',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
label: '名称',
|
||||
prop: 'name',
|
||||
scopedSlots: { customRender: 'name' }
|
||||
},
|
||||
{
|
||||
label: 'IP地址',
|
||||
prop: 'manageIp'
|
||||
},
|
||||
{
|
||||
label: 'CPU利用率',
|
||||
prop: 'cpuUsage',
|
||||
scopedSlots: { customRender: 'cpuUsage' }
|
||||
},
|
||||
{
|
||||
label: '内存利用率',
|
||||
prop: 'memUsage',
|
||||
scopedSlots: { customRender: 'memUsage' }
|
||||
},
|
||||
{
|
||||
label: '总CPU(MHZ)',
|
||||
prop: 'cpuTotal'
|
||||
},
|
||||
{
|
||||
label: '总内存(GB)',
|
||||
prop: 'memTotal'
|
||||
},
|
||||
{
|
||||
label: '云主机数',
|
||||
prop: 'vmNum'
|
||||
},
|
||||
// {
|
||||
// label: '通断状态',
|
||||
// prop: 'onOffStatus',
|
||||
// scopedSlots: { customRender: 'onOffStatus' }
|
||||
// },
|
||||
// {
|
||||
// label: '响应时长',
|
||||
// prop: 'responseTime',
|
||||
// scopedSlots: { customRender: 'responseTime' }
|
||||
// },
|
||||
{
|
||||
label: '操作',
|
||||
disabled: true,
|
||||
prop: 'id',
|
||||
width: '160px',
|
||||
scopedSlots: { customRender: 'operate' }
|
||||
}
|
||||
]
|
||||
export default {
|
||||
components: {
|
||||
detail,
|
||||
addPolicy
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
statusOnColorFilter,
|
||||
customColorMethod,
|
||||
handleStart,
|
||||
columns,
|
||||
searchConfigs: [
|
||||
{ type: 'Input', label: '名称', value: 'name' },
|
||||
{ type: 'Input', label: 'IP', value: 'manageIp' },
|
||||
{ type: 'Const', value: 'vendorType', initValue: 'CLOUDTOWER' },
|
||||
{ type: 'Const', value: 'vendorId', initValue: this.$route.query.vendorId }
|
||||
],
|
||||
params: {
|
||||
page: 1,
|
||||
rows: 10
|
||||
},
|
||||
vendorData: [],
|
||||
list: [],
|
||||
total: 0,
|
||||
idList: [],
|
||||
selectList: [],
|
||||
detailFlag: false,
|
||||
detailData: {},
|
||||
detailId: null,
|
||||
loading: false,
|
||||
addFlag: false,
|
||||
resourceId: 0,
|
||||
ruleGroupIds: [],
|
||||
resourceType: 'MONITOR_CLOUDTOWER_HOST'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.loading = true
|
||||
this.refreshId()
|
||||
getPolicyHosts(this.params).then((data) => {
|
||||
this.loading = false
|
||||
if (data.success) {
|
||||
this.list = data.data.rows
|
||||
this.total = data.data.total
|
||||
this.list.forEach((item) => {
|
||||
item.cpuUsage = Number(item.cpuUsage).toFixed(2) * 1
|
||||
item.memUsage = Number(item.memUsage).toFixed(2) * 1
|
||||
switch (item.onOffStatus) {
|
||||
case '0':
|
||||
item.onOffStatus = '断开'
|
||||
break
|
||||
case '1':
|
||||
item.onOffStatus = '正常'
|
||||
break
|
||||
default:
|
||||
item.onOffStatus = '未知'
|
||||
break
|
||||
}
|
||||
const self = this
|
||||
setTimeout(function () {
|
||||
if (self.idList.indexOf(item.id) > -1) self.$refs.resourceMonitorTable.toggleRowSelection(item, true)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleSelectItem(selection, row) {
|
||||
this.refreshId()
|
||||
if (this.idList.indexOf(row.id) > -1) {
|
||||
for (let j = 0; j < this.selectList.length; j++) {
|
||||
const item = this.selectList[j]
|
||||
if (item.id == row.id) {
|
||||
this.selectList.splice(j, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.selectList.push(row)
|
||||
}
|
||||
},
|
||||
handleSelectAll(selection) {
|
||||
this.refreshId()
|
||||
if (selection.length) {
|
||||
// 全选情况下
|
||||
selection.forEach((item) => {
|
||||
if (this.idList.indexOf(item.id) == -1) {
|
||||
this.selectList.push(item)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 全不选情况下
|
||||
this.list.forEach((item) => {
|
||||
if (this.idList.indexOf(item.id) > -1) {
|
||||
for (let j = 0; j < this.selectList.length; j++) {
|
||||
const row = this.selectList[j]
|
||||
if (item.id == row.id) {
|
||||
this.selectList.splice(j, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
refreshId() {
|
||||
this.idList = []
|
||||
this.selectList.forEach((item) => {
|
||||
this.idList.push(item.id)
|
||||
})
|
||||
},
|
||||
handleSearch(params) {
|
||||
this.params.page = 1
|
||||
this.params.params = params
|
||||
this.getList()
|
||||
},
|
||||
handleLink(id, flag) {
|
||||
this.ruleGroupIds = []
|
||||
this.resourceId = id
|
||||
getRuleGroupBind(id).then((data) => {
|
||||
if (data.success) {
|
||||
this.ruleGroupIds = data.data
|
||||
this.addFlag = true
|
||||
}
|
||||
})
|
||||
},
|
||||
cancle() {
|
||||
this.addFlag = false
|
||||
this.getList()
|
||||
},
|
||||
handlePolicy(data) {
|
||||
this.handleStart(this, data, this.resourceType)
|
||||
},
|
||||
getDetail(row) {
|
||||
this.detailId = row.id
|
||||
this.detailData = {
|
||||
name: row.name
|
||||
}
|
||||
this.detailFlag = true
|
||||
},
|
||||
goBack() {
|
||||
this.detailFlag = false
|
||||
},
|
||||
handleMonitorDetail(id, name) {
|
||||
this.$router.push({
|
||||
name: 'MonitorDetailList',
|
||||
query: { id: id, name: name, type: this.resourceType }
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,66 @@
|
|||
<template>
|
||||
<div>
|
||||
<detail-map :detail="detailData" :list="detailMapList"></detail-map>
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="12" v-for="chart in typeData" :key="chart.value">
|
||||
<chart-box :params-data="chart" :item-data="dashboradData[chart.value]"></chart-box>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import detailMap from 'views/components/detailMap.vue'
|
||||
import { getCharts, getHostCpu } from 'services/monitor'
|
||||
import chartBox from 'views/components/chartBox.vue'
|
||||
export default {
|
||||
components: { detailMap, chartBox },
|
||||
props: {
|
||||
detailId: {
|
||||
type: Number
|
||||
},
|
||||
detailName: {
|
||||
type: String
|
||||
},
|
||||
address: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
detailData: {},
|
||||
typeData: [{ title: 'CPU利用率', value: 'usage', expr: JSON.stringify(['round(bocloud_cloudtower_host_host_cpu_overall_usage_percent{id="' + this.detailId + '"}, 0.01)']), name: '["cpu利用率"]', unit: '%' }],
|
||||
detailMapList: [
|
||||
{ name: 'CPU类型', value: 'cpuModel', unit: '' },
|
||||
{ name: 'CPU数量', value: 'cpuAmount', unit: '' },
|
||||
{ name: 'CPU核数', value: 'cpuCore', unit: '' },
|
||||
{ name: 'CPU总量', value: 'cpuTotal', unit: 'MHZ' },
|
||||
{ name: 'CPU使用量', value: 'cpuUsed', unit: 'MHZ' },
|
||||
{ name: 'CPU空闲量', value: 'cpuFree', unit: 'MHZ' }
|
||||
],
|
||||
dashboradData: {
|
||||
usage: {}
|
||||
},
|
||||
userDefindVisible: false,
|
||||
userDefindTime: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCpu() {
|
||||
getHostCpu(this.detailId).then((data) => {
|
||||
if (data.success) {
|
||||
this.detailData = Object.assign({}, data.data)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
for (const key in this.dashboradData) {
|
||||
const element = this.dashboradData[key]
|
||||
this.$set(element, 'step', null)
|
||||
this.$set(element, 'stepValue', 20)
|
||||
this.$set(element, 'defindTime', [])
|
||||
}
|
||||
this.getCpu()
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,60 @@
|
|||
<template>
|
||||
<div>
|
||||
<detail-map :detail="detailData" :list="detailMapList"></detail-map>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12" v-for="chart in typeData" :key="chart.value">
|
||||
<chart-box :params-data="chart" :item-data="dashboradData[chart.value]"></chart-box>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import detailMap from 'views/components/detailMap.vue'
|
||||
import { getCharts, getHostMem } from 'services/monitor'
|
||||
import chartBox from 'views/components/chartBox.vue'
|
||||
export default {
|
||||
components: { detailMap, chartBox },
|
||||
props: {
|
||||
detailId: {
|
||||
type: Number
|
||||
},
|
||||
detailName: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
typeData: [{ title: '内存利用率', value: 'usage', expr: JSON.stringify(['round(bocloud_cloudtower_host_host_memory_usage_percent{id="' + this.detailId + '"}, 0.01)']), name: "['内存利用率']", unit: '%' }],
|
||||
detailData: {},
|
||||
detailMapList: [
|
||||
{ name: '内存总量', value: 'memTotalCapacity', unit: 'GB' },
|
||||
{ name: '内存使用量', value: 'memUsed', unit: 'GB' },
|
||||
{ name: '内存空闲量', value: 'memFree', unit: 'GB' }
|
||||
],
|
||||
dashboradData: {
|
||||
usage: {}
|
||||
},
|
||||
userDefindVisible: false,
|
||||
userDefindTime: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
getHostMem(this.detailId).then((data) => {
|
||||
if (data.success) {
|
||||
this.detailData = Object.assign({}, data.data)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getDetail()
|
||||
for (const key in this.dashboradData) {
|
||||
const element = this.dashboradData[key]
|
||||
this.$set(element, 'step', null)
|
||||
this.$set(element, 'stepValue', 20)
|
||||
this.$set(element, 'defindTime', [])
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,41 @@
|
|||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12" v-for="chart in typeData" :key="chart.value">
|
||||
<chart-box :params-data="chart" :item-data="dashboradData[chart.value]"></chart-box>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<script>
|
||||
import chartBox from 'views/components/chartBox.vue'
|
||||
export default {
|
||||
components: { chartBox },
|
||||
props: {
|
||||
detailId: {
|
||||
type: Number
|
||||
},
|
||||
detailName: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
typeData: [
|
||||
{ title: '网络发送速率', value: 'read', expr: JSON.stringify(['round(bocloud_cloudtower_host_host_network_transmit_speed_bitps{id="' + this.detailId + '"}, 0.01)']), name: "['网络发送速率']", unit: 'bitps' },
|
||||
{ title: '网络接收速率', value: 'write', expr: JSON.stringify(['round(bocloud_cloudtower_host_host_network_receive_speed_bitps{id="' + this.detailId + '"}, 0.01)']), name: "['网络接收速率']", unit: 'bitps' }
|
||||
],
|
||||
dashboradData: {
|
||||
read: {},
|
||||
write: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
for (const key in this.dashboradData) {
|
||||
const element = this.dashboradData[key]
|
||||
this.$set(element, 'step', null)
|
||||
this.$set(element, 'stepValue', 20)
|
||||
this.$set(element, 'defindTime', [])
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,140 @@
|
|||
<template>
|
||||
<div>
|
||||
<detail-map :detail="detailData" :list="detailMapList"></detail-map>
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="12">
|
||||
<el-card class="box-card m-t-xs" style="height: 289px">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>使用情况</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<el-col :span="12">
|
||||
<div>CPU利用率</div>
|
||||
<gauge-charts v-if="dashboardData.cpuUsage1" height="190px" id="cpuUsage" width="100%" :data="dashboardData.cpuUsage1"></gauge-charts>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div>内存利用率</div>
|
||||
<gauge-charts v-if="dashboardData.memUsage1" height="190px" id="memUsage" width="100%" :data="dashboardData.memUsage1"></gauge-charts>
|
||||
</el-col>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12" v-for="chart in typeData" :key="chart.value">
|
||||
<chart-box :params-data="chart" :item-data="paramsOverviewChart[chart.value]"></chart-box>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import detailMap from 'views/components/detailMap.vue'
|
||||
import { getCharts, getHostDashboard, getHostDetail } from 'services/monitor'
|
||||
import chartBox from 'views/components/chartBox.vue'
|
||||
export default {
|
||||
components: {
|
||||
detailMap,
|
||||
chartBox
|
||||
},
|
||||
props: {
|
||||
detailId: {
|
||||
type: Number
|
||||
},
|
||||
detailName: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
typeData: [
|
||||
{
|
||||
title: 'CPU利用率',
|
||||
value: 'cpu',
|
||||
expr: JSON.stringify(['round(bocloud_cloudtower_host_host_cpu_overall_usage_percent{id="' + this.detailId + '"}, 0.01)']),
|
||||
name: '["cpu利用率"]',
|
||||
unit: '%'
|
||||
},
|
||||
{
|
||||
title: '内存利用率',
|
||||
value: 'mem',
|
||||
expr: JSON.stringify(['round(bocloud_cloudtower_host_host_memory_usage_percent{id="' + this.detailId + '"}, 0.01)']),
|
||||
name: "['内存利用率']",
|
||||
unit: '%'
|
||||
},
|
||||
{ title: '磁盘读取速率', value: 'read', expr: JSON.stringify(['round(bocloud_cloudtower_host_zbs_chunk_read_iops{id="' + this.detailId + '"}, 0.01)']), name: "['磁盘读取速率']", unit: '%' }
|
||||
],
|
||||
detailData: {},
|
||||
detailMapList: [
|
||||
{ name: 'IP', value: 'ip', unit: '' },
|
||||
{ name: '总CPU', value: 'cpuCapacity', unit: 'MHz', img: '/web-common-resource/img/detail/cpu.png' },
|
||||
{ name: '总内存', value: 'memoryCapacity', unit: 'GB', img: '/web-common-resource/img/detail/memorys.png' },
|
||||
{ name: '云主机', value: 'vmNum', unit: '台', img: '/web-common-resource/img/detail/vms.png' }
|
||||
],
|
||||
dashboardData: {},
|
||||
paramsOverviewChart: {
|
||||
cpu: {},
|
||||
mem: {},
|
||||
read: {},
|
||||
write: {}
|
||||
},
|
||||
userDefindTime: [],
|
||||
userDefindVisible: false,
|
||||
timeIntervalDashboard: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
getHostDetail(this.detailId, 'CLOUDTOWER').then((data) => {
|
||||
if (data.success) {
|
||||
this.detailData = Object.assign({}, data.data)
|
||||
}
|
||||
})
|
||||
},
|
||||
getDashboard() {
|
||||
const expr1 = 'round(bocloud_cloudtower_host_host_cpu_overall_usage_percent{id="' + this.detailId + '"}, 0.01)'
|
||||
const expr2 = 'round(bocloud_cloudtower_host_host_memory_usage_percent{id="' + this.detailId + '"}, 0.01)'
|
||||
getHostDashboard({
|
||||
expr: expr1,
|
||||
simple: true
|
||||
}).then((data) => {
|
||||
if (data.success) {
|
||||
this.$set(this.dashboardData, 'cpuUsage1', {
|
||||
name: 'CPU利用率',
|
||||
data: { value: data.data, name: '%' },
|
||||
min: 0,
|
||||
max: 100
|
||||
})
|
||||
}
|
||||
})
|
||||
getHostDashboard({
|
||||
expr: expr2,
|
||||
simple: true
|
||||
}).then((data) => {
|
||||
if (data.success) {
|
||||
this.$set(this.dashboardData, 'memUsage1', {
|
||||
name: '内存利用率',
|
||||
data: { value: data.data, name: '%' },
|
||||
min: 0,
|
||||
max: 100
|
||||
})
|
||||
}
|
||||
})
|
||||
if (this.timeIntervalDashboard) {
|
||||
clearInterval(this.timeIntervalDashboard)
|
||||
this.timeIntervalDashboard = ''
|
||||
}
|
||||
this.timeIntervalDashboard = setInterval(() => {
|
||||
this.getDashboard()
|
||||
}, 60 * 1000)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getDetail()
|
||||
this.getDashboard()
|
||||
for (const key in this.paramsOverviewChart) {
|
||||
const element = this.paramsOverviewChart[key]
|
||||
this.$set(element, 'step', null)
|
||||
this.$set(element, 'stepValue', 20)
|
||||
this.$set(element, 'defindTime', [])
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<div>
|
||||
<detail-map :detail="detailData" :list="detailMapList"></detail-map>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12" v-for="chart in typeData" :key="chart.value">
|
||||
<chart-box :params-data="chart" :item-data="dashboradData[chart.value]"></chart-box>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import detailMap from 'views/components/detailMap.vue'
|
||||
import { getCharts, getHostDisk } from 'services/monitor'
|
||||
import chartBox from 'views/components/chartBox.vue'
|
||||
export default {
|
||||
components: { detailMap, chartBox },
|
||||
props: {
|
||||
detailId: {
|
||||
type: Number
|
||||
},
|
||||
detailName: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
typeData: [
|
||||
{ title: '磁盘读取速率', value: 'read', expr: JSON.stringify(['round(bocloud_cloudtower_host_zbs_chunk_read_iops{id="' + this.detailId + '"}, 0.01)']), name: "['磁盘读取速率']", unit: '%' },
|
||||
{ title: '磁盘写入速率', value: 'write', expr: JSON.stringify(['round(bocloud_cloudtower_host_zbs_chunk_write_iops{id="' + this.detailId + '"}, 0.01)']), name: "['磁盘读取速率']", unit: '%' }
|
||||
],
|
||||
detailData: {},
|
||||
detailMapList: [
|
||||
{ name: '磁盘总量', value: 'diskCapacity', unit: 'GB' },
|
||||
{ name: '磁盘使用量', value: 'diskUsed', unit: 'GB' },
|
||||
{ name: '磁盘空闲量', value: 'diskFree', unit: 'GB' }
|
||||
],
|
||||
dashboradData: {
|
||||
read: {},
|
||||
write: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
getHostDisk(this.detailId).then((data) => {
|
||||
if (data.success) {
|
||||
this.detailData = Object.assign({}, data.data)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getDetail()
|
||||
for (const key in this.dashboradData) {
|
||||
const element = this.dashboradData[key]
|
||||
this.$set(element, 'step', null)
|
||||
this.$set(element, 'stepValue', 20)
|
||||
this.$set(element, 'defindTime', [])
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,80 @@
|
|||
<template>
|
||||
<el-dialog title="自定义时间" :close-on-click-modal="false" v-if="userDefindVisible" :visible.sync="userDefindVisible" append-to-body>
|
||||
<basic-form>
|
||||
<basic-form-item label="选择时间:">
|
||||
<el-date-picker
|
||||
v-model="time"
|
||||
type="datetimerange"
|
||||
size="mini"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="timestamp"
|
||||
:picker-options="pickerOptions"></el-date-picker>
|
||||
</basic-form-item>
|
||||
</basic-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="ghost" @click.native="close">取消</el-button>
|
||||
<el-button type="primary" @click.native="userDefindSubmit">确定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
props: {
|
||||
userDefindVisible: {
|
||||
type: Boolean
|
||||
},
|
||||
userDefindTime: {
|
||||
type: Array
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
time: [],
|
||||
pickerMinDate: '',
|
||||
dateRange: [],
|
||||
pickerOptions: {
|
||||
onPick: ({ maxDate, minDate }) => {
|
||||
this.pickerMinDate = minDate.getTime()
|
||||
if (maxDate) {
|
||||
this.pickerMinDate = ''
|
||||
}
|
||||
},
|
||||
disabledDate: (time) => {
|
||||
if (this.pickerMinDate !== '') {
|
||||
const day14 = (14 - 1) * 24 * 3600 * 1000
|
||||
let maxTime = this.pickerMinDate + day14
|
||||
const minTime = this.pickerMinDate - day14
|
||||
if (maxTime > new Date()) {
|
||||
maxTime = new Date()
|
||||
}
|
||||
return time.getTime() > maxTime || time.getTime() < minTime
|
||||
}
|
||||
return time.getTime() > Date.now()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.time = [];
|
||||
if (this.userDefindTime.length) {
|
||||
this.time.push(this.userDefindTime[0], this.userDefindTime[1])
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
userDefindSubmit () {
|
||||
if (this.time && this.time.length && this.time[0] != undefined) {
|
||||
this.$emit('getData', this.time);
|
||||
} else {
|
||||
return this.$message.error('请选择自定义时间!');
|
||||
}
|
||||
},
|
||||
close () {
|
||||
this.$emit('getData');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,55 @@
|
|||
<template>
|
||||
<el-card>
|
||||
<el-tabs v-model="activeName" class="m-t-n-md">
|
||||
<el-tab-pane name="overview" label="资源总览">
|
||||
<overview ref="overview" v-if="activeName == 'overview'" :detail-id="detailId" :detail-name="detailName"></overview>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="cpu" label="CPU">
|
||||
<cpu ref="cpu" v-if="activeName == 'cpu'" :detail-id="detailId" :detail-name="detailName"></cpu>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="mem" label="内存">
|
||||
<mem ref="mem" v-if="activeName == 'mem'" :detail-id="detailId" :detail-name="detailName"></mem>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="storage" label="磁盘">
|
||||
<storage ref="storage" v-if="activeName == 'storage'" :detail-id="detailId" :detail-name="detailName"></storage>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="net" label="网络">
|
||||
<net ref="net" v-if="activeName == 'net'" :detail-id="detailId" :detail-name="detailName"></net>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import overview from './hostDetail/overview.vue'
|
||||
import cpu from './hostDetail/cpu.vue'
|
||||
import mem from './hostDetail/mem.vue'
|
||||
import storage from './hostDetail/storage.vue'
|
||||
import net from './hostDetail/net.vue'
|
||||
export default {
|
||||
components: {
|
||||
overview,
|
||||
cpu,
|
||||
mem,
|
||||
storage,
|
||||
net
|
||||
},
|
||||
props: {
|
||||
detailId: {
|
||||
type: Number
|
||||
},
|
||||
detailName: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeName: 'overview'
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
created() {},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
<style scoped></style>
|
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<el-card class="wrapper">
|
||||
<div slot="header" class="clearfix">
|
||||
<div class="detail-header">
|
||||
<span class="detail-back" @click="goBack"><i class="iconfont icon-left-arrow"></i> 返回</span>
|
||||
<span class="line"></span>
|
||||
<span class="title">{{ $route.query.vendorName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-tabs ref="resourceMonitorTab" type="card" @tab-click="handleClick" v-model="activeName">
|
||||
<el-tab-pane name="dashboard" label="概览">
|
||||
<dashboard ref="Dashboard" v-if="activeName == 'dashboard'"></dashboard>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="host" label="宿主机">
|
||||
<host v-if="activeName == 'host'" ref="monitorHost"></host>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="vm" label="云主机">
|
||||
<vm v-if="activeName == 'vm'" ref="monitorVm"></vm>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import host from './host.vue'
|
||||
import vm from './vm.vue'
|
||||
import dashboard from 'views/components/dashboard.vue'
|
||||
export default {
|
||||
components: {
|
||||
dashboard,
|
||||
host,
|
||||
vm
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeName: 'dashboard'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick() {},
|
||||
goBack() {
|
||||
history.go(-1)
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.detail-header .detail-back {
|
||||
color: #46abf1;
|
||||
cursor: pointer;
|
||||
}
|
||||
.detail-header .line {
|
||||
position: relative;
|
||||
top: 4px;
|
||||
margin: 0 6px;
|
||||
height: 14px;
|
||||
width: 1px;
|
||||
display: inline-block;
|
||||
background-color: #b5b5b5;
|
||||
}
|
||||
|
||||
.detail_icon {
|
||||
font-size: 25px;
|
||||
margin: 10px;
|
||||
color: #409eff;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,187 @@
|
|||
<template>
|
||||
<div class="wrapper">
|
||||
<div>
|
||||
<div slot="header" class="clearfix">
|
||||
<div class="detail-header">
|
||||
<span class="detail-back" @click="goBack"><i class="iconfont icon-left-arrow"></i> 返回</span>
|
||||
<span class="line"></span>
|
||||
<span class="title">{{ $route.query.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-tabs ref="monitorList" v-model="activeName" type="border-card">
|
||||
<el-tab-pane label="当前告警" name="current">
|
||||
<current-monitor v-if="activeName == 'current'" :target="target" :typeName="type" ref="currentMonitor"></current-monitor>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="历史告警" name="history">
|
||||
<history-monitor v-if="activeName == 'history'" :target="target" :typeName="type" ref="historyMonitor"></history-monitor>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-row class="m-t-xs" :gutter="5">
|
||||
<el-col :span="10">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>告警统计</span>
|
||||
</div>
|
||||
<pie-charts ref="chart1" v-if="chart1Data" id="chart1" :data="chart1Data" width="100%" :setting="{ color: ['#EC1C24', '#FF7F27', '#FFF200', '#4EAFF5'] }" height="250px" theme="告警统计"></pie-charts>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>告警统计</span>
|
||||
<span class="pull-right">
|
||||
<el-button-group>
|
||||
<el-button size="mini" :type="item.value == chart2.step ? 'primary' : ''" v-for="item in intervalData" :key="item.value" @click="changeInterval(item.value)">{{ item.name }}</el-button>
|
||||
<el-button size="mini" :type="chart2.step === 0 ? 'primary' : ''" @click="userDefind()">自定义</el-button>
|
||||
</el-button-group>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<bar-charts ref="chart2" height="250px" width="100%" id="cpu" :data="chart2Data" :setting="{ color: ['#EC1C24', '#FF7F27', '#FFF200', '#4EAFF5'] }" v-if="chart2Data"></bar-charts>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-dialog title="自定义时间" :close-on-click-modal="false" v-if="userDefindVisible" :visible.sync="userDefindVisible">
|
||||
<basic-form>
|
||||
<basic-form-item label="选择时间:">
|
||||
<el-date-picker v-model="userDefindTime2" type="datetimerange" size="mini" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="timestamp" :picker-options="pickerOptions"></el-date-picker>
|
||||
</basic-form-item>
|
||||
</basic-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="ghost" @click.native="close">取消</el-button>
|
||||
<el-button type="primary" @click.native="userDefindSubmit">确定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import currentMonitor from './currentMonitor.vue'
|
||||
import historyMonitor from './historyMonitor.vue'
|
||||
import { getAlarmChart } from 'services/monitor'
|
||||
const intervalData = [
|
||||
{ name: '7D', value: '7' },
|
||||
{ name: '15D', value: '15' },
|
||||
{ name: '1M', value: '30' }
|
||||
]
|
||||
export default {
|
||||
components: {
|
||||
currentMonitor,
|
||||
historyMonitor
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
intervalData,
|
||||
target: this.$route.query.id,
|
||||
type: this.$route.query.type,
|
||||
activeName: 'current',
|
||||
chart1Data: null,
|
||||
chart2Data: null,
|
||||
chart2: {
|
||||
step: null
|
||||
},
|
||||
userDefindTime: [],
|
||||
userDefindTime2: [],
|
||||
userDefindVisible: false,
|
||||
pickerOptions: {
|
||||
disabledDate: (time) => {
|
||||
return time.getTime() > Date.now()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getPieData()
|
||||
this.changeInterval(7)
|
||||
},
|
||||
beforeDestroy() {},
|
||||
methods: {
|
||||
getPieData() {
|
||||
getAlarmChart({
|
||||
action: 'pieChart',
|
||||
target: this.target,
|
||||
type: this.type
|
||||
}).then((data) => {
|
||||
if (data.success) {
|
||||
this.chart1Data = data.data
|
||||
}
|
||||
})
|
||||
},
|
||||
getBarData() {
|
||||
getAlarmChart({
|
||||
action: 'barChart',
|
||||
target: this.target,
|
||||
type: this.type,
|
||||
start: this.chart2.start,
|
||||
end: this.chart2.end
|
||||
}).then((data) => {
|
||||
if (data.success) {
|
||||
this.chart2Data = data.data
|
||||
}
|
||||
})
|
||||
},
|
||||
// 改变周期
|
||||
changeInterval(value) {
|
||||
this.userDefindTime = []
|
||||
this.userDefindTime2 = []
|
||||
this.chart2.step = value
|
||||
// 获取当天 0 点的时间戳
|
||||
const timeStamp = new Date(new Date().setHours(0, 0, 0, 0)) / 1000
|
||||
this.chart2.end = timeStamp
|
||||
// 一天是86400秒 故 value 天前的时间戳为
|
||||
this.chart2.start = timeStamp - 86400 * value
|
||||
this.getBarData()
|
||||
},
|
||||
userDefind() {
|
||||
this.userDefindTime2 = Object.assign([], this.userDefindTime)
|
||||
this.userDefindVisible = true
|
||||
},
|
||||
userDefindSubmit() {
|
||||
this.userDefindTime = Object.assign([], this.userDefindTime2)
|
||||
if (this.userDefindTime.length) {
|
||||
this.chart2.step = 0
|
||||
this.chart2.end = Math.round(this.userDefindTime[1] / 1000)
|
||||
this.chart2.start = Math.round(this.userDefindTime[0] / 1000)
|
||||
this.getBarData()
|
||||
this.userDefindVisible = false
|
||||
} else {
|
||||
return this.$message.error('请选择自定义时间!')
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.userDefindVisible = false
|
||||
},
|
||||
goBack() {
|
||||
history.go(-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.detail-header {
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #e6e6e6;
|
||||
}
|
||||
.detail-header .detail-back {
|
||||
color: #46abf1;
|
||||
cursor: pointer;
|
||||
}
|
||||
.detail-header .line {
|
||||
position: relative;
|
||||
top: 4px;
|
||||
margin: 0 6px;
|
||||
height: 14px;
|
||||
width: 1px;
|
||||
display: inline-block;
|
||||
background-color: #b5b5b5;
|
||||
}
|
||||
|
||||
.detail_icon {
|
||||
font-size: 25px;
|
||||
margin: 10px;
|
||||
color: #409eff;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,274 @@
|
|||
<template>
|
||||
<div>
|
||||
<AdvanceTable title="" :search-configs="searchConfigs" :data="list" :params="params" :columns="vmColumns" :get-list="getList" :total="total" :loading="loading" @select="handleSelectItem" @select-all="handleSelectAll" ref="resourceMonitorTable">
|
||||
<template #name="val, record">
|
||||
<span class="detail-href" @click="getDetail(record)">{{ val }}</span>
|
||||
</template>
|
||||
<template #privateIps="privateIps, record">
|
||||
{{ record.managerIp }}
|
||||
</template>
|
||||
<template #status="status">
|
||||
<status-icon :type="vmStatusColorFilter(status)">{{ vmStatusFilter(status) }} </status-icon>
|
||||
</template>
|
||||
<template #cpuUsage="cpuUsage">
|
||||
<el-progress class="progress" :color="customColorMethod" text-inside :stroke-width="16" :percentage="cpuUsage ? cpuUsage : 0"></el-progress>
|
||||
</template>
|
||||
<template #memUsage="memUsage">
|
||||
<el-progress class="progress" :color="customColorMethod" text-inside :stroke-width="16" :percentage="memUsage ? memUsage : 0"></el-progress>
|
||||
</template>
|
||||
<template #onOffStatus="onOffStatus">
|
||||
<status-icon :type="statusOnColorFilter(onOffStatus)">
|
||||
{{ onOffStatus }}
|
||||
</status-icon>
|
||||
</template>
|
||||
<template #responseTime="responseTime">
|
||||
<span v-if="responseTime">{{ responseTime }}ms</span>
|
||||
<span v-else>未知</span>
|
||||
</template>
|
||||
<template #operate="val, record">
|
||||
<el-button type="text" @click="handleMonitorDetail(record.id, record.name)"> 告警详情</el-button>
|
||||
<div class="action-divider"></div>
|
||||
<el-dropdown trigger="click">
|
||||
<span class="el-dropdown-link"> 更多<i class="el-icon-arrow-down el-icon--right"></i> </span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="handleLink(record.id)"> 关联规则 </el-dropdown-item>
|
||||
<el-dropdown-item @click.native="handlePolicy(record)">
|
||||
{{ `${record.alarmEnable ? '屏蔽' : '开启'}告警` }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="setIP(record)"> 设置监控IP </el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</AdvanceTable>
|
||||
<add-policy v-if="addFlag" resourceType="MONITOR_CLOUDTOWER_VM" @cancle="cancle" :add-link-flag="addFlag" :resourceId="resourceId" :ruleGroupIds="ruleGroupIds"></add-policy>
|
||||
<el-dialog title="设置监控IP" :visible.sync="setIPFlag" v-if="setIPFlag">
|
||||
<el-row>
|
||||
<basic-form ref="setData" :model="setData" :status-icon="true">
|
||||
<el-col :span="24">
|
||||
<basic-form-item label="IP地址:" prop="ip" validate="required">
|
||||
<el-select filterable clearable v-model="setData.ip">
|
||||
<el-option v-for="(item, index) in ipData" :key="index" :label="item.address" :value="item.address"></el-option>
|
||||
</el-select>
|
||||
</basic-form-item>
|
||||
</el-col>
|
||||
</basic-form>
|
||||
</el-row>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="ghost" @click.native="setIPFlag = false">取 消</el-button>
|
||||
<el-button type="primary" @click.native="setSubmit">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<common-detail v-if="detailFlag" :title="detailData.name" @goBack="goBack">
|
||||
<div slot="custom_content">
|
||||
<detail :detail-id="detailId" :identifier="identifier" :host-name="hostName" :bios-uuid="biosUuid"></detail>
|
||||
</div>
|
||||
</common-detail>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { statusOnColorFilter, vmStatusFilter, vmStatusColorFilter } from '@/filters/index'
|
||||
import { getVms, setIps, getRuleGroupBind } from 'services/monitor/index.js'
|
||||
import { vmColumns, customColorMethod, handleStart } from 'views/data'
|
||||
import detail from './vm_detail.vue'
|
||||
import addPolicy from 'views/components/linkPolicy.vue'
|
||||
export default {
|
||||
components: {
|
||||
detail,
|
||||
addPolicy
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
statusOnColorFilter,
|
||||
vmStatusFilter,
|
||||
vmStatusColorFilter,
|
||||
vmColumns,
|
||||
handleStart,
|
||||
searchConfigs: [
|
||||
{ type: 'Input', label: '名称', value: 'name' },
|
||||
{ type: 'Input', label: 'IP', value: 'privateIps' },
|
||||
{
|
||||
type: 'Select',
|
||||
label: '状态',
|
||||
value: 'status',
|
||||
data: [
|
||||
{ id: 'RUNNING', name: '运行中' },
|
||||
{ id: 'BUILDING', name: '创建中' },
|
||||
{ id: 'STOPPED', name: '关机' },
|
||||
{ id: 'SUSPENDED', name: '挂起' },
|
||||
{ id: 'EXCEPTION', name: '异常' },
|
||||
{ id: 'UNKNOWN', name: '断开' }
|
||||
]
|
||||
},
|
||||
{ type: 'Const', value: 'vendorType', initValue: 'CLOUDTOWER' },
|
||||
{ type: 'Const', value: 'vendorId', initValue: this.$route.query.vendorId },
|
||||
{ type: 'Const', value: 'isTemplate', initValue: false }
|
||||
],
|
||||
customColorMethod,
|
||||
params: {
|
||||
page: 1,
|
||||
rows: 10
|
||||
},
|
||||
list: [],
|
||||
total: 0,
|
||||
idList: [],
|
||||
selectList: [],
|
||||
detailFlag: false,
|
||||
detailId: null,
|
||||
identifier: '',
|
||||
setData: {},
|
||||
ipData: [],
|
||||
setIPFlag: false,
|
||||
loading: false,
|
||||
hostName: '',
|
||||
addFlag: false,
|
||||
resourceId: 0,
|
||||
ruleGroupIds: [],
|
||||
biosUuid: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.refreshId()
|
||||
this.loading = true
|
||||
getVms(this.params).then((data) => {
|
||||
this.loading = false
|
||||
if (data.success) {
|
||||
this.list = data.data.rows
|
||||
this.total = data.data.total
|
||||
this.list.forEach((item) => {
|
||||
item.cpuUsage = Number(item.cpuUsage)
|
||||
item.memUsage = Number(item.memUsage)
|
||||
if (item.privateIps) {
|
||||
item.privateIps = JSON.parse(item.privateIps)
|
||||
}
|
||||
switch (item.onOffStatus) {
|
||||
case '0':
|
||||
item.onOffStatus = '断开'
|
||||
break
|
||||
case '1':
|
||||
item.onOffStatus = '正常'
|
||||
break
|
||||
default:
|
||||
item.onOffStatus = '未知'
|
||||
break
|
||||
}
|
||||
const self = this
|
||||
setTimeout(function () {
|
||||
if (self.idList.indexOf(item.id) > -1) self.$refs.resourceMonitorTable.toggleRowSelection(item, true)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleSelectItem(selection, row) {
|
||||
this.refreshId()
|
||||
if (this.idList.indexOf(row.id) > -1) {
|
||||
for (let j = 0; j < this.selectList.length; j++) {
|
||||
const item = this.selectList[j]
|
||||
if (item.id == row.id) {
|
||||
this.selectList.splice(j, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.selectList.push(row)
|
||||
}
|
||||
},
|
||||
handleSelectAll(selection) {
|
||||
this.refreshId()
|
||||
if (selection.length) {
|
||||
// 全选情况下
|
||||
selection.forEach((item) => {
|
||||
if (this.idList.indexOf(item.id) == -1) {
|
||||
this.selectList.push(item)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 全不选情况下
|
||||
this.list.forEach((item) => {
|
||||
if (this.idList.indexOf(item.id) > -1) {
|
||||
for (let j = 0; j < this.selectList.length; j++) {
|
||||
const row = this.selectList[j]
|
||||
if (item.id == row.id) {
|
||||
this.selectList.splice(j, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
refreshId() {
|
||||
this.idList = []
|
||||
this.selectList.forEach((item) => {
|
||||
this.idList.push(item.id)
|
||||
})
|
||||
},
|
||||
handleSearch(params) {
|
||||
this.params.page = 1
|
||||
this.params.params = params
|
||||
this.getList()
|
||||
},
|
||||
handleLink(id, flag) {
|
||||
this.ruleGroupIds = []
|
||||
this.resourceId = id
|
||||
getRuleGroupBind(id).then((data) => {
|
||||
if (data.success) {
|
||||
this.ruleGroupIds = data.data
|
||||
this.addFlag = true
|
||||
}
|
||||
})
|
||||
},
|
||||
cancle() {
|
||||
this.addFlag = false
|
||||
this.getList()
|
||||
},
|
||||
handlePolicy(data) {
|
||||
this.handleStart(this, data, 'MONITOR_CLOUDTOWER_VM')
|
||||
},
|
||||
getDetail(row) {
|
||||
this.detailId = row.id
|
||||
this.identifier = row.name
|
||||
this.hostName = row.hostName
|
||||
this.biosUuid = row.biosUuid
|
||||
this.detailData = {
|
||||
name: row.name
|
||||
}
|
||||
this.detailFlag = true
|
||||
},
|
||||
goBack() {
|
||||
this.detailFlag = false
|
||||
},
|
||||
handleMonitorDetail(id, name) {
|
||||
this.$router.push({
|
||||
name: 'MonitorDetailList',
|
||||
query: { id: id, name: name, type: 'MONITOR_CLOUDTOWER_VM' }
|
||||
})
|
||||
},
|
||||
setIP(row) {
|
||||
this.setData = {
|
||||
id: row.id,
|
||||
ip: row.monitorIp
|
||||
}
|
||||
this.ipData = row.privateIps
|
||||
this.setIPFlag = true
|
||||
},
|
||||
setSubmit() {
|
||||
this.$refs.setData.validate((valid) => {
|
||||
if (valid) {
|
||||
setIps(this.setData).then((data) => {
|
||||
this.$notify({
|
||||
message: data.message,
|
||||
type: 'success'
|
||||
})
|
||||
this.setIPFlag = false
|
||||
this.getList()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="12" v-for="chart in typeData" :key="chart.value">
|
||||
<chart-box :params-data="chart" :item-data="dashboradData[chart.value]"></chart-box>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import chartBox from 'views/components/chartBox.vue'
|
||||
import { init } from 'views/components/util'
|
||||
export default {
|
||||
components: { chartBox },
|
||||
props: {
|
||||
detailId: {
|
||||
type: Number
|
||||
},
|
||||
identifier: {
|
||||
type: String
|
||||
},
|
||||
hostName: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
typeData: [
|
||||
{
|
||||
title: 'CPU利用率',
|
||||
value: 'usage',
|
||||
expr: JSON.stringify(['round(bocloud_cloudtower_vm_elf_vm_cpu_overall_usage_percent{id="' + this.detailId + '"}, 0.01)']),
|
||||
name: "['CPU利用率']",
|
||||
unit: '%'
|
||||
}
|
||||
],
|
||||
dashboradData: {
|
||||
usage: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {},
|
||||
methods: {},
|
||||
created() {
|
||||
for (const key in this.dashboradData) {
|
||||
const element = this.dashboradData[key]
|
||||
this.$set(element, 'step', null)
|
||||
this.$set(element, 'stepValue', 20)
|
||||
this.$set(element, 'defindTime', [])
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,50 @@
|
|||
<template>
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="12" v-for="chart in typeData" :key="chart.value">
|
||||
<chart-box :params-data="chart" :item-data="dashboradData[chart.value]"></chart-box>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<script>
|
||||
import chartBox from 'views/components/chartBox.vue'
|
||||
export default {
|
||||
components: { chartBox },
|
||||
props: {
|
||||
detailId: {
|
||||
type: Number
|
||||
},
|
||||
identifier: {
|
||||
type: String
|
||||
},
|
||||
hostName: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
typeData: [
|
||||
{
|
||||
title: '内存利用率',
|
||||
value: 'usage',
|
||||
expr: JSON.stringify(['round(bocloud_cloudtower_vm_elf_vm_memory_usage_percent{id="' + this.detailId + '"}, 0.01)']),
|
||||
name: "['内存利用率']",
|
||||
unit: '%'
|
||||
}
|
||||
],
|
||||
dashboradData: {
|
||||
usage: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
created() {
|
||||
for (const key in this.dashboradData) {
|
||||
const element = this.dashboradData[key]
|
||||
this.$set(element, 'step', null)
|
||||
this.$set(element, 'stepValue', 20)
|
||||
this.$set(element, 'defindTime', [])
|
||||
}
|
||||
},
|
||||
beforeDestroy() {}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,41 @@
|
|||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12" v-for="chart in typeData" :key="chart.value">
|
||||
<chart-box :params-data="chart" :item-data="dashboradData[chart.value]"></chart-box>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<script>
|
||||
import chartBox from 'views/components/chartBox.vue'
|
||||
export default {
|
||||
components: { chartBox },
|
||||
props: {
|
||||
detailId: {
|
||||
type: Number
|
||||
},
|
||||
detailName: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
typeData: [
|
||||
{ title: '网络发送速率', value: 'read', expr: JSON.stringify(['round(bocloud_cloudtower_vm_elf_vm_network_transmit_speed_bps{id="' + this.detailId + '"}, 0.01)']), name: "['网络发送速率']", unit: 'bitps' },
|
||||
{ title: '网络接收速率', value: 'write', expr: JSON.stringify(['round(bocloud_cloudtower_vm_elf_vm_network_receive_speed_bps{id="' + this.detailId + '"}, 0.01)']), name: "['网络接收速率']", unit: 'bitps' }
|
||||
],
|
||||
dashboradData: {
|
||||
read: {},
|
||||
write: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
for (const key in this.dashboradData) {
|
||||
const element = this.dashboradData[key]
|
||||
this.$set(element, 'step', null)
|
||||
this.$set(element, 'stepValue', 20)
|
||||
this.$set(element, 'defindTime', [])
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,151 @@
|
|||
<template>
|
||||
<div>
|
||||
<detail-map :detail="detailData" :list="detailMapList" v-if="isShow"></detail-map>
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="24">
|
||||
<el-col :span="12">
|
||||
<el-card class="box-card m-t-xs" style="height: 300px">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>使用情况</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<el-col :span="12">
|
||||
<div>CPU利用率</div>
|
||||
<gauge-charts v-if="dashboardData.cpuUsage1" height="190px" id="cpuUsage" width="100%" :data="dashboardData.cpuUsage1"></gauge-charts>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div>内存利用率</div>
|
||||
<gauge-charts v-if="dashboardData.memUsage1" height="190px" id="memUsage" width="100%" :data="dashboardData.memUsage1"></gauge-charts>
|
||||
</el-col>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12" v-for="chart in typeData" :key="chart.value">
|
||||
<chart-box :params-data="chart" :item-data="dashboardDataChart[chart.value]"></chart-box>
|
||||
</el-col>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import chartBox from 'views/components/chartBox.vue'
|
||||
import detailMap from 'views/components/detailMap.vue'
|
||||
import { getHostDashboard } from 'services/monitor'
|
||||
import { detailVm } from 'services/platform/index'
|
||||
export default {
|
||||
components: {
|
||||
chartBox,
|
||||
detailMap
|
||||
},
|
||||
props: {
|
||||
detailId: {
|
||||
type: Number
|
||||
},
|
||||
identifier: {
|
||||
type: String
|
||||
},
|
||||
hostName: {
|
||||
type: String
|
||||
},
|
||||
isShow: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.timeIntervalDashboard)
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
typeData: [
|
||||
{
|
||||
title: 'CPU利用率',
|
||||
value: 'cpu',
|
||||
expr: JSON.stringify(['round(bocloud_cloudtower_vm_elf_vm_cpu_overall_usage_percent{id="' + this.detailId + '"}, 0.01)']),
|
||||
name: '["CPU利用率"]',
|
||||
unit: '%'
|
||||
},
|
||||
{
|
||||
title: '内存利用率',
|
||||
value: 'mem',
|
||||
expr: JSON.stringify(['round(bocloud_cloudtower_vm_elf_vm_memory_usage_percent{id="' + this.detailId + '"}, 0.01)']),
|
||||
name: '["内存利用率"]',
|
||||
unit: '%'
|
||||
}
|
||||
],
|
||||
dashboardDataChart: {
|
||||
cpu: {},
|
||||
mem: {},
|
||||
read: {}
|
||||
},
|
||||
detailData: {},
|
||||
detailMapList: [
|
||||
// { name: '名称', value: 'name', unit: '' },
|
||||
{ name: 'IP', value: 'managerIp', unit: '' },
|
||||
{ name: '规格', value: 'spec' },
|
||||
{ name: '创建时间', value: 'gmtCreate', unit: '' },
|
||||
{ name: '操作系统', value: 'osCategory' }
|
||||
],
|
||||
dashboardData: {},
|
||||
timeIntervalDashboard: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
detailVm(this.detailId).then((data) => {
|
||||
if (data.success) {
|
||||
this.detailData = Object.assign({}, data.data)
|
||||
this.detailData.privateIps = JSON.parse(this.detailData.privateIps)
|
||||
this.detailData.spec = (this.detailData.cpu ? this.detailData.cpu : 0) + 'C/' + (this.detailData.memory ? this.detailData.memory : 0) + 'GB/'
|
||||
}
|
||||
})
|
||||
},
|
||||
getDashboard() {
|
||||
const expr1 = 'round(bocloud_cloudtower_vm_elf_vm_cpu_overall_usage_percent{id="' + this.detailId + '"}, 0.01)'
|
||||
const expr2 = 'round(bocloud_cloudtower_vm_elf_vm_memory_usage_percent{id="' + this.detailId + '"}, 0.01)'
|
||||
getHostDashboard({
|
||||
expr: expr1,
|
||||
simple: true
|
||||
}).then((data) => {
|
||||
if (data.success) {
|
||||
this.$set(this.dashboardData, 'cpuUsage1', {
|
||||
name: 'CPU利用率',
|
||||
data: { value: data.data, name: '%' },
|
||||
min: 0,
|
||||
max: 100
|
||||
})
|
||||
}
|
||||
})
|
||||
getHostDashboard({
|
||||
expr: expr2,
|
||||
simple: true
|
||||
}).then((data) => {
|
||||
if (data.success) {
|
||||
this.$set(this.dashboardData, 'memUsage1', {
|
||||
name: '内存利用率',
|
||||
data: { value: data.data, name: '%' },
|
||||
min: 0,
|
||||
max: 100
|
||||
})
|
||||
}
|
||||
})
|
||||
if (this.timeIntervalDashboard) {
|
||||
clearInterval(this.timeIntervalDashboard)
|
||||
this.timeIntervalDashboard = ''
|
||||
}
|
||||
this.timeIntervalDashboard = setInterval(() => {
|
||||
this.getDashboard()
|
||||
}, 60 * 1000)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
for (const key in this.dashboardDataChart) {
|
||||
const element = this.dashboardDataChart[key]
|
||||
this.$set(element, 'step', null)
|
||||
this.$set(element, 'stepValue', 20)
|
||||
this.$set(element, 'defindTime', [])
|
||||
}
|
||||
this.getDetail()
|
||||
this.getDashboard()
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,47 @@
|
|||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12" v-for="chart in typeData" :key="chart.value">
|
||||
<chart-box :params-data="chart" :item-data="dashboradData[chart.value]"></chart-box>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<script>
|
||||
import chartBox from 'views/components/chartBox.vue'
|
||||
export default {
|
||||
components: { chartBox },
|
||||
props: {
|
||||
detailId: {
|
||||
type: Number
|
||||
},
|
||||
detailName: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
typeData: [
|
||||
{ title: '磁盘读取速率', value: 'read', expr: JSON.stringify(['round(bocloud_cloudtower_vm_elf_vm_disk_overall_read_iops{id="' + this.detailId + '"}, 0.01)']), name: "['磁盘读取速率']", unit: '%' },
|
||||
{ title: '磁盘写入速率', value: 'write', expr: JSON.stringify(['round(bocloud_cloudtower_vm_elf_vm_disk_overall_write_iops{id="' + this.detailId + '"}, 0.01)']), name: "['磁盘读取速率']", unit: '%' }
|
||||
],
|
||||
detailData: {},
|
||||
detailMapList: [
|
||||
{ name: '磁盘总量', value: 'diskCapacity', unit: 'GB' },
|
||||
{ name: '磁盘使用量', value: 'diskUsed', unit: 'GB' },
|
||||
{ name: '磁盘空闲量', value: 'diskFree', unit: 'GB' }
|
||||
],
|
||||
dashboradData: {
|
||||
read: {},
|
||||
write: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
for (const key in this.dashboradData) {
|
||||
const element = this.dashboradData[key]
|
||||
this.$set(element, 'step', null)
|
||||
this.$set(element, 'stepValue', 20)
|
||||
this.$set(element, 'defindTime', [])
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,68 @@
|
|||
<template>
|
||||
<el-card>
|
||||
<el-tabs v-model="activeName" class="m-t-n-md">
|
||||
<el-tab-pane name="overview" label="资源概览">
|
||||
<overview ref="overview" v-if="activeName == 'overview'" :detail-id="detailId" :identifier="identifier" :host-name="hostName" :is-show="isShow"></overview>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="cpu" label="CPU">
|
||||
<cpu ref="cpu" v-if="activeName == 'cpu'" :detail-id="detailId" :identifier="identifier" :host-name="hostName"></cpu>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="mem" label="内存">
|
||||
<mem ref="mem" v-if="activeName == 'mem'" :detail-id="detailId" :identifier="identifier" :host-name="hostName"></mem>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="storage" label="磁盘">
|
||||
<storage ref="storage" v-if="activeName == 'storage'" :detail-id="detailId" :detail-name="detailName"></storage>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="net" label="网络">
|
||||
<net ref="net" v-if="activeName == 'net'" :detail-id="detailId" :detail-name="detailName"></net>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import overview from './vmDetail/overview.vue'
|
||||
import cpu from './vmDetail/cpu.vue'
|
||||
import mem from './vmDetail/mem.vue'
|
||||
import storage from './vmDetail/storage.vue'
|
||||
import net from './vmDetail/net.vue'
|
||||
export default {
|
||||
components: {
|
||||
overview,
|
||||
cpu,
|
||||
mem,
|
||||
storage,
|
||||
net
|
||||
},
|
||||
props: {
|
||||
detailId: {
|
||||
type: Number
|
||||
},
|
||||
identifier: {
|
||||
type: String
|
||||
},
|
||||
detailName: {
|
||||
type: String
|
||||
},
|
||||
hostName: {
|
||||
type: String
|
||||
},
|
||||
biosUuid: {
|
||||
type: String
|
||||
},
|
||||
isShow: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeName: 'overview'
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
created() {},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
<style scoped></style>
|
|
@ -201,6 +201,39 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="server-body" @click="go(item)" v-if="item.type == 'CLOUDTOWER'">
|
||||
<el-row>
|
||||
<el-col :span="12" class="body-left">
|
||||
<div class="body-left-header">
|
||||
<img src="/web-common-resource/img/platform/cloudTower.png" alt="" />
|
||||
</div>
|
||||
<div class="body-left-body" :class="{ colorRed: item.flag, colorWarn: item.warnFlag }">
|
||||
{{ platformStatusFilter(item.status) }}
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12" class="body-right">
|
||||
<div class="tag-box">
|
||||
<div class="tag">
|
||||
<el-col :span="12">宿主机</el-col>
|
||||
<el-col :span="7" class="tag1">{{ item.hostCount }}</el-col>
|
||||
<el-col :span="2" :offset="1">个</el-col>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="tag">
|
||||
<el-col :span="12">云主机</el-col>
|
||||
<el-col :span="7" class="tag1">{{ item.instance }}</el-col>
|
||||
<el-col :span="2" :offset="1">个</el-col>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="tag">
|
||||
<el-col :span="12">监控</el-col>
|
||||
<el-col :span="10" :class="item.isAlarm ? 'tag2' : 'tag3'">{{ item.isAlarm ? '已开启' : '已关闭' }}</el-col>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="server-body" @click="go(item)" v-if="item.type == 'TIANYI' || item.type == 'HUAWEI'">
|
||||
<el-row>
|
||||
<el-col :span="12" class="body-left">
|
||||
|
@ -403,6 +436,16 @@ export default {
|
|||
}
|
||||
})
|
||||
break
|
||||
case 'CLOUDTOWER':
|
||||
this.$router.push({
|
||||
name: 'MonitorCloudCloudTower',
|
||||
query: {
|
||||
vendorId: item.id,
|
||||
vendorName: item.name,
|
||||
type: item.type
|
||||
}
|
||||
})
|
||||
break
|
||||
case 'SMARTX':
|
||||
this.$router.push({
|
||||
name: 'MonitorCloudSmart',
|
||||
|
@ -518,7 +561,7 @@ export default {
|
|||
conditionCloudVendor({
|
||||
condition: JSON.stringify({
|
||||
condition: 'listByTypes',
|
||||
types: ['OPENSTACK', 'VMWARE', 'FUSIONCLOUD', 'HMC', 'MANAGEONE', 'KUBERNETES', 'TIANYI', 'HUAWEI', 'H3C', 'ALIYUN', 'SMARTX']
|
||||
types: ['OPENSTACK', 'VMWARE', 'FUSIONCLOUD', 'HMC', 'MANAGEONE', 'KUBERNETES', 'TIANYI', 'HUAWEI', 'H3C', 'ALIYUN', 'SMARTX', 'CLOUDTOWER']
|
||||
})
|
||||
}).then((data) => {
|
||||
if (data.success) {
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
<div class="wrapper-container">
|
||||
<common-detail :title="$route.query.name" @goBack="goBack">
|
||||
<div slot="custom_content">
|
||||
<detail :detail-id="detailId" :detail-name="detailData.name"></detail>
|
||||
</div>
|
||||
</common-detail>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import detail from '../cloudTower/host_detail.vue'
|
||||
export default {
|
||||
components: {
|
||||
detail
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
detailData: {
|
||||
name: this.$route.query.name
|
||||
},
|
||||
detailId: Number(this.$route.query.id),
|
||||
vendorId: this.$route.query.vendorId
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goBack () {
|
||||
if (!this.vendorId) {
|
||||
history.go(-1)
|
||||
} else {
|
||||
this.$router.push({
|
||||
name: 'MonitorDashboard',
|
||||
query: {
|
||||
vendorId: this.vendorId
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,47 @@
|
|||
<template>
|
||||
<div class="wrapper-container">
|
||||
<common-detail :title="$route.query.name" @goBack="goBack">
|
||||
<div slot="custom_content">
|
||||
<detail :detail-id="detailId" :instanceId="identifier"></detail>
|
||||
</div>
|
||||
</common-detail>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import detail from '../cloudTower/vm_detail.vue'
|
||||
export default {
|
||||
components: {
|
||||
detail
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
detailData: {
|
||||
name: this.$route.query.name
|
||||
},
|
||||
detailId: Number(this.$route.query.id),
|
||||
identifier: this.$route.query.identifier,
|
||||
vendorId: this.$route.query.vendorId
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goBack () {
|
||||
if (!this.vendorId) {
|
||||
history.go(-1)
|
||||
} else {
|
||||
this.$router.push({
|
||||
name: 'MonitorDashboard',
|
||||
query: {
|
||||
vendorId: this.vendorId
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -54,8 +54,8 @@
|
|||
<div v-else-if="record.vendorType == 'JDCLOUD'">
|
||||
<div v-for="(item, index) in record.privateIps" :key="index">(内网){{ item }}</div>
|
||||
</div>
|
||||
<div v-else-if="record.vendorType == 'SMARTX'">
|
||||
{{ record.managerIp }}
|
||||
<div v-else-if="record.vendorType == 'SMARTX' || record.vendorType == 'CLOUDTOWER'">
|
||||
<div>{{ record.managerIp ? '(内网)' + record.managerIp : '--' }}</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-for="item in record.privateIps" :key="item">(内网){{ item }}</div>
|
||||
|
@ -128,6 +128,7 @@
|
|||
<vcenter-detail v-if="detailData.vendorType == 'VMWARE'" :detail-id="detailId" :identifier="identifier" :host-name="hostName" :bios-uuid="biosUuid"></vcenter-detail>
|
||||
<huawei-detail v-if="detailData.vendorType == 'HUAWEI'" :detail-id="detailId" :instance-id="instanceId"></huawei-detail>
|
||||
<smart-detail v-if="detailData.vendorType == 'SMARTX'" :detail-id="detailId" :instanceId="instanceId"></smart-detail>
|
||||
<cloudtower-detail v-if="detailData.vendorType == 'CLOUDTOWER'" :detail-id="detailId" :instanceId="instanceId"></cloudtower-detail>
|
||||
</div>
|
||||
</common-detail>
|
||||
</el-card>
|
||||
|
@ -144,6 +145,7 @@ import openstackDetail from './cloud/openstack/vm_detail.vue'
|
|||
import vcenterDetail from './cloud/vcenter/vm_detail.vue'
|
||||
import huaweiDetail from './cloud/huawei/detail.vue'
|
||||
import smartDetail from './cloud/smart/vm_detail.vue'
|
||||
import cloudtowerDetail from './cloud/cloudTower/vm_detail.vue'
|
||||
import { customColorMethod, handleStart } from 'views/data'
|
||||
import addPolicy from 'views/components/linkPolicy'
|
||||
import { downloadFile } from 'utils/index'
|
||||
|
@ -214,7 +216,8 @@ export default {
|
|||
vcenterDetail,
|
||||
huaweiDetail,
|
||||
smartDetail,
|
||||
addPolicy
|
||||
addPolicy,
|
||||
cloudtowerDetail
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -373,7 +376,7 @@ export default {
|
|||
conditionCloudVendor({
|
||||
condition: JSON.stringify({
|
||||
condition: 'listByTypes',
|
||||
types: ['OPENSTACK', 'VMWARE', 'FUSIONCLOUD', 'HMC', 'MANAGEONE', 'TIANYI', 'HUAWEI', 'H3C', 'ALIYUN', 'QCLOUD', 'AZURE', 'TENCENT', 'AWS', 'SMARTX']
|
||||
types: ['OPENSTACK', 'VMWARE', 'FUSIONCLOUD', 'HMC', 'MANAGEONE', 'TIANYI', 'HUAWEI', 'H3C', 'ALIYUN', 'QCLOUD', 'AZURE', 'TENCENT', 'AWS', 'SMARTX', 'CLOUDTOWER']
|
||||
})
|
||||
}).then((data) => {
|
||||
if (data.success) {
|
||||
|
|
|
@ -19,6 +19,21 @@ export const catalogList = [
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'CloudTower',
|
||||
value: 'MONITOR_CLOUDTOWER',
|
||||
vendorType: 'CLOUDTOWER',
|
||||
data: [
|
||||
{
|
||||
name: '宿主机',
|
||||
value: 'MONITOR_CLOUDTOWER_HOST'
|
||||
},
|
||||
{
|
||||
name: '云主机',
|
||||
value: 'MONITOR_CLOUDTOWER_VM'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'OpenStack',
|
||||
value: 'MONITOR_OPENSTACK',
|
||||
|
@ -334,6 +349,16 @@ export const resourceList = [
|
|||
value: 'MONITOR_SMARTX_HOST',
|
||||
type: 'SMARTX'
|
||||
},
|
||||
{
|
||||
name: 'CloudTower宿主机',
|
||||
value: 'MONITOR_CLOUDTOWER_HOST',
|
||||
type: 'CLOUDTOWER'
|
||||
},
|
||||
{
|
||||
name: 'CloudTower云主机',
|
||||
value: 'MONITOR_CLOUDTOWER_VM',
|
||||
type: 'CLOUDTOWER'
|
||||
},
|
||||
{
|
||||
name: 'Dell存储设备',
|
||||
value: 'MONITOR_STORAGE_DELL_STORAGE',
|
||||
|
@ -664,5 +689,5 @@ export function handleStart(self, data, resourceType) {
|
|||
}
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch(() => { })
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ function resolve(dir) {
|
|||
return path.join(__dirname, dir)
|
||||
}
|
||||
|
||||
const httpType = 'http://'
|
||||
const proxyUrl = '23.33.3.3:60006/' // 代理地址设置
|
||||
const httpType = 'https://'
|
||||
const proxyUrl = '23.33.3.28:60006/' // 代理地址设置
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
|
|
|
@ -9,8 +9,8 @@ const CompressPlugin = require('compress-webpack-plugin')
|
|||
function resolve(dir) {
|
||||
return path.join(__dirname, dir)
|
||||
}
|
||||
const httpType = 'http://'
|
||||
const proxyUrl = '23.33.3.3:60006/' // 代理地址设置
|
||||
const httpType = 'https://'
|
||||
const proxyUrl = '23.33.3.28:60006/' // 代理地址设置
|
||||
// const proxyUrl = '10.20.51.92:7001' // 代理地址设置
|
||||
// const proxyUrl = '10.10.2.60:50006/' 苏州代理地址
|
||||
const publicPath = process.env.NODE_ENV === 'production' ? '/cms-web/' : '/'
|
||||
|
|
Loading…
Reference in New Issue