mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-07-17 01:15:23 +00:00
fix topology metrics
This commit is contained in:
parent
b9b50df3d6
commit
a78d8ea2d4
@ -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
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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") }}
|
||||||
|
@ -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") {
|
||||||
|
@ -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>
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 });
|
||||||
|
}
|
||||||
|
return prev;
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
items[index].dashboard = states.nodeDashboards[0].value;
|
||||||
}
|
}
|
||||||
function updateNodeDashboards(index: number, content: string) {
|
function updateNodeDashboards(index: number, content: Option[] | any) {
|
||||||
items[index].dashboard = content;
|
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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user