Files
fe.ems.vue3/src/views/monitor/cache/info.vue

230 lines
6.6 KiB
Vue

<script setup lang="ts">
import * as echarts from 'echarts/core';
import {
ToolboxComponent,
ToolboxComponentOption,
TooltipComponent,
TooltipComponentOption,
LegendComponent,
LegendComponentOption,
} from 'echarts/components';
import { PieChart, PieSeriesOption } from 'echarts/charts';
import { LabelLayout } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';
import { PageContainer } from 'antdv-pro-layout';
import { getCache } from '@/api/monitor/cache';
import { reactive, ref, onMounted } from 'vue';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import useI18n from '@/hooks/useI18n';
const { t, currentLocale } = useI18n();
echarts.use([
ToolboxComponent,
TooltipComponent,
LegendComponent,
PieChart,
CanvasRenderer,
LabelLayout,
]);
/**加载状态 */
let loading = ref<boolean>(true);
/**数据参数类型 */
type CacheType = {
/**服务信息 */
info: InfoType;
/**当前连接可用键Key总数 */
dbSize: number;
/**命令状态 */
commandStats: Record<string, string>[];
};
/**数据参数服务信息类型 */
type InfoType = {
clients: Record<string, string>;
cluster: Record<string, string>;
cpu: Record<string, string>;
errorstats: Record<string, string>;
keyspace: Record<string, string>;
memory: Record<string, string>;
modules: Record<string, string>;
persistence: Record<string, string>;
replication: Record<string, string>;
server: Record<string, string>;
stats: Record<string, string>;
};
let cache: CacheType = reactive({
info: {
clients: {},
cluster: {},
cpu: {},
errorstats: {},
keyspace: {},
memory: {},
modules: {},
persistence: {},
replication: {},
server: {},
stats: {},
},
dbSize: 0,
commandStats: [],
});
/**生成命令统计图 */
function commandStatsChart() {
const commandStatsDom = document.getElementById('commandstats');
if (!commandStatsDom) return;
const locale = currentLocale.value.split("_")[0]
const commandStatsEchart = echarts.init(commandStatsDom, 'light', {
// https://github.com/apache/echarts/tree/release/src/i18n 取值langEN.ts ==> EN
locale: locale.toUpperCase(),
});
const option: echarts.ComposeOption<
| ToolboxComponentOption
| TooltipComponentOption
| LegendComponentOption
| PieSeriesOption
> = {
// 鼠标悬浮提示
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)',
},
// 左侧标签
legend: {
orient: 'vertical',
left: 'left',
},
// 右侧工具
toolbox: {
show: true,
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
restore: { show: true },
saveAsImage: { show: true },
},
},
series: [
{
name: t('views.monitor.cacheInfo.commandstats'),
type: 'pie',
radius: ['5%', '80%'],
center: ['60%', '50%'],
roseType: 'area',
itemStyle: {
borderRadius: 8,
},
data: cache.commandStats,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
},
},
},
],
};
commandStatsEchart.setOption(option);
// 创建 ResizeObserver 实例
var observer = new ResizeObserver(entries => {
if (commandStatsEchart) {
commandStatsEchart.resize();
}
});
// 监听元素大小变化
observer.observe(commandStatsDom);
}
onMounted(() => {
getCache()
.then(res => {
if (res.code === RESULT_CODE_SUCCESS && res.data) {
cache.info = res.data.info;
cache.dbSize = res.data.dbSize;
cache.commandStats = res.data.commandStats;
// 加载状态
loading.value = false;
}
})
.then(() => {
// 加载结束后生成图
commandStatsChart();
});
});
</script>
<template>
<PageContainer :loading="loading">
<a-card
:title="t('views.monitor.cacheInfo.baseInfo')"
:bordered="false"
:body-style="{ marginBottom: '24px', padding: 0 }"
>
<a-descriptions
size="middle"
layout="horizontal"
:label-style="{ width: '140px' }"
:bordered="true"
:column="{ lg: 4, md: 2, xs: 1 }"
>
<a-descriptions-item :label="t('views.monitor.cacheInfo.version')">
{{ cache.info.server.redis_version }}
</a-descriptions-item>
<a-descriptions-item :label="t('views.monitor.cacheInfo.mode')">
{{
cache.info.server.redis_mode == 'standalone'
? t('views.monitor.cacheInfo.modeStandalone')
: t('views.monitor.cacheInfo.modeClusters')
}}
</a-descriptions-item>
<a-descriptions-item :label="t('views.monitor.cacheInfo.port')">
{{ cache.info.server.tcp_port }}
</a-descriptions-item>
<a-descriptions-item :label="t('views.monitor.cacheInfo.clients')">
{{ cache.info.clients.connected_clients }}
</a-descriptions-item>
<a-descriptions-item :label="t('views.monitor.cacheInfo.uptimeInDays')">
{{ cache.info.server.uptime_in_days }}
</a-descriptions-item>
<a-descriptions-item :label="t('views.monitor.cacheInfo.memoryHuman')">
{{ cache.info.memory.used_memory_human }}
</a-descriptions-item>
<a-descriptions-item :label="t('views.monitor.cacheInfo.usedCpu')">
{{ parseFloat(cache.info.cpu.used_cpu_user_children).toFixed(2) }}
</a-descriptions-item>
<a-descriptions-item :label="t('views.monitor.cacheInfo.maxmemory')">
{{ cache.info.memory.maxmemory_human }}
</a-descriptions-item>
<a-descriptions-item :label="t('views.monitor.cacheInfo.aof')">
{{ cache.info.persistence.aof_enabled == '1' }}
</a-descriptions-item>
<a-descriptions-item :label="t('views.monitor.cacheInfo.rdb')">
{{ cache.info.persistence.rdb_last_bgsave_status }}
</a-descriptions-item>
<a-descriptions-item :label="t('views.monitor.cacheInfo.dbSize')">
{{ cache.dbSize }}
</a-descriptions-item>
<a-descriptions-item :label="t('views.monitor.cacheInfo.kbps')">
{{ cache.info.stats.instantaneous_input_kbps }} kps /
{{ cache.info.stats.instantaneous_output_kbps }} kps
</a-descriptions-item>
</a-descriptions>
</a-card>
<a-card
:title="t('views.monitor.cacheInfo.commandstats')"
:bordered="false"
>
<div id="commandstats" style="height: 400px; width: 100%"></div>
</a-card>
</PageContainer>
</template>
<style lang="less" scoped></style>