fix topology metrics

This commit is contained in:
Qiuxia Fan 2022-03-21 13:22:26 +08:00
parent b9b50df3d6
commit a78d8ea2d4
8 changed files with 100 additions and 50 deletions

View File

@ -37,8 +37,8 @@ import { ref, watch } from "vue";
import type { PropType } from "vue"; import type { PropType } from "vue";
interface Option { interface Option {
label: string; label: string | number;
value: string; value: string | number;
} }
/*global defineProps, defineEmits*/ /*global defineProps, defineEmits*/
@ -49,11 +49,14 @@ const props = defineProps({
default: () => [], default: () => [],
}, },
value: { value: {
type: [Array, String, Number] as PropType<any>, type: [Array, String, Number, undefined] as PropType<any>,
default: () => [], default: () => [],
}, },
size: { type: null, default: "default" }, size: { type: null, default: "default" },
placeholder: { type: String, default: "Select a option" }, placeholder: {
type: [String, Number] as PropType<string | number>,
default: "Select a option",
},
borderRadius: { type: Number, default: 3 }, borderRadius: { type: Number, default: 3 },
multiple: { type: Boolean, default: false }, multiple: { type: Boolean, default: false },
disabled: { type: Boolean, default: false }, disabled: { type: Boolean, default: false },
@ -61,7 +64,7 @@ const props = defineProps({
const selected = ref<string[] | string>(props.value); const selected = ref<string[] | string>(props.value);
function changeSelected() { function changeSelected() {
const options = props.options.filter((d: Option) => const options = props.options.filter((d: any) =>
props.multiple props.multiple
? selected.value.includes(d.value) ? selected.value.includes(d.value)
: selected.value === d.value : selected.value === d.value

View File

@ -99,7 +99,7 @@ const theme = ["VirtualMachine", "Kubernetes"].includes(name.value || "")
? ref("light") ? ref("light")
: ref("black"); : ref("black");
const routes = ref<any>(useRouter().options.routes); const routes = ref<any>(useRouter().options.routes);
const isCollapse = ref(true); const isCollapse = ref(false);
const controlMenu = () => { const controlMenu = () => {
isCollapse.value = !isCollapse.value; isCollapse.value = !isCollapse.value;
}; };

View File

@ -57,7 +57,7 @@ limitations under the License. -->
<el-table-column label="Operations"> <el-table-column label="Operations">
<template #default="scope"> <template #default="scope">
<el-button size="small" @click="handleView(scope.row)"> <el-button size="small" @click="handleView(scope.row)">
{{ t("view") }} {{ t("edit") }}
</el-button> </el-button>
<el-button size="small" @click="handleEdit(scope.row)"> <el-button size="small" @click="handleEdit(scope.row)">
{{ t("rename") }} {{ t("rename") }}

View File

@ -96,6 +96,7 @@ import {
ChartTypes, ChartTypes,
PodsChartTypes, PodsChartTypes,
ListEntity, ListEntity,
MetricsType,
} from "../../data"; } from "../../data";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import Icon from "@/components/Icon.vue"; import Icon from "@/components/Icon.vue";
@ -150,7 +151,7 @@ async function setMetricType(catalog?: string) {
(d: { catalog: string; type: string }) => { (d: { catalog: string; type: string }) => {
if (states.isList || graph.type === "Table") { if (states.isList || graph.type === "Table") {
if ( if (
d.type === "REGULAR_VALUE" && d.type === MetricsType.REGULAR_VALUE &&
catalog === (MetricCatalog as any)[d.catalog] catalog === (MetricCatalog as any)[d.catalog]
) { ) {
return d; return d;
@ -367,7 +368,7 @@ function deleteMetric(index: number) {
states.metricTypes.splice(index, 1); states.metricTypes.splice(index, 1);
} }
function setMetricTypeList(type: string) { function setMetricTypeList(type: string) {
if (type !== "REGULAR_VALUE") { if (type !== MetricsType.REGULAR_VALUE) {
return MetricTypes[type]; return MetricTypes[type];
} }
if (states.isList || dashboardStore.selectedGrid.graph.type === "Table") { if (states.isList || dashboardStore.selectedGrid.graph.type === "Table") {

View File

@ -33,6 +33,6 @@ defineProps({
}); });
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const isSankey = ref<boolean>( const isSankey = ref<boolean>(
[EntityType[2].value, EntityType[3].value].includes(dashboardStore.entity) [EntityType[2].value, EntityType[4].value].includes(dashboardStore.entity)
); );
</script> </script>

View File

@ -239,7 +239,9 @@ function handleLinkClick(event: any, d: Call) {
dashboardStore.entity === EntityType[1].value dashboardStore.entity === EntityType[1].value
? EntityType[0].value ? EntityType[0].value
: dashboardStore.entity; : dashboardStore.entity;
const path = `/dashboard/${dashboardStore.layerId}/${e}Relation/${d.source.id}/${d.target.id}/${settings.value.linkDashboard}`; const path = `/dashboard/${dashboardStore.layerId}/${e}Relation/${
d.source.id
}/${d.target.id}/${settings.value.linkDashboard.split(" ").join("-")}`;
const routeUrl = router.resolve({ path }); const routeUrl = router.resolve({ path });
window.open(routeUrl.href, "_blank"); window.open(routeUrl.href, "_blank");
} }
@ -371,19 +373,25 @@ async function handleInspect() {
update(); update();
} }
function handleGoEndpoint(name: string) { function handleGoEndpoint(name: string) {
const path = `/dashboard/${dashboardStore.layerId}/Endpoint/${topologyStore.node.id}/${name}`; const path = `/dashboard/${dashboardStore.layerId}/Endpoint/${
topologyStore.node.id
}/${name.split(" ").join("-")}`;
const routeUrl = router.resolve({ path }); const routeUrl = router.resolve({ path });
window.open(routeUrl.href, "_blank"); window.open(routeUrl.href, "_blank");
} }
function handleGoInstance(name: string) { function handleGoInstance(name: string) {
const path = `/dashboard/${dashboardStore.layerId}/ServiceInstance/${topologyStore.node.id}/${name}`; const path = `/dashboard/${dashboardStore.layerId}/ServiceInstance/${
topologyStore.node.id
}/${name.split(" ").join("-")}`;
const routeUrl = router.resolve({ path }); const routeUrl = router.resolve({ path });
window.open(routeUrl.href, "_blank"); window.open(routeUrl.href, "_blank");
} }
function handleGoDashboard(name: string) { function handleGoDashboard(name: string) {
const path = `/dashboard/${dashboardStore.layerId}/Service/${topologyStore.node.id}/${name}`; const path = `/dashboard/${dashboardStore.layerId}/Service/${
topologyStore.node.id
}/${name.split(" ").join("-")}`;
const routeUrl = router.resolve({ path }); const routeUrl = router.resolve({ path });
window.open(routeUrl.href, "_blank"); window.open(routeUrl.href, "_blank");

View File

@ -207,7 +207,7 @@ async function getTopology(id: string) {
Number(depth.value) Number(depth.value)
); );
break; break;
case EntityType[3].value: case EntityType[4].value:
resp = await topologyStore.getInstanceTopology(); resp = await topologyStore.getInstanceTopology();
break; break;
} }

View File

@ -16,11 +16,12 @@ limitations under the License. -->
<div class="link-settings"> <div class="link-settings">
<h5 class="title">{{ t("callSettings") }}</h5> <h5 class="title">{{ t("callSettings") }}</h5>
<div class="label">{{ t("linkDashboard") }}</div> <div class="label">{{ t("linkDashboard") }}</div>
<el-input <Selector
v-model="states.linkDashboard" :value="states.linkDashboard"
placeholder="Please input a dashboard name for calls" :options="states.linkDashboards"
@change="updateSettings"
size="small" size="small"
placeholder="Please input a dashboard name for calls"
@change="changeLinkDashboard"
class="inputs" class="inputs"
/> />
<div class="label">{{ t("linkServerMetrics") }}</div> <div class="label">{{ t("linkServerMetrics") }}</div>
@ -51,16 +52,17 @@ limitations under the License. -->
<div class="node-settings"> <div class="node-settings">
<h5 class="title">{{ t("nodeSettings") }}</h5> <h5 class="title">{{ t("nodeSettings") }}</h5>
<div class="label">{{ t("nodeDashboard") }}</div> <div class="label">{{ t("nodeDashboard") }}</div>
<el-input <Selector
v-show="!isServer" v-show="!isService"
v-model="states.nodeDashboard" :value="states.nodeDashboard"
placeholder="Please input a dashboard name for nodes" :options="states.nodeDashboards"
@change="updateSettings"
size="small" size="small"
placeholder="Please input a dashboard name for nodes"
@change="changeNodeDashboard"
class="inputs" class="inputs"
/> />
<div <div
v-show="isServer" v-show="isService"
v-for="(item, index) in items" v-for="(item, index) in items"
:key="index" :key="index"
class="metric-item" class="metric-item"
@ -73,11 +75,12 @@ limitations under the License. -->
@change="changeScope(index, $event)" @change="changeScope(index, $event)"
class="item mr-5" class="item mr-5"
/> />
<el-input <Selector
v-model="item.dashboard" :value="item.dashboard"
:options="states.nodeDashboards"
size="small"
placeholder="Please input a dashboard name for nodes" placeholder="Please input a dashboard name for nodes"
@change="updateNodeDashboards(index, $event)" @change="updateNodeDashboards(index, $event)"
size="small"
class="item mr-5" class="item mr-5"
/> />
<span> <span>
@ -108,7 +111,7 @@ limitations under the License. -->
@change="changeNodeMetrics" @change="changeNodeMetrics"
/> />
</div> </div>
<div class="legend-settings" v-show="isServer"> <div class="legend-settings" v-show="isService">
<h5 class="title">{{ t("legendSettings") }}</h5> <h5 class="title">{{ t("legendSettings") }}</h5>
<div class="label">{{ t("conditions") }}</div> <div class="label">{{ t("conditions") }}</div>
<div v-for="(metric, index) of legend.metric" :key="metric.name + index"> <div v-for="(metric, index) of legend.metric" :key="metric.name + index">
@ -184,7 +187,8 @@ import { MetricCatalog, ScopeType, MetricConditions } from "../../../data";
import { Option } from "@/types/app"; import { Option } from "@/types/app";
import { useQueryTopologyMetrics } from "@/hooks/useProcessor"; import { useQueryTopologyMetrics } from "@/hooks/useProcessor";
import { Node, Call } from "@/types/topology"; import { Node, Call } from "@/types/topology";
import { EntityType, LegendOpt } from "../../../data"; import { DashboardItem } from "@/types/dashboard";
import { EntityType, LegendOpt, MetricsType } from "../../../data";
/*global defineEmits */ /*global defineEmits */
const emit = defineEmits(["update", "updateNodes"]); const emit = defineEmits(["update", "updateNodes"]);
@ -208,6 +212,8 @@ const states = reactive<{
nodeMetrics: string[]; nodeMetrics: string[];
nodeMetricList: Option[]; nodeMetricList: Option[];
linkMetricList: Option[]; linkMetricList: Option[];
linkDashboards: (DashboardItem & { label: string; value: string })[];
nodeDashboards: (DashboardItem & { label: string; value: string })[];
}>({ }>({
linkDashboard: "", linkDashboard: "",
nodeDashboard: [], nodeDashboard: [],
@ -216,8 +222,10 @@ const states = reactive<{
nodeMetrics: [], nodeMetrics: [],
nodeMetricList: [], nodeMetricList: [],
linkMetricList: [], linkMetricList: [],
linkDashboards: [],
nodeDashboards: [],
}); });
const isServer = [EntityType[0].value, EntityType[1].value].includes( const isService = [EntityType[0].value, EntityType[1].value].includes(
dashboardStore.entity dashboardStore.entity
); );
const legend = reactive<{ const legend = reactive<{
@ -226,6 +234,7 @@ const legend = reactive<{
getMetricList(); getMetricList();
async function getMetricList() { async function getMetricList() {
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
const json = await dashboardStore.fetchMetricList(); const json = await dashboardStore.fetchMetricList();
if (json.errors) { if (json.errors) {
ElMessage.error(json.errors); ElMessage.error(json.errors);
@ -237,18 +246,28 @@ async function getMetricList() {
: dashboardStore.entity === EntityType[4].value : dashboardStore.entity === EntityType[4].value
? EntityType[3].value ? EntityType[3].value
: dashboardStore.entity; : dashboardStore.entity;
states.nodeMetricList = (json.data.metrics || []).filter( states.linkDashboards = list.reduce(
(d: { catalog: string }) => entity === (MetricCatalog as any)[d.catalog] (
prev: (DashboardItem & { label: string; value: string })[],
d: DashboardItem
) => {
if (
d.layer === dashboardStore.layerId &&
d.entity === entity + "Relation"
) {
prev.push({ ...d, label: d.name, value: d.name });
}
return prev;
},
[]
);
states.nodeMetricList = (json.data.metrics || []).filter(
(d: { type: string }) => d.type === MetricsType.REGULAR_VALUE
); );
const e =
dashboardStore.entity === EntityType[1].value
? EntityType[0].value
: dashboardStore.entity === EntityType[4].value
? EntityType[3].value
: dashboardStore.entity;
states.linkMetricList = (json.data.metrics || []).filter( states.linkMetricList = (json.data.metrics || []).filter(
(d: { catalog: string }) => (d: { catalog: string; type: string }) =>
e + "Relation" === (MetricCatalog as any)[d.catalog] entity + "Relation" === (MetricCatalog as any)[d.catalog] &&
d.type === MetricsType.REGULAR_VALUE
); );
} }
async function setLegend() { async function setLegend() {
@ -259,7 +278,7 @@ async function setLegend() {
emit("update", { emit("update", {
linkDashboard: states.linkDashboard, linkDashboard: states.linkDashboard,
nodeDashboard: isServer nodeDashboard: isService
? items.filter((d: { scope: string; dashboard: string }) => d.dashboard) ? items.filter((d: { scope: string; dashboard: string }) => d.dashboard)
: states.nodeDashboard, : states.nodeDashboard,
linkServerMetrics: states.linkServerMetrics, linkServerMetrics: states.linkServerMetrics,
@ -276,15 +295,34 @@ async function setLegend() {
} }
emit("updateNodes"); emit("updateNodes");
} }
function changeNodeDashboard(opt: any) {
states.nodeDashboard = opt[0].value;
}
function changeLinkDashboard(opt: any) {
states.linkDashboard = opt[0].value;
}
function changeLegend(type: string, opt: any, index: number) { function changeLegend(type: string, opt: any, index: number) {
(legend.metric[index] as any)[type] = opt[0].value || opt; (legend.metric[index] as any)[type] = opt[0].value || opt;
} }
function changeScope(index: number, opt: Option[]) { function changeScope(index: number, opt: Option[] | any) {
items[index].scope = opt[0].value; items[index].scope = opt[0].value;
items[index].dashboard = ""; const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
states.nodeDashboards = list.reduce(
(
prev: (DashboardItem & { label: string; value: string })[],
d: DashboardItem
) => {
if (d.layer === dashboardStore.layerId && d.entity === opt[0].value) {
prev.push({ ...d, label: d.name, value: d.name });
} }
function updateNodeDashboards(index: number, content: string) { return prev;
items[index].dashboard = content; },
[]
);
items[index].dashboard = states.nodeDashboards[0].value;
}
function updateNodeDashboards(index: number, content: Option[] | any) {
items[index].dashboard = content[0].value;
updateSettings(); updateSettings();
} }
function addItem() { function addItem() {
@ -297,7 +335,7 @@ function deleteItem(index: number) {
function updateSettings() { function updateSettings() {
emit("update", { emit("update", {
linkDashboard: states.linkDashboard, linkDashboard: states.linkDashboard,
nodeDashboard: isServer nodeDashboard: isService
? items.filter((d: { scope: string; dashboard: string }) => d.dashboard) ? items.filter((d: { scope: string; dashboard: string }) => d.dashboard)
: states.nodeDashboard, : states.nodeDashboard,
linkServerMetrics: states.linkServerMetrics, linkServerMetrics: states.linkServerMetrics,
@ -306,7 +344,7 @@ function updateSettings() {
legend: legend.metric, legend: legend.metric,
}); });
} }
async function changeLinkServerMetrics(options: Option[]) { async function changeLinkServerMetrics(options: Option[] | any) {
states.linkServerMetrics = options.map((d: Option) => d.value); states.linkServerMetrics = options.map((d: Option) => d.value);
updateSettings(); updateSettings();
if (!states.linkServerMetrics.length) { if (!states.linkServerMetrics.length) {
@ -323,7 +361,7 @@ async function changeLinkServerMetrics(options: Option[]) {
ElMessage.error(res.errors); ElMessage.error(res.errors);
} }
} }
async function changeLinkClientMetrics(options: Option[]) { async function changeLinkClientMetrics(options: Option[] | any) {
states.linkClientMetrics = options.map((d: Option) => d.value); states.linkClientMetrics = options.map((d: Option) => d.value);
updateSettings(); updateSettings();
if (!states.linkClientMetrics.length) { if (!states.linkClientMetrics.length) {
@ -340,7 +378,7 @@ async function changeLinkClientMetrics(options: Option[]) {
ElMessage.error(res.errors); ElMessage.error(res.errors);
} }
} }
async function changeNodeMetrics(options: Option[]) { async function changeNodeMetrics(options: Option[] | any) {
states.nodeMetrics = options.map((d: Option) => d.value); states.nodeMetrics = options.map((d: Option) => d.value);
updateSettings(); updateSettings();
if (!states.nodeMetrics.length) { if (!states.nodeMetrics.length) {