Redis监控图标使用Echart组件整合

(cherry picked from commit bf629a9554)
This commit is contained in:
Chika 2023-05-12 15:30:01 +08:00 committed by shizhong
parent 7a5993c584
commit 80f1c08951
2 changed files with 216 additions and 195 deletions

View File

@ -342,6 +342,28 @@ const remainingRouter: AppRouteRecordRaw[] = [
} }
] ]
}, },
{
path: '/infra',
component: Layout,
name: 'InfraRedis',
meta: {
hidden: true
},
children: [
{
path: '/infra/redis',
component: () => import('@/views/infra/redis/index.vue'),
name: 'InfraRedis',
meta: {
noCache: true,
hidden: true,
canTo: true,
title: 'REDIS测试测试测试',
activeMenu: 'infra/redis/index'
}
}
]
},
{ {
path: '/property', path: '/property',
component: Layout, component: Layout,

View File

@ -1,6 +1,9 @@
<template> <template>
<doc-alert title="Redis 缓存" url="https://doc.iocoder.cn/redis-cache/" />
<doc-alert title="本地缓存" url="https://doc.iocoder.cn/local-cache/" />
<el-scrollbar height="calc(100vh - 88px - 40px - 50px)"> <el-scrollbar height="calc(100vh - 88px - 40px - 50px)">
<el-row> <el-row>
<!-- 基本信息 -->
<el-col :span="24" class="card-box" shadow="hover"> <el-col :span="24" class="card-box" shadow="hover">
<el-card> <el-card>
<el-descriptions title="基本信息" :column="6" border> <el-descriptions title="基本信息" :column="6" border>
@ -44,125 +47,126 @@
</el-descriptions> </el-descriptions>
</el-card> </el-card>
</el-col> </el-col>
<!-- 命令统计 -->
<el-col :span="12" class="mt-3"> <el-col :span="12" class="mt-3">
<el-card :gutter="12" shadow="hover"> <el-card :gutter="12" shadow="hover">
<div ref="commandStatsRef" class="h-88"></div> <Echart :options="commandStatsRefChika" :height="420" />
</el-card> </el-card>
</el-col> </el-col>
<!-- 内存使用量统计 -->
<el-col :span="12" class="mt-3"> <el-col :span="12" class="mt-3">
<el-card class="ml-3" :gutter="12" shadow="hover"> <el-card class="ml-3" :gutter="12" shadow="hover">
<div ref="usedmemory" class="h-88"></div> <Echart :options="usedmemoryEchartChika" :height="420" />
</el-card>
</el-col>
</el-row>
<el-row class="mt-3">
<el-col :span="24" class="card-box" shadow="hover">
<el-card>
<el-table
v-loading="keyListLoad"
:data="keyList"
row-key="id"
@row-click="openKeyTemplate"
>
<el-table-column prop="keyTemplate" label="Key 模板" width="200" />
<el-table-column prop="keyType" label="Key 类型" width="100" />
<el-table-column prop="valueType" label="Value 类型" />
<el-table-column prop="timeoutType" label="超时时间" width="200">
<template #default="{ row }">
<DictTag :type="DICT_TYPE.INFRA_REDIS_TIMEOUT_TYPE" :value="row?.timeoutType" />
<span v-if="row?.timeout > 0">({{ row?.timeout / 1000 }} )</span>
</template>
</el-table-column>
<el-table-column prop="memo" label="备注" />
</el-table>
</el-card> </el-card>
</el-col> </el-col>
</el-row> </el-row>
</el-scrollbar> </el-scrollbar>
<XModal v-model="dialogVisible" :title="keyTemplate + ' 模板'">
<el-row>
<el-col :span="14" class="mt-3">
<el-card shadow="always">
<template #header>
<div class="card-header">
<span>键名列表</span>
</div>
</template>
<el-table :data="cacheKeys" style="width: 100%" @row-click="handleKeyValue">
<el-table-column label="缓存键名" align="center" :show-overflow-tooltip="true">
<template #default="{ row }">
{{ row }}
</template>
</el-table-column>
<el-table-column label="操作" align="right" width="60">
<template #default="{ row }">
<XTextButton preIcon="ep:delete" @click="handleDeleteKey(row)" />
</template>
</el-table-column>
</el-table>
</el-card>
</el-col>
<el-col :span="10" class="mt-3">
<el-card shadow="always">
<template #header>
<div class="card-header">
<span>缓存内容</span>
<XTextButton
preIcon="ep:refresh"
title="清理全部"
@click="handleDeleteKeys(keyTemplate)"
class="float-right p-1"
/>
</div>
</template>
<el-descriptions :column="1">
<el-descriptions-item label="缓存键名:">{{ cacheForm.key }}</el-descriptions-item>
<el-descriptions-item label="缓存内容:">{{ cacheForm.value }}</el-descriptions-item>
</el-descriptions>
</el-card>
</el-col>
</el-row>
</XModal>
</template> </template>
<script setup lang="ts" name="Redis"> <script setup lang="ts">
import * as echarts from 'echarts' import echarts from '@/plugins/echarts'
import { DICT_TYPE } from '@/utils/dict' import { GaugeChart } from 'echarts/charts'
import { ToolboxComponent } from 'echarts/components'
import * as RedisApi from '@/api/infra/redis' import * as RedisApi from '@/api/infra/redis'
import { RedisKeyInfo, RedisMonitorInfoVO } from '@/api/infra/redis/types' import { RedisMonitorInfoVO } from '@/api/infra/redis/types'
echarts.use([ToolboxComponent])
const { t } = useI18n() // echarts.use([GaugeChart])
const message = useMessage() //
const cache = ref<RedisMonitorInfoVO>() const cache = ref<RedisMonitorInfoVO>()
const keyListLoad = ref(true)
const keyList = ref<RedisKeyInfo[]>([])
// //
const readRedisInfo = async () => { const readRedisInfo = async () => {
const data = await RedisApi.getCacheApi() const data = await RedisApi.getCache()
cache.value = data cache.value = data
loadEchartOptions(data.commandStats)
const redisKeysInfo = await RedisApi.getKeyDefineListApi()
keyList.value = redisKeysInfo
keyListLoad.value = false //
} }
//
const commandStatsRef = ref<HTMLElement>()
const usedmemory = ref<HTMLDivElement>()
const loadEchartOptions = (stats) => { // 使
const commandStats = [] as any[] const usedmemoryEchartChika = reactive({
const nameList = [] as string[] title: {
stats.forEach((row) => { //
commandStats.push({ text: '内存使用情况',
name: row.command, left: 'center',
value: row.calls show: true, // , true
}) offsetCenter: [0, '20%'], //
nameList.push(row.command) color: 'yellow', // , #333
}) fontSize: 20 // , 15
},
toolbox: {
show: false,
feature: {
restore: { show: true },
saveAsImage: { show: true }
}
},
series: [
{
name: '峰值',
type: 'gauge',
min: 0,
max: 50,
splitNumber: 10,
//
color: '#F5C74E',
radius: '85%',
center: ['50%', '50%'],
startAngle: 225,
endAngle: -45,
axisLine: {
// 线
lineStyle: {
// lineStyle线
color: [
[0.2, '#7FFF00'],
[0.8, '#00FFFF'],
[1, '#FF0000']
],
//width: 6
width: 10
}
},
axisTick: {
//
//线5线
length: 5, // length线
lineStyle: {
// lineStyle线
color: '#76D9D7'
}
},
splitLine: {
// 线
length: 20, // length线
lineStyle: {
// lineStylelineStyle线
color: '#76D9D7'
}
},
axisLabel: {
color: '#76D9D7',
distance: 15,
fontSize: 15
},
pointer: {
//
width: 7,
show: true
},
detail: {
textStyle: {
fontWeight: 'normal',
//50
fontSize: 15,
color: '#FFFFFF'
},
valueAnimation: true
},
progress: {
show: true
}
}
]
})
const commandStatsInstance = echarts.init(commandStatsRef.value!, 'macarons') // 使
const commandStatsRefChika = reactive({
commandStatsInstance.setOption({
title: { title: {
text: '命令统计', text: '命令统计',
left: 'center' left: 'center'
@ -177,7 +181,7 @@ const loadEchartOptions = (stats) => {
right: 30, right: 30,
top: 10, top: 10,
bottom: 20, bottom: 20,
data: nameList, data: [] as any[],
textStyle: { textStyle: {
color: '#a1a1a1' color: '#a1a1a1'
} }
@ -188,7 +192,7 @@ const loadEchartOptions = (stats) => {
type: 'pie', type: 'pie',
radius: [20, 120], radius: [20, 120],
center: ['40%', '60%'], center: ['40%', '60%'],
data: commandStats, data: [] as any[],
roseType: 'radius', roseType: 'radius',
label: { label: {
show: true show: true
@ -205,68 +209,63 @@ const loadEchartOptions = (stats) => {
} }
} }
] ]
}) })
const usedMemoryInstance = echarts.init(usedmemory.value!, 'macarons') /** 加载数据 */
usedMemoryInstance.setOption({ const getSummary = () => {
title: { //
text: '内存使用情况', initcommandStatsChart()
left: 'center' usedMemoryInstance()
}, }
tooltip: {
formatter: '{b} <br/>{a} : ' + cache.value!.info.used_memory_human /** 命令使用情况 */
}, const initcommandStatsChart = async () => {
series: [ usedmemoryEchartChika.series[0].data = []
{ //
name: '峰值', try {
type: 'gauge', const data = await RedisApi.getCache()
min: 0, cache.value = data
max: 100, //
progress: { const commandStats = [] as any[]
show: true const nameList = [] as string[]
}, data.commandStats.forEach((row) => {
detail: { commandStats.push({
formatter: cache.value!.info.used_memory_human name: row.command,
}, value: row.calls
data: [ })
{ nameList.push(row.command)
value: parseFloat(cache.value!.info.used_memory_human), })
commandStatsRefChika.legend.data = nameList
commandStatsRefChika.series[0].data = commandStats
} catch {}
}
const usedMemoryInstance = async () => {
try {
const data = await RedisApi.getCache()
cache.value = data
//
usedmemoryEchartChika.series[0].detail = {
show: true, // , true
offsetCenter: [0, '50%'], //
color: 'auto', // , auto
fontSize: 30, // , 15
formatter: cache.value!.info.used_memory_human //
}
usedmemoryEchartChika.series[0].data[0] = {
value: cache.value!.info.used_memory_human,
name: '内存消耗' name: '内存消耗'
} }
] usedmemoryEchartChika.tooltip = {
formatter: '{b} <br/>{a} : ' + cache.value!.info.used_memory_human
} }
] } catch {}
})
} }
const dialogVisible = ref(false)
const keyTemplate = ref('') /** 初始化 **/
const cacheKeys = ref() onMounted(() => {
const cacheForm = ref<{
key: string
value: string
}>({
key: '',
value: ''
})
const openKeyTemplate = async (row: RedisKeyInfo) => {
keyTemplate.value = row.keyTemplate
cacheKeys.value = await RedisApi.getKeyListApi(row.keyTemplate)
dialogVisible.value = true
}
const handleDeleteKey = async (row) => {
RedisApi.deleteKeyApi(row)
message.success(t('common.delSuccess'))
}
const handleDeleteKeys = async (row) => {
RedisApi.deleteKeysApi(row)
message.success(t('common.delSuccess'))
}
const handleKeyValue = async (row) => {
const res = await RedisApi.getKeyValueApi(row)
cacheForm.value = res
}
onBeforeMount(() => {
// TODO @hiiwbs 使 Echart
readRedisInfo() readRedisInfo()
//
getSummary()
}) })
</script> </script>