This is an automated email from the ASF dual-hosted git repository. wankai pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/skywalking-booster-ui.git
The following commit(s) were added to refs/heads/main by this push: new 03f321b6 refactor: remove the `General ` metric mode and related logical code (#384) 03f321b6 is described below commit 03f321b62ae0b3581f156954f75429a52ef511b6 Author: Fine0830 <fanxue0...@gmail.com> AuthorDate: Thu Apr 11 17:50:43 2024 +0800 refactor: remove the `General ` metric mode and related logical code (#384) --- src/hooks/data.ts | 69 ---- src/hooks/useExpressionsProcessor.ts | 6 +- src/hooks/useListConfig.ts | 41 -- src/hooks/useMetricsProcessor.ts | 437 --------------------- src/locales/lang/en.ts | 1 - src/locales/lang/es.ts | 1 - src/locales/lang/zh.ts | 1 - src/store/modules/dashboard.ts | 14 +- src/store/modules/topology.ts | 99 ----- src/types/dashboard.d.ts | 4 - src/views/dashboard/List.vue | 25 +- src/views/dashboard/Widget.vue | 44 +-- src/views/dashboard/components/WidgetLink.vue | 18 +- src/views/dashboard/configuration/Widget.vue | 21 - .../configuration/widget/metric/Index.vue | 314 +++------------ .../configuration/widget/metric/Standard.vue | 49 +-- src/views/dashboard/controls/Widget.vue | 42 +- src/views/dashboard/data.ts | 86 ---- src/views/dashboard/graphs/EndpointList.vue | 51 +-- src/views/dashboard/graphs/InstanceList.vue | 53 +-- src/views/dashboard/graphs/ServiceList.vue | 58 +-- src/views/dashboard/graphs/Table.vue | 5 - src/views/dashboard/graphs/TopList.vue | 14 +- .../dashboard/graphs/components/ColumnGraph.vue | 36 +- .../dashboard/related/topology/config/Metrics.vue | 33 +- .../dashboard/related/topology/config/Settings.vue | 311 ++------------- .../dashboard/related/topology/pod/InstanceMap.vue | 5 +- .../dashboard/related/topology/pod/PodMap.vue | 14 +- .../dashboard/related/topology/pod/Sankey.vue | 31 +- .../related/topology/service/HierarchyMap.vue | 4 +- .../related/topology/service/ServiceMap.vue | 107 ++--- 31 files changed, 204 insertions(+), 1790 deletions(-) diff --git a/src/hooks/data.ts b/src/hooks/data.ts index 3d45a00d..f7c2b2db 100644 --- a/src/hooks/data.ts +++ b/src/hooks/data.ts @@ -14,32 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export enum MetricQueryTypes { - ReadMetricsValue = "readMetricsValue", - ReadMetricsValues = "readMetricsValues", - SortMetrics = "sortMetrics", - ReadLabeledMetricsValues = "readLabeledMetricsValues", - READHEATMAP = "readHeatMap", - ReadSampledRecords = "readSampledRecords", - ReadRecords = "readRecords", - ReadNullableMetricsValue = "readNullableMetricsValue", -} -export enum Calculations { - Percentage = "percentage", - ByteToKB = "byteToKB", - ByteToMB = "byteToMB", - ByteToGB = "byteToGB", - Apdex = "apdex", - ConvertSeconds = "convertSeconds", - ConvertMilliseconds = "convertMilliseconds", - MsToS = "msTos", - Average = "average", - PercentageAvg = "percentageAvg", - ApdexAvg = "apdexAvg", - SecondToDay = "secondToDay", - NanosecondToMillisecond = "nanosecondToMillisecond", -} export enum sizeEnum { XS = "XS", SM = "SM", @@ -68,50 +43,6 @@ screenMap.set(sizeEnum.XL, screenEnum.XL); screenMap.set(sizeEnum.XXL, screenEnum.XXL); export const RespFields: Indexable = { - readMetricsValues: `{ - label - values { - values {value isEmptyValue} - } - }`, - readMetricsValue: ``, - readNullableMetricsValue: `{ - value - isEmptyValue - }`, - sortMetrics: `{ - name - id - value - refId - }`, - readLabeledMetricsValues: `{ - label - values { - values {value isEmptyValue} - } - }`, - readHeatMap: `{ - values { - id - values - } - buckets { - min - max - } - }`, - readSampledRecords: `{ - name - value - refId - }`, - readRecords: `{ - id - name - value - refId - }`, execExpression: `{ type results { diff --git a/src/hooks/useExpressionsProcessor.ts b/src/hooks/useExpressionsProcessor.ts index 60c66abe..080469ae 100644 --- a/src/hooks/useExpressionsProcessor.ts +++ b/src/hooks/useExpressionsProcessor.ts @@ -129,9 +129,9 @@ export async function useExpressionsQueryProcessor(config: Indexable) { } if (type === ExpressionResultType.SINGLE_VALUE) { for (const item of results) { - const label = item.metric.labels - .map((d: { key: string; value: string }) => `${d.key}=${d.value}`) - .join(","); + const label = + item.metric && + item.metric.labels.map((d: { key: string; value: string }) => `${d.key}=${d.value}`).join(","); const values = item.values.map((d: { value: unknown }) => d.value) || []; if (results.length === 1) { source[label || c.label || name] = values; diff --git a/src/hooks/useListConfig.ts b/src/hooks/useListConfig.ts deleted file mode 100644 index d0705b5d..00000000 --- a/src/hooks/useListConfig.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { MetricQueryTypes, Calculations } from "./data"; -import { MetricModes } from "@/views/dashboard/data"; - -export function useListConfig(config: Indexable, index: number) { - if (config.metricModes === MetricModes.Expression) { - return { - isLinear: false, - isAvg: true, - }; - } - const i = Number(index); - const types = [Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg]; - const calculation = config.metricConfig && config.metricConfig[i] && config.metricConfig[i].calculation; - const isLinear = - [MetricQueryTypes.ReadMetricsValues, MetricQueryTypes.ReadLabeledMetricsValues].includes(config.metricTypes[i]) && - !types.includes(calculation); - const isAvg = - [MetricQueryTypes.ReadMetricsValues, MetricQueryTypes.ReadLabeledMetricsValues].includes(config.metricTypes[i]) && - types.includes(calculation); - - return { - isLinear, - isAvg, - }; -} diff --git a/src/hooks/useMetricsProcessor.ts b/src/hooks/useMetricsProcessor.ts deleted file mode 100644 index b8ecc895..00000000 --- a/src/hooks/useMetricsProcessor.ts +++ /dev/null @@ -1,437 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import dayjs from "dayjs"; -import { RespFields, MetricQueryTypes, Calculations } from "./data"; -import { ElMessage } from "element-plus"; -import { useDashboardStore } from "@/store/modules/dashboard"; -import { useSelectorStore } from "@/store/modules/selectors"; -import { useAppStoreWithOut } from "@/store/modules/app"; -import type { Instance, Endpoint, Service } from "@/types/selector"; -import type { MetricConfigOpt } from "@/types/dashboard"; - -export function useQueryProcessor(config: Indexable) { - if (!(config.metrics && config.metrics[0])) { - return; - } - if (!(config.metricTypes && config.metricTypes[0])) { - return; - } - const appStore = useAppStoreWithOut(); - const dashboardStore = useDashboardStore(); - const selectorStore = useSelectorStore(); - - if (!selectorStore.currentService && dashboardStore.entity !== "All") { - return; - } - const conditions: Recordable = { - duration: appStore.durationTime, - }; - const variables: string[] = [`$duration: Duration!`]; - const isRelation = ["ServiceRelation", "ServiceInstanceRelation", "EndpointRelation", "ProcessRelation"].includes( - dashboardStore.entity, - ); - if (isRelation && !selectorStore.currentDestService) { - return; - } - const fragment = config.metrics.map((name: string, index: number) => { - const metricType = config.metricTypes[index] || ""; - const c = (config.metricConfig && config.metricConfig[index]) || {}; - if ([MetricQueryTypes.ReadSampledRecords, MetricQueryTypes.SortMetrics].includes(metricType)) { - variables.push(`$condition${index}: TopNCondition!`); - conditions[`condition${index}`] = { - name, - parentService: ["All"].includes(dashboardStore.entity) ? null : selectorStore.currentService.value, - normal: selectorStore.currentService ? selectorStore.currentService.normal : true, - topN: Number(c.topN) || 10, - order: c.sortOrder || "DES", - }; - } else { - const entity = { - serviceName: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.value, - normal: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.normal, - serviceInstanceName: ["ServiceInstance", "ServiceInstanceRelation", "ProcessRelation"].includes( - dashboardStore.entity, - ) - ? selectorStore.currentPod && selectorStore.currentPod.value - : undefined, - endpointName: dashboardStore.entity.includes("Endpoint") - ? selectorStore.currentPod && selectorStore.currentPod.value - : undefined, - processName: dashboardStore.entity.includes("Process") - ? selectorStore.currentProcess && selectorStore.currentProcess.value - : undefined, - destNormal: isRelation ? selectorStore.currentDestService.normal : undefined, - destServiceName: isRelation ? selectorStore.currentDestService.value : undefined, - destServiceInstanceName: ["ServiceInstanceRelation", "ProcessRelation"].includes(dashboardStore.entity) - ? selectorStore.currentDestPod && selectorStore.currentDestPod.value - : undefined, - destEndpointName: - dashboardStore.entity === "EndpointRelation" - ? selectorStore.currentDestPod && selectorStore.currentDestPod.value - : undefined, - destProcessName: dashboardStore.entity.includes("ProcessRelation") - ? selectorStore.currentDestProcess && selectorStore.currentDestProcess.value - : undefined, - }; - if ([MetricQueryTypes.ReadRecords].includes(metricType)) { - variables.push(`$condition${index}: RecordCondition!`); - conditions[`condition${index}`] = { - name, - parentEntity: entity, - topN: Number(c.topN) || 10, - order: c.sortOrder || "DES", - }; - } else { - if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) { - const labels = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); - variables.push(`$labels${index}: [String!]!`); - conditions[`labels${index}`] = labels; - } - variables.push(`$condition${index}: MetricsCondition!`); - conditions[`condition${index}`] = { - name, - entity, - }; - } - } - if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) { - return `${name}${index}: ${metricType}(condition: $condition${index}, labels: $labels${index}, duration: $duration)${RespFields[metricType]}`; - } - const t = metricType === MetricQueryTypes.ReadMetricsValue ? MetricQueryTypes.ReadNullableMetricsValue : metricType; - - return `${name}${index}: ${t}(condition: $condition${index}, duration: $duration)${RespFields[t]}`; - }); - const queryStr = `query queryData(${variables}) {${fragment}}`; - - return { - queryStr, - conditions, - }; -} -export function useSourceProcessor( - resp: { errors: string; data: Indexable }, - config: { - metrics: string[]; - metricTypes: string[]; - metricConfig: MetricConfigOpt[]; - }, -) { - if (resp.errors) { - ElMessage.error(resp.errors); - return {}; - } - if (!resp.data) { - ElMessage.error("The query is wrong"); - return {}; - } - const source: { [key: string]: unknown } = {}; - const keys = Object.keys(resp.data); - - config.metricTypes.forEach((type: string, index) => { - const m = config.metrics[index]; - const c = (config.metricConfig && config.metricConfig[index]) || {}; - - if (type === MetricQueryTypes.ReadMetricsValues) { - source[c.label || m] = (resp.data[keys[index]] && calculateExp(resp.data[keys[index]].values.values, c)) || []; - } - if (type === MetricQueryTypes.ReadLabeledMetricsValues) { - const resVal = Object.values(resp.data)[0] || []; - const labels = (c.label || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); - const labelsIdx = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); - for (const item of resVal) { - const values = item.values.values.map((d: { value: number; isEmptyValue: boolean }) => - d.isEmptyValue ? NaN : aggregation(Number(d.value), c), - ); - const indexNum = labelsIdx.findIndex((d: string) => d === item.label); - if (labels[indexNum] && indexNum > -1) { - source[labels[indexNum]] = values; - } else { - source[item.label] = values; - } - } - } - if (type === MetricQueryTypes.ReadMetricsValue) { - const v = Object.values(resp.data)[0] || {}; - source[m] = v.isEmptyValue ? NaN : aggregation(Number(v.value), c); - } - if ( - ( - [MetricQueryTypes.ReadRecords, MetricQueryTypes.ReadSampledRecords, MetricQueryTypes.SortMetrics] as string[] - ).includes(type) - ) { - source[m] = (Object.values(resp.data)[0] || []).map((d: { value: unknown; name: string }) => { - d.value = aggregation(Number(d.value), c); - - return d; - }); - } - if (type === MetricQueryTypes.READHEATMAP) { - const resVal = Object.values(resp.data)[0] || {}; - const nodes = [] as Indexable[]; - if (!(resVal && resVal.values)) { - source[m] = { nodes: [] }; - return; - } - resVal.values.forEach((items: { values: number[] }, x: number) => { - const grids = items.values.map((val: number, y: number) => [x, y, val]); - - nodes.push(...grids); - }); - let buckets = [] as Indexable[]; - if (resVal.buckets.length) { - buckets = [resVal.buckets[0].min, ...resVal.buckets.map((item: { min: string; max: string }) => item.max)]; - } - - source[m] = { nodes, buckets }; // nodes: number[][] - } - }); - - return source; -} - -export function useQueryPodsMetrics( - pods: Array<(Instance | Endpoint | Service) & Indexable>, - config: { - metrics: string[]; - metricTypes: string[]; - metricConfig: MetricConfigOpt[]; - }, - scope: string, -) { - const metricTypes = (config.metricTypes || []).filter((m: string) => m); - if (!metricTypes.length) { - return; - } - const metrics = (config.metrics || []).filter((m: string) => m); - if (!metrics.length) { - return; - } - const appStore = useAppStoreWithOut(); - const selectorStore = useSelectorStore(); - const conditions: { [key: string]: unknown } = { - duration: appStore.durationTime, - }; - const variables: string[] = [`$duration: Duration!`]; - const currentService = selectorStore.currentService || {}; - const fragmentList = pods.map((d: (Instance | Endpoint | Service) & Indexable, index: number) => { - const param = { - serviceName: scope === "Service" ? d.label : currentService.label, - serviceInstanceName: scope === "ServiceInstance" ? d.label : undefined, - endpointName: scope === "Endpoint" ? d.label : undefined, - normal: scope === "Service" ? d.normal : currentService.normal, - }; - const f = metrics.map((name: string, idx: number) => { - const metricType = metricTypes[idx] || ""; - variables.push(`$condition${index}${idx}: MetricsCondition!`); - conditions[`condition${index}${idx}`] = { - name, - entity: param, - }; - let labelStr = ""; - if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) { - const c = config.metricConfig[idx] || {}; - variables.push(`$labels${index}${idx}: [String!]!`); - labelStr = `labels: $labels${index}${idx}, `; - const labels = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); - conditions[`labels${index}${idx}`] = labels; - } - const t = - metricType === MetricQueryTypes.ReadMetricsValue ? MetricQueryTypes.ReadNullableMetricsValue : metricType; - return `${name}${index}${idx}: ${t}(condition: $condition${index}${idx}, ${labelStr}duration: $duration)${RespFields[t]}`; - }); - return f; - }); - const fragment = fragmentList.flat(1).join(" "); - const queryStr = `query queryData(${variables}) {${fragment}}`; - - return { queryStr, conditions }; -} - -export function usePodsSource( - pods: Array<Instance | Endpoint>, - resp: { errors: string; data: Indexable }, - config: { - metrics: string[]; - metricTypes: string[]; - metricConfig: MetricConfigOpt[]; - }, -): Indexable { - if (resp.errors) { - ElMessage.error(resp.errors); - return {}; - } - const names: string[] = []; - const metricConfigArr: MetricConfigOpt[] = []; - const metricTypesArr: string[] = []; - const data = pods.map((d: any, idx: number) => { - config.metrics.map((name: string, index: number) => { - const c: any = (config.metricConfig && config.metricConfig[index]) || {}; - const key = name + idx + index; - if (config.metricTypes[index] === MetricQueryTypes.ReadMetricsValue) { - const v = resp.data[key]; - d[name] = v.isEmptyValue ? NaN : aggregation(v.value, c); - if (idx === 0) { - names.push(name); - metricConfigArr.push(c); - metricTypesArr.push(config.metricTypes[index]); - } - } - if (config.metricTypes[index] === MetricQueryTypes.ReadMetricsValues) { - d[name] = {}; - if ([Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg].includes(c.calculation)) { - d[name]["avg"] = calculateExp(resp.data[key].values.values, c); - } - d[name]["values"] = resp.data[key].values.values.map((val: { value: number; isEmptyValue: boolean }) => - val.isEmptyValue ? NaN : aggregation(val.value, c), - ); - if (idx === 0) { - names.push(name); - metricConfigArr.push(c); - metricTypesArr.push(config.metricTypes[index]); - } - } - if (config.metricTypes[index] === MetricQueryTypes.ReadLabeledMetricsValues) { - const resVal = resp.data[key] || []; - const labels = (c.label || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); - const labelsIdx = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, "")); - for (let i = 0; i < resVal.length; i++) { - const item = resVal[i]; - const values = item.values.values.map((d: { value: number; isEmptyValue: boolean }) => - d.isEmptyValue ? NaN : aggregation(Number(d.value), c), - ); - const indexNum = labelsIdx.findIndex((d: string) => d === item.label); - let key = item.label; - if (labels[indexNum] && indexNum > -1) { - key = labels[indexNum]; - } - if (!d[key]) { - d[key] = {}; - } - if ([Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg].includes(c.calculation)) { - d[key]["avg"] = calculateExp(item.values.values, c); - } - d[key]["values"] = values; - if (idx === 0) { - names.push(key); - metricConfigArr.push({ ...c, index: i }); - metricTypesArr.push(config.metricTypes[index]); - } - } - } - }); - return d; - }); - return { data, names, metricConfigArr, metricTypesArr }; -} -export function useQueryTopologyMetrics(metrics: string[], ids: string[]) { - const appStore = useAppStoreWithOut(); - const conditions: { [key: string]: unknown } = { - duration: appStore.durationTime, - ids, - }; - const variables: string[] = [`$duration: Duration!`, `$ids: [ID!]!`]; - const fragmentList = metrics.map((d: string, index: number) => { - conditions[`m${index}`] = d; - variables.push(`$m${index}: String!`); - - return `${d}: getValues(metric: { - name: $m${index} - ids: $ids - }, duration: $duration) { - values { - id - value - } - }`; - }); - const queryStr = `query queryData(${variables}) {${fragmentList.join(" ")}}`; - - return { queryStr, conditions }; -} -export function calculateExp( - list: { value: number; isEmptyValue: boolean }[], - config: { calculation?: string }, -): (number | string)[] { - const arr = list.filter((d: { value: number; isEmptyValue: boolean }) => !d.isEmptyValue); - const sum = arr.length ? arr.map((d: { value: number }) => Number(d.value)).reduce((a, b) => a + b) : 0; - let data: (number | string)[] = []; - switch (config.calculation) { - case Calculations.Average: - data = [(sum / arr.length).toFixed(2)]; - break; - case Calculations.PercentageAvg: - data = [(sum / arr.length / 100).toFixed(2)]; - break; - case Calculations.ApdexAvg: - data = [(sum / arr.length / 10000).toFixed(2)]; - break; - default: - data = list.map((d: { value: number; isEmptyValue: boolean }) => - d.isEmptyValue ? NaN : aggregation(d.value, config), - ); - break; - } - return data; -} - -export function aggregation(val: number, config: { calculation?: string }): number | string { - let data: number | string = Number(val); - - switch (config.calculation) { - case Calculations.Percentage: - data = (val / 100).toFixed(2); - break; - case Calculations.PercentageAvg: - data = (val / 100).toFixed(2); - break; - case Calculations.ByteToKB: - data = (val / 1024).toFixed(2); - break; - case Calculations.ByteToMB: - data = (val / 1024 / 1024).toFixed(2); - break; - case Calculations.ByteToGB: - data = (val / 1024 / 1024 / 1024).toFixed(2); - break; - case Calculations.Apdex: - data = (val / 10000).toFixed(2); - break; - case Calculations.ConvertSeconds: - data = dayjs(val * 1000).format("YYYY-MM-DD HH:mm:ss"); - break; - case Calculations.ConvertMilliseconds: - data = dayjs(val).format("YYYY-MM-DD HH:mm:ss"); - break; - case Calculations.MsToS: - data = (val / 1000).toFixed(2); - break; - case Calculations.SecondToDay: - data = (val / 86400).toFixed(2); - break; - case Calculations.NanosecondToMillisecond: - data = (val / 1000 / 1000).toFixed(2); - break; - case Calculations.ApdexAvg: - data = (val / 10000).toFixed(2); - break; - default: - data; - break; - } - - return data; -} diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts index 9c9e065f..3fd57937 100644 --- a/src/locales/lang/en.ts +++ b/src/locales/lang/en.ts @@ -377,7 +377,6 @@ const msg = { menus: "Menus", saveReload: "Save and reload the page", document: "Documentation", - metricMode: "Metric Mode", addExpressions: "Add Expressions", expressions: "Expression", unhealthyExpression: "Unhealthy Expression", diff --git a/src/locales/lang/es.ts b/src/locales/lang/es.ts index dd08fad3..f9e1ef7f 100644 --- a/src/locales/lang/es.ts +++ b/src/locales/lang/es.ts @@ -377,7 +377,6 @@ const msg = { menus: "Menus", saveReload: "Save and reload the page", document: "Documentation", - metricMode: "Metric Mode", addExpressions: "Add Expressions", expressions: "Expression", unhealthyExpression: "Unhealthy Expression", diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts index 7549cc07..18a8dbfe 100644 --- a/src/locales/lang/zh.ts +++ b/src/locales/lang/zh.ts @@ -375,7 +375,6 @@ const msg = { menusManagement: "菜单", saveReload: "保存并重新加载页面", document: "文档", - metricMode: "指标模式", addExpressions: "添加表达式", expressions: "表达式", unhealthyExpression: "非健康表达式", diff --git a/src/store/modules/dashboard.ts b/src/store/modules/dashboard.ts index 46f6cac3..666577c6 100644 --- a/src/store/modules/dashboard.ts +++ b/src/store/modules/dashboard.ts @@ -24,7 +24,7 @@ import { useSelectorStore } from "@/store/modules/selectors"; import { NewControl, TextConfig, TimeRangeConfig, ControlsTypes } from "../data"; import type { AxiosResponse } from "axios"; import { ElMessage } from "element-plus"; -import { EntityType, MetricModes, WidgetType } from "@/views/dashboard/data"; +import { EntityType, WidgetType } from "@/views/dashboard/data"; interface DashboardState { showConfig: boolean; layout: LayoutConfig[]; @@ -88,13 +88,7 @@ export const dashboardStore = defineStore({ i: index, id: index, type, - metricTypes: [""], - metrics: [""], }; - - if (type === WidgetType.Widget) { - newItem.metricMode = MetricModes.Expression; - } if (type === WidgetType.Tab) { newItem.h = 36; newItem.activedTabIndex = 0; @@ -167,18 +161,12 @@ export const dashboardStore = defineStore({ i: index, id, type, - metricTypes: [""], - metrics: [""], }; - if (type === WidgetType.Widget) { - newItem.metricMode = MetricModes.Expression; - } if (type === WidgetType.Topology) { newItem.h = 32; newItem.graph = { showDepth: true, }; - newItem.metricMode = MetricModes.Expression; } if (ControlsTypes.includes(type)) { newItem.h = 32; diff --git a/src/store/modules/topology.ts b/src/store/modules/topology.ts index dee037ae..1a399134 100644 --- a/src/store/modules/topology.ts +++ b/src/store/modules/topology.ts @@ -23,7 +23,6 @@ import { useDashboardStore } from "@/store/modules/dashboard"; import { useAppStoreWithOut } from "@/store/modules/app"; import type { AxiosResponse } from "axios"; import query from "@/graphql/fetch"; -import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor"; import { useQueryTopologyExpressionsProcessor } from "@/hooks/useExpressionsProcessor"; import { ElMessage } from "element-plus"; @@ -226,9 +225,6 @@ export const topologyStore = defineStore({ setNodeMetricValue(m: MetricVal) { this.nodeMetricValue = m; }, - setNodeValue(m: MetricVal) { - this.nodeMetricValue = m; - }, setLegendValues(expressions: string, data: { [key: string]: any }) { for (let idx = 0; idx < this.nodes.length; idx++) { for (let index = 0; index < expressions.length; index++) { @@ -446,15 +442,6 @@ export const topologyStore = defineStore({ return { calls, nodes }; }, - async getNodeMetricValue(param: { queryStr: string; conditions: { [key: string]: unknown } }) { - const res: AxiosResponse = await query(param); - - if (res.data.errors) { - return res.data; - } - this.setNodeMetricValue(res.data.data); - return res.data; - }, async getNodeExpressionValue(param: { queryStr: string; conditions: { [key: string]: unknown } }) { const res: AxiosResponse = await query(param); @@ -464,38 +451,6 @@ export const topologyStore = defineStore({ return res.data; }, - async getLinkClientMetrics(linkClientMetrics: string[]) { - if (!linkClientMetrics.length) { - this.setLinkClientMetrics({}); - return; - } - const idsC = this.calls.filter((i: Call) => i.detectPoints.includes("CLIENT")).map((b: Call) => b.id); - if (!idsC.length) { - return; - } - const param = await useQueryTopologyMetrics(linkClientMetrics, idsC); - const res = await this.getCallClientMetrics(param); - - if (res.errors) { - ElMessage.error(res.errors); - } - }, - async getLinkServerMetrics(linkServerMetrics: string[]) { - if (!linkServerMetrics.length) { - this.setLinkServerMetrics({}); - return; - } - const idsS = this.calls.filter((i: Call) => i.detectPoints.includes("SERVER")).map((b: Call) => b.id); - if (!idsS.length) { - return; - } - const param = await useQueryTopologyMetrics(linkServerMetrics, idsS); - const res = await this.getCallServerMetrics(param); - - if (res.errors) { - ElMessage.error(res.errors); - } - }, async getLinkExpressions(expressions: string[], type: string) { if (!expressions.length) { this.setLinkServerMetrics({}); @@ -519,22 +474,6 @@ export const topologyStore = defineStore({ this.setLinkClientMetrics(metrics); } }, - async queryNodeMetrics(nodeMetrics: string[]) { - if (!nodeMetrics.length) { - this.setNodeMetricValue({}); - return; - } - const ids = this.nodes.map((d: Node) => d.id); - if (!ids.length) { - return; - } - const param = await useQueryTopologyMetrics(nodeMetrics, ids); - const res = await this.getNodeMetricValue(param); - - if (res.errors) { - ElMessage.error(res.errors); - } - }, async queryNodeExpressions(expressions: string[]) { if (!expressions.length) { this.setNodeMetricValue({}); @@ -557,44 +496,6 @@ export const topologyStore = defineStore({ const metrics = handleExpressionValues(res.data); this.setNodeMetricValue(metrics); }, - async getLegendMetrics(param: { queryStr: string; conditions: { [key: string]: unknown } }) { - const res: AxiosResponse = await query(param); - - if (res.data.errors) { - return res.data; - } - const data = res.data.data; - const metrics = Object.keys(data); - this.nodes = this.nodes.map((d: Node & Recordable) => { - for (const m of metrics) { - for (const val of data[m].values) { - if (d.id === val.id) { - d[m] = val.value; - } - } - } - return d; - }); - return res.data; - }, - async getCallServerMetrics(param: { queryStr: string; conditions: { [key: string]: unknown } }) { - const res: AxiosResponse = await query(param); - - if (res.data.errors) { - return res.data; - } - this.setLinkServerMetrics(res.data.data); - return res.data; - }, - async getCallClientMetrics(param: { queryStr: string; conditions: { [key: string]: unknown } }) { - const res: AxiosResponse = await query(param); - - if (res.data.errors) { - return res.data; - } - this.setLinkClientMetrics(res.data.data); - return res.data; - }, async getHierarchyServiceTopology() { const dashboardStore = useDashboardStore(); const { currentService } = useSelectorStore(); diff --git a/src/types/dashboard.d.ts b/src/types/dashboard.d.ts index be0bca58..5a24e53d 100644 --- a/src/types/dashboard.d.ts +++ b/src/types/dashboard.d.ts @@ -32,12 +32,9 @@ export interface LayoutConfig { h: number; i: string; type: string; - metricMode?: string; widget?: WidgetConfig; graph?: GraphConfig; - metrics?: string[]; expressions?: string[]; - metricTypes?: string[]; typesOfMQE?: string[]; children?: { name: string; children: LayoutConfig[]; expression?: string; enable?: boolean }[]; activedTabIndex?: number; @@ -77,7 +74,6 @@ export type Filters = { export type MetricConfigOpt = { unit?: string; label?: string; - calculation?: string; labelsIndex?: string; sortOrder?: string; topN?: number; diff --git a/src/views/dashboard/List.vue b/src/views/dashboard/List.vue index e57a92df..66285edc 100644 --- a/src/views/dashboard/List.vue +++ b/src/views/dashboard/List.vue @@ -304,6 +304,7 @@ limitations under the License. --> async function importTemplates(event: any) { const arr: any = await readFile(event); + for (const item of arr) { const { layer, name, entity } = item.configuration; const index = dashboardStore.dashboards.findIndex( @@ -359,6 +360,20 @@ limitations under the License. --> multipleTableRef.value!.clearSelection(); }, 2000); } + + function removeUnusedConfig(config: any) { + // remove `General` metrics config + delete config.metrics; + delete config.metricTypes; + delete config.metricMode; + delete config.linkServerMetrics; + delete config.linkClientMetrics; + delete config.nodeMetric; + if (([WidgetType.Topology] as string[]).includes(config.type)) { + delete config.legend; + } + } + function optimizeTemplate( children: (LayoutConfig & { moved?: boolean; @@ -390,17 +405,8 @@ limitations under the License. --> if (isEmptyObject(child.widget)) { delete child.widget; } - if (!(child.metrics && child.metrics.length && child.metrics[0])) { - delete child.metrics; - } - if (!(child.metricTypes && child.metricTypes.length && child.metricTypes[0])) { - delete child.metricTypes; - } if (child.metricConfig && child.metricConfig.length) { child.metricConfig.forEach((c, index) => { - if (!c.calculation) { - delete c.calculation; - } if (!c.unit) { delete c.unit; } @@ -415,6 +421,7 @@ limitations under the License. --> if (!(child.metricConfig && child.metricConfig.length)) { delete child.metricConfig; } + removeUnusedConfig(child); if (child.type === WidgetType.Tab) { for (const item of child.children || []) { optimizeTemplate(item.children); diff --git a/src/views/dashboard/Widget.vue b/src/views/dashboard/Widget.vue index 1bbf7215..6a87e97e 100644 --- a/src/views/dashboard/Widget.vue +++ b/src/views/dashboard/Widget.vue @@ -32,10 +32,7 @@ limitations under the License. --> :config="{ i: 0, ...graph, - metrics: config.metrics, - metricTypes: config.metricTypes, metricConfig: config.metricConfig, - metricMode: config.metricMode, expressions: config.expressions || [], typesOfMQE: typesOfMQE || [], subExpressions: config.subExpressions || [], @@ -56,12 +53,10 @@ limitations under the License. --> import { useRoute } from "vue-router"; import { useSelectorStore } from "@/store/modules/selectors"; import { useDashboardStore } from "@/store/modules/dashboard"; - import { useQueryProcessor, useSourceProcessor } from "@/hooks/useMetricsProcessor"; import { useExpressionsQueryProcessor } from "@/hooks/useExpressionsProcessor"; import graphs from "./graphs"; import { EntityType } from "./data"; import timeFormat from "@/utils/timeFormat"; - import { MetricModes } from "./data"; export default defineComponent({ name: "WidgetPage", @@ -132,37 +127,16 @@ limitations under the License. --> } } async function queryMetrics() { - const isExpression = config.value.metricMode === MetricModes.Expression; - if (isExpression) { - loading.value = true; - const params = await useExpressionsQueryProcessor({ - metrics: config.value.expressions || [], - metricConfig: config.value.metricConfig || [], - subExpressions: config.value.subExpressions || [], - }); - - loading.value = false; - source.value = params.source || {}; - typesOfMQE.value = params.typesOfMQE; - return; - } - const params = await useQueryProcessor({ ...config.value }); - if (!params) { - source.value = {}; - return; - } loading.value = true; - const json = await dashboardStore.fetchMetricValue(params); - loading.value = false; - if (!json) { - return; - } - const d = { - metrics: config.value.metrics || [], - metricTypes: config.value.metricTypes || [], + const params = await useExpressionsQueryProcessor({ + metrics: config.value.expressions || [], metricConfig: config.value.metricConfig || [], - }; - source.value = await useSourceProcessor(json, d); + subExpressions: config.value.subExpressions || [], + }); + + loading.value = false; + source.value = params.source || {}; + typesOfMQE.value = params.typesOfMQE; } watch( () => appStoreWithOut.durationTime, @@ -209,7 +183,7 @@ limitations under the License. --> height: 25px; line-height: 25px; text-align: center; - background-color: aliceblue; + background-color: var(--sw-config-header); font-size: $font-size-smaller; position: relative; } diff --git a/src/views/dashboard/components/WidgetLink.vue b/src/views/dashboard/components/WidgetLink.vue index 3660c504..fe159940 100644 --- a/src/views/dashboard/components/WidgetLink.vue +++ b/src/views/dashboard/components/WidgetLink.vue @@ -54,7 +54,6 @@ limitations under the License. --> import copy from "@/utils/copy"; import { RefreshOptions } from "@/views/dashboard/data"; import { TimeType } from "@/constants/data"; - import { MetricModes } from "../data"; const { t } = useI18n(); const appStore = useAppStoreWithOut(); @@ -88,8 +87,7 @@ limitations under the License. --> step: appStore.durationRow.step, utc: appStore.utc, }); - const { widget, graph, metrics, metricTypes, metricConfig, metricMode, expressions, typesOfMQE, subExpressions } = - dashboardStore.selectedGrid; + const { widget, graph, metricConfig, expressions, typesOfMQE, subExpressions } = dashboardStore.selectedGrid; const c = (metricConfig || []).map((d: any) => { const t: any = {}; if (d.label) { @@ -103,19 +101,13 @@ limitations under the License. --> const opt: any = { type: dashboardStore.selectedGrid.type, graph: graph, - metricMode, metricConfig: c, height: dashboardStore.selectedGrid.h * 20 + 60, }; - if (metricMode === MetricModes.Expression) { - opt.expressions = expressions; - opt.typesOfMQE = typesOfMQE; - if (subExpressions && subExpressions.length) { - opt.subExpressions = subExpressions; - } - } else { - opt.metrics = metrics; - opt.metricTypes = metricTypes; + opt.expressions = expressions; + opt.typesOfMQE = typesOfMQE; + if (subExpressions && subExpressions.length) { + opt.subExpressions = subExpressions; } if (widget) { opt.widget = { diff --git a/src/views/dashboard/configuration/Widget.vue b/src/views/dashboard/configuration/Widget.vue index dd846a99..62248e94 100644 --- a/src/views/dashboard/configuration/Widget.vue +++ b/src/views/dashboard/configuration/Widget.vue @@ -34,11 +34,8 @@ limitations under the License. --> ...graph, legend: (dashboardStore.selectedGrid.graph || {}).legend, i: dashboardStore.selectedGrid.i, - metrics: dashboardStore.selectedGrid.metrics, - metricTypes: dashboardStore.selectedGrid.metricTypes, metricConfig: dashboardStore.selectedGrid.metricConfig, relatedTrace: dashboardStore.selectedGrid.relatedTrace, - metricMode: dashboardStore.selectedGrid.metricMode, expressions: dashboardStore.selectedGrid.expressions || [], typesOfMQE: dashboardStore.selectedGrid.typesOfMQE || [], subExpressions: dashboardStore.selectedGrid.subExpressions || [], @@ -89,7 +86,6 @@ limitations under the License. --> import type { Option } from "@/types/app"; import graphs from "../graphs"; import CustomOptions from "./widget/index"; - import { MetricModes } from "../data"; export default defineComponent({ name: "WidgetEdit", @@ -142,23 +138,6 @@ limitations under the License. --> function applyConfig() { dashboardStore.setConfigPanel(false); - const { metricMode } = dashboardStore.selectedGrid; - let p = {}; - if (metricMode === MetricModes.Expression) { - p = { - metrics: [], - metricTypes: [], - }; - } else { - p = { - expressions: [], - typesOfMQE: [], - }; - } - dashboardStore.selectWidget({ - ...dashboardStore.selectedGrid, - ...p, - }); dashboardStore.setConfigs(dashboardStore.selectedGrid); } diff --git a/src/views/dashboard/configuration/widget/metric/Index.vue b/src/views/dashboard/configuration/widget/metric/Index.vue index a58d2d9a..44cfc4aa 100644 --- a/src/views/dashboard/configuration/widget/metric/Index.vue +++ b/src/views/dashboard/configuration/widget/metric/Index.vue @@ -25,28 +25,20 @@ limitations under the License. --> :clearable="true" /> </div> - <div>{{ t("metrics") }}</div> <div class="flex-h"> - <el-switch - v-model="isExpression" - class="mb-5" - active-text="Expressions" - inactive-text="General" - size="small" - @change="changeMetricMode" - /> - <div class="ml-5 link"> + <div>{{ t("metrics") }}</div> + <div class="link"> <a target="_blank" href="https://skywalking.apache.org/docs/main/next/en/api/metrics-query-expression/"> <Icon iconName="info_outline" size="middle" /> </a> </div> </div> - <div v-if="isExpression && states.isList"> + <div v-if="states.isList"> <span class="title">{{ t("summary") }}</span> <span>{{ t("detail") }}</span> </div> <div v-for="(metric, index) in states.metrics" :key="index" class="mb-10"> - <span v-if="isExpression"> + <span> <div class="expression-param" contenteditable="true" @blur="changeExpression($event, index)"> {{ metric }} </div> @@ -59,24 +51,6 @@ limitations under the License. --> {{ states.subMetrics[index] }} </div> </span> - <span v-else> - <Selector - :value="metric" - :options="states.metricList" - size="small" - placeholder="Select a metric" - @change="changeMetrics(index, $event)" - class="selectors" - /> - <Selector - :value="states.metricTypes[index]" - :options="states.metricTypeList[index]" - size="small" - :disabled="graph.type && !states.isList && index !== 0" - @change="changeMetricType(index, $event)" - class="selectors" - /> - </span> <el-popover placement="top" :width="400" trigger="click"> <template #reference> <span @click="setMetricConfig(index)"> @@ -88,7 +62,7 @@ limitations under the License. --> <span v-show=" states.isList || - [ProtocolTypes.ReadMetricsValues, ExpressionResultType.TIME_SERIES_VALUES as string].includes(states.metricTypes[0]) + [ExpressionResultType.TIME_SERIES_VALUES as string].includes(states.metricTypes[0]) " > <Icon @@ -100,13 +74,13 @@ limitations under the License. --> /> <Icon class="cp" iconName="remove_circle_outline" size="middle" @click="deleteMetric(index)" /> </span> - <div v-if="(states.tips || [])[index] && isExpression" class="ml-10 red sm"> + <div v-if="(states.tips || [])[index]" class="ml-10 red sm"> {{ states.tips[index] }} </div> - <div v-if="(errors || [])[index] && isExpression" class="ml-10 red sm"> + <div v-if="(errors || [])[index]" class="ml-10 red sm"> {{ (errors || [])[index] }} </div> - <div v-if="(subErrors || [])[index] && isExpression" class="ml-10 red sm"> + <div v-if="(subErrors || [])[index]" class="ml-10 red sm"> {{ (subErrors || [])[index] }} </div> </div> @@ -128,20 +102,14 @@ limitations under the License. --> import type { Option } from "@/types/app"; import { useDashboardStore } from "@/store/modules/dashboard"; import { - MetricTypes, ListChartTypes, DefaultGraphConfig, EntityType, ChartTypes, PodsChartTypes, - MetricsType, - ProtocolTypes, ExpressionResultType, - MetricModes, - } from "../../../data"; - import { ElMessage } from "element-plus"; + } from "@/views/dashboard/data"; import Icon from "@/components/Icon.vue"; - import { useQueryProcessor, useSourceProcessor } from "@/hooks/useMetricsProcessor"; import { useExpressionsQueryProcessor } from "@/hooks/useExpressionsProcessor"; import { useI18n } from "vue-i18n"; import type { DashboardItem, MetricConfigOpt } from "@/types/dashboard"; @@ -160,16 +128,11 @@ limitations under the License. --> }, }); const dashboardStore = useDashboardStore(); - const isExpression = ref<boolean>(dashboardStore.selectedGrid.metricMode === MetricModes.Expression); - const metrics = computed( - () => (isExpression.value ? dashboardStore.selectedGrid.expressions : dashboardStore.selectedGrid.metrics) || [], - ); - const subMetrics = computed(() => (isExpression.value ? dashboardStore.selectedGrid.subExpressions : []) || []); - const subMetricTypes = computed(() => (isExpression.value ? dashboardStore.selectedGrid.subTypesOfMQE : []) || []); + const metrics = computed(() => dashboardStore.selectedGrid.expressions || []); + const subMetrics = computed(() => dashboardStore.selectedGrid.subExpressions || []); + const subMetricTypes = computed(() => dashboardStore.selectedGrid.subTypesOfMQE || []); const graph = computed(() => dashboardStore.selectedGrid.graph || {}); - const metricTypes = computed( - () => (isExpression.value ? dashboardStore.selectedGrid.typesOfMQE : dashboardStore.selectedGrid.metricTypes) || [], - ); + const typesOfMQE = computed(() => dashboardStore.selectedGrid.typesOfMQE || []); const states = reactive<{ metrics: string[]; subMetrics: string[]; @@ -177,17 +140,15 @@ limitations under the License. --> metricTypes: string[]; metricTypeList: Option[][]; isList: boolean; - metricList: (Option & { type: string })[]; dashboardName: string; dashboardList: ((DashboardItem & { label: string; value: string }) | any)[]; tips: string[]; subTips: string[]; }>({ metrics: metrics.value.length ? metrics.value : [""], - metricTypes: metricTypes.value.length ? metricTypes.value : [""], + metricTypes: typesOfMQE.value.length ? typesOfMQE.value : [""], metricTypeList: [], isList: false, - metricList: [], dashboardName: graph.value.dashboardName, dashboardList: [{ label: "", value: "" }], tips: [], @@ -199,16 +160,13 @@ limitations under the License. --> unit: "", label: "", labelsIndex: "", - calculation: "", sortOrder: "DES", }); states.isList = ListChartTypes.includes(graph.value.type); const defaultLen = ref<number>(states.isList ? 5 : 20); - const backupMetricConfig = ref<MetricConfigOpt[]>([]); setDashboards(); - setMetricType(); const setVisTypes = computed(() => { let graphs = []; @@ -223,70 +181,6 @@ limitations under the License. --> return graphs; }); - async function setMetricType(chart?: any) { - const g = chart || dashboardStore.selectedGrid.graph || {}; - let arr: any[] = states.metricList; - if (!chart) { - const json = await dashboardStore.fetchMetricList(); - if (json.errors) { - ElMessage.error(json.errors); - return; - } - arr = json.data.metrics; - } - states.metricList = (arr || []).filter((d: { type: string }) => { - if (states.isList) { - if (d.type === MetricsType.REGULAR_VALUE || d.type === MetricsType.LABELED_VALUE) { - return d; - } - } else if (g.type === "Table") { - if (d.type === MetricsType.LABELED_VALUE || d.type === MetricsType.REGULAR_VALUE) { - return d; - } - } else { - return d; - } - }); - if (isExpression.value) { - if (states.metrics && states.metrics[0]) { - queryMetrics(); - } else { - emit("update", {}); - } - return; - } - const metrics: any = states.metricList.filter((d: { value: string; type: string }) => - states.metrics.includes(d.value), - ); - - if (metrics.length) { - // keep states.metrics index - const m = metrics.map((d: { value: string }) => d.value); - states.metrics = states.metrics.filter((d) => m.includes(d)); - } else { - states.metrics = [""]; - states.metricTypes = [""]; - } - dashboardStore.selectWidget({ - ...dashboardStore.selectedGrid, - metrics: states.metrics, - metricTypes: states.metricTypes, - graph: g, - }); - states.metricTypeList = []; - for (const metric of metrics) { - if (states.metrics.includes(metric.value)) { - const arr = setMetricTypeList(metric.type); - states.metricTypeList.push(arr); - } - } - if (states.metrics && states.metrics[0]) { - queryMetrics(); - } else { - emit("update", {}); - } - } - function setDashboards(type?: string) { const chart = type || (dashboardStore.selectedGrid.graph && dashboardStore.selectedGrid.graph.type); const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]"); @@ -308,6 +202,11 @@ limitations under the License. --> }, []); states.dashboardList = arr.length ? arr : [{ label: "", value: "" }]; + if (states.metrics && states.metrics[0]) { + queryMetrics(); + } else { + emit("update", {}); + } } function changeChartType(item: Option) { @@ -316,8 +215,6 @@ limitations under the License. --> if (states.isList) { dashboardStore.selectWidget({ ...dashboardStore.selectedGrid, - metrics: [""], - metricTypes: [""], expressions: [""], typesOfMQE: [""], }); @@ -326,97 +223,20 @@ limitations under the License. --> defaultLen.value = 5; } - if (isExpression.value) { - dashboardStore.selectWidget({ - ...dashboardStore.selectedGrid, - graph: chart, - }); - } else { - setMetricType(chart); - } - setDashboards(chart.type); - states.dashboardName = ""; - defaultLen.value = 10; - } - - function changeMetrics(index: number, arr: (Option & { type: string })[] | any) { - if (!arr.length) { - states.metricTypeList = []; - states.metricTypes = []; - dashboardStore.selectWidget({ - ...dashboardStore.selectedGrid, - ...{ metricTypes: states.metricTypes, metrics: states.metrics }, - }); - return; - } - states.metrics[index] = arr[0].value; - const typeOfMetrics = arr[0].type; - - states.metricTypeList[index] = setMetricTypeList(typeOfMetrics); - states.metricTypes[index] = MetricTypes[typeOfMetrics][0].value; dashboardStore.selectWidget({ ...dashboardStore.selectedGrid, - ...{ metricTypes: states.metricTypes, metrics: states.metrics }, + graph: chart, }); - if (states.isList) { - return; - } - queryMetrics(); + setDashboards(chart.type); + states.dashboardName = ""; + defaultLen.value = 10; } - function changeMetricType(index: number, opt: Option[] | any) { - const metric = states.metricList.filter((d: Option) => states.metrics[index] === d.value)[0] || {}; - const l = setMetricTypeList(metric.type); - if (states.isList) { - states.metricTypes[index] = opt[0].value; - states.metricTypeList[index] = l; - } else { - states.metricTypes = states.metricTypes.map((d: string) => { - d = opt[0].value; - return d; - }); - states.metricTypeList = states.metricTypeList.map((d: Option[]) => { - d = l; - - return d; - }); - } - dashboardStore.selectWidget({ - ...dashboardStore.selectedGrid, - ...{ metricTypes: states.metricTypes }, - }); - if (states.isList) { - return; - } - queryMetrics(); - } async function queryMetrics() { if (states.isList) { return; } - if (isExpression.value) { - queryMetricsWithExpressions(); - return; - } - const { metricConfig, metricTypes, metrics } = dashboardStore.selectedGrid; - if (!(metrics && metrics[0] && metricTypes && metricTypes[0])) { - return emit("update", {}); - } - const params = useQueryProcessor({ ...states, metricConfig }); - if (!params) { - emit("update", {}); - return; - } - - emit("loading", true); - const json = await dashboardStore.fetchMetricValue(params); - emit("loading", false); - if (json.errors) { - ElMessage.error(json.errors); - return; - } - const source = useSourceProcessor(json, { ...states, metricConfig }); - emit("update", source); + queryMetricsWithExpressions(); } async function queryMetricsWithExpressions() { @@ -432,7 +252,6 @@ limitations under the License. --> ...dashboardStore.selectedGrid, typesOfMQE: states.metricTypes, }); - emit("update", params.source || {}); } @@ -454,43 +273,32 @@ limitations under the License. --> function addMetric() { states.metrics.push(""); states.tips.push(""); - if (isExpression.value && states.isList) { + if (states.isList) { states.subMetrics.push(""); states.subTips.push(""); } if (!states.isList) { states.metricTypes.push(states.metricTypes[0]); - if (!isExpression.value) { - states.metricTypeList.push(states.metricTypeList[0]); - } return; } states.metricTypes.push(""); - if (isExpression.value && states.isList) { - states.subMetricTypes.push(""); - } } function deleteMetric(index: number) { if (states.metrics.length === 1) { states.metrics = [""]; states.metricTypes = [""]; states.tips = [""]; - let v = {}; - if (isExpression.value) { - v = { typesOfMQE: states.metricTypes, expressions: states.metrics }; - if (states.isList) { - states.subMetrics = [""]; - states.subMetricTypes = [""]; - states.subTips = [""]; - v = { - ...v, - subTypesOfMQE: states.subMetricTypes, - subExpressions: states.subMetrics, - }; - } - } else { - v = { metricTypes: states.metricTypes, metrics: states.metrics }; + let v: any = { typesOfMQE: states.metricTypes, expressions: states.metrics }; + if (states.isList) { + states.subMetrics = [""]; + states.subMetricTypes = [""]; + states.subTips = [""]; + v = { + ...v, + subTypesOfMQE: states.subMetricTypes, + subExpressions: states.subMetrics, + }; } dashboardStore.selectWidget({ ...dashboardStore.selectedGrid, @@ -505,37 +313,26 @@ limitations under the License. --> const config = dashboardStore.selectedGrid.metricConfig || []; const metricConfig = config[index] ? config.splice(index, 1) : config; let p = {}; - if (isExpression.value) { - if (states.isList) { - states.subMetrics.splice(index, 1); - states.subMetricTypes.splice(index, 1); - states.subTips.splice(index, 1); - p = { - ...p, - typesOfMQE: states.metricTypes, - expressions: states.metrics, - subTypesOfMQE: states.subMetricTypes, - subExpressions: states.subMetrics, - }; - } - } else { - p = { metricTypes: states.metricTypes, metrics: states.metrics }; + if (states.isList) { + states.subMetrics.splice(index, 1); + states.subMetricTypes.splice(index, 1); + states.subTips.splice(index, 1); + p = { + ...p, + typesOfMQE: states.metricTypes, + expressions: states.metrics, + subTypesOfMQE: states.subMetricTypes, + subExpressions: states.subMetrics, + }; } dashboardStore.selectWidget({ ...dashboardStore.selectedGrid, ...p, metricConfig, }); + queryMetrics(); } - function setMetricTypeList(type: string) { - if (type !== MetricsType.REGULAR_VALUE) { - return MetricTypes[type]; - } - if (states.isList || graph.value.type === "Table") { - return [MetricTypes.REGULAR_VALUE[0], MetricTypes.REGULAR_VALUE[1]]; - } - return MetricTypes[type]; - } + function setMetricConfig(index: number) { const n = { unit: "", @@ -553,20 +350,6 @@ limitations under the License. --> ...dashboardStore.selectedGrid.metricConfig[index], }; } - function changeMetricMode() { - states.metrics = metrics.value.length ? metrics.value : [""]; - states.subMetrics = subMetrics.value.length ? subMetrics.value : [""]; - states.metricTypes = metricTypes.value.length ? metricTypes.value : [""]; - states.subMetricTypes = subMetricTypes.value.length ? subMetricTypes.value : [""]; - const config = dashboardStore.selectedGrid.metricConfig; - dashboardStore.selectWidget({ - ...dashboardStore.selectedGrid, - metricMode: isExpression.value ? MetricModes.Expression : MetricModes.General, - metricConfig: backupMetricConfig.value, - }); - backupMetricConfig.value = config; - queryMetrics(); - } async function changeExpression(event: any, index: number) { const params = (event.target.textContent || "").replace(/\s+/g, ""); @@ -651,5 +434,6 @@ limitations under the License. --> .link { cursor: pointer; color: $active-color; + padding-left: 2px; } </style> diff --git a/src/views/dashboard/configuration/widget/metric/Standard.vue b/src/views/dashboard/configuration/widget/metric/Standard.vue index 5b88699b..6b8de5b6 100644 --- a/src/views/dashboard/configuration/widget/metric/Standard.vue +++ b/src/views/dashboard/configuration/widget/metric/Standard.vue @@ -28,7 +28,7 @@ limitations under the License. --> " /> </div> - <div class="item mb-10" v-if="hasLabel || isExpression"> + <div class="item mb-10"> <span class="label">{{ t("labels") }}</span> <el-input class="input" @@ -42,7 +42,7 @@ limitations under the License. --> " /> </div> - <div class="item mb-10" v-if="isList && isExpression"> + <div class="item mb-10" v-if="isList"> <span class="label">{{ t("detailLabel") }}</span> <el-input class="input" @@ -56,30 +56,6 @@ limitations under the License. --> " /> </div> - <div class="item mb-10" v-if="[ProtocolTypes.ReadLabeledMetricsValues].includes(metricType) && !isExpression"> - <span class="label">{{ t("labelsIndex") }}</span> - <el-input - class="input" - v-model="currentMetric.labelsIndex" - size="small" - placeholder="auto" - @change=" - updateConfig(index, { - labelsIndex: encodeURIComponent(currentMetric.labelsIndex || ''), - }) - " - /> - </div> - <div class="item mb-10" v-show="!isExpression"> - <span class="label">{{ t("aggregation") }}</span> - <SelectSingle - :value="currentMetric.calculation" - :options="CalculationOpts" - @change="changeConfigs(index, { calculation: $event })" - class="selectors" - :clearable="true" - /> - </div> <div class="item mb-10" v-show="isTopn"> <span class="label">{{ t("sortOrder") }}</span> <SelectSingle @@ -108,10 +84,9 @@ limitations under the License. --> import { ref, watch, computed } from "vue"; import type { PropType } from "vue"; import { useI18n } from "vue-i18n"; - import { SortOrder, CalculationOpts, MetricModes } from "../../../data"; + import { SortOrder, ExpressionResultType, ListChartTypes } from "@/views/dashboard/data"; import { useDashboardStore } from "@/store/modules/dashboard"; import type { MetricConfigOpt } from "@/types/dashboard"; - import { ListChartTypes, ProtocolTypes } from "../../../data"; /*global defineEmits, defineProps */ const props = defineProps({ @@ -124,30 +99,17 @@ limitations under the License. --> const { t } = useI18n(); const emit = defineEmits(["update"]); const dashboardStore = useDashboardStore(); - const isExpression = ref<boolean>(dashboardStore.selectedGrid.metricMode === MetricModes.Expression); const currentMetric = ref<MetricConfigOpt>({ ...props.currentMetricConfig, topN: props.currentMetricConfig.topN || 10, }); - const metricTypes = computed( - () => (isExpression.value ? dashboardStore.selectedGrid.typesOfMQE : dashboardStore.selectedGrid.metricTypes) || [], - ); - const metricType = computed(() => metricTypes.value[props.index]); - const hasLabel = computed(() => { - const graph = dashboardStore.selectedGrid.graph || {}; - return ( - ListChartTypes.includes(graph.type) || - [ProtocolTypes.ReadLabeledMetricsValues, ProtocolTypes.ReadMetricsValues].includes(metricType.value) - ); - }); + const metricTypes = computed(() => dashboardStore.selectedGrid.typesOfMQE || []); const isList = computed(() => { const graph = dashboardStore.selectedGrid.graph || {}; return ListChartTypes.includes(graph.type); }); const isTopn = computed(() => - [ProtocolTypes.SortMetrics, ProtocolTypes.ReadSampledRecords, ProtocolTypes.ReadRecords].includes( - metricTypes.value[props.index], - ), + [ExpressionResultType.RECORD_LIST, ExpressionResultType.SORTED_LIST].includes(metricTypes.value[props.index]), ); function updateConfig(index: number, param: { [key: string]: string }) { @@ -170,7 +132,6 @@ limitations under the License. --> watch( () => props.currentMetricConfig, () => { - isExpression.value = dashboardStore.selectedGrid.metricMode === MetricModes.Expression; currentMetric.value = { ...props.currentMetricConfig, topN: Number(props.currentMetricConfig.topN) || 10, diff --git a/src/views/dashboard/controls/Widget.vue b/src/views/dashboard/controls/Widget.vue index f7ac3812..49078a07 100644 --- a/src/views/dashboard/controls/Widget.vue +++ b/src/views/dashboard/controls/Widget.vue @@ -51,15 +51,12 @@ limitations under the License. --> :data="state.source" :config="{ ...data.graph, - metrics: data.metrics || [''], - metricTypes: data.metricTypes || [''], i: data.i, id: data.id, metricConfig: data.metricConfig || [], filters: data.filters || {}, relatedTrace: data.relatedTrace || {}, associate: data.associate || [], - metricMode: data.metricMode, expressions: data.expressions || [], typesOfMQE: typesOfMQE || [], subExpressions: data.subExpressions || [], @@ -81,12 +78,10 @@ limitations under the License. --> import { useSelectorStore } from "@/store/modules/selectors"; import graphs from "../graphs"; import { useI18n } from "vue-i18n"; - import { useQueryProcessor, useSourceProcessor } from "@/hooks/useMetricsProcessor"; import { useExpressionsQueryProcessor } from "@/hooks/useExpressionsProcessor"; import { EntityType, ListChartTypes } from "../data"; import type { EventParams } from "@/types/dashboard"; import getDashboard from "@/hooks/useDashboardsSession"; - import { MetricModes } from "../data"; const props = { data: { @@ -121,38 +116,15 @@ limitations under the License. --> } async function queryMetrics() { - const isExpression = props.data.metricMode === MetricModes.Expression; - - if (isExpression) { - loading.value = true; - const e = { - metrics: props.data.expressions || [], - metricConfig: props.data.metricConfig || [], - }; - const params = (await useExpressionsQueryProcessor(e)) || {}; - loading.value = false; - state.source = params.source || {}; - typesOfMQE.value = params.typesOfMQE; - return; - } - const params = await useQueryProcessor({ ...props.data }); - - if (!params) { - state.source = {}; - return; - } loading.value = true; - const json = await dashboardStore.fetchMetricValue(params); - loading.value = false; - if (!json) { - return; - } - const d = { - metrics: props.data.metrics || [], - metricTypes: props.data.metricTypes || [], + const e = { + metrics: props.data.expressions || [], metricConfig: props.data.metricConfig || [], }; - state.source = await useSourceProcessor(json, d); + const params = (await useExpressionsQueryProcessor(e)) || {}; + loading.value = false; + state.source = params.source || {}; + typesOfMQE.value = params.typesOfMQE; } function removeWidget() { @@ -188,7 +160,7 @@ limitations under the License. --> dashboardStore.selectWidget(props.data); } watch( - () => [props.data.metricTypes, props.data.metrics, props.data.expressions], + () => props.data.expressions, () => { if (!dashboardStore.selectedGrid) { return; diff --git a/src/views/dashboard/data.ts b/src/views/dashboard/data.ts index 7cb2d458..c691ba02 100644 --- a/src/views/dashboard/data.ts +++ b/src/views/dashboard/data.ts @@ -34,29 +34,6 @@ export const ChartTypes = [ { label: "Endpoint List", value: "EndpointList" }, { label: "Instance List", value: "InstanceList" }, ]; -export const MetricChartType: any = { - readMetricsValue: [{ label: "Card", value: "Card" }], - readMetricsValues: [ - { label: "Bar", value: "Bar" }, - { label: "Line", value: "Line" }, - { label: "Area", value: "Area" }, - ], - sortMetrics: [{ label: "Top List", value: "TopList" }], - readLabeledMetricsValues: [{ label: "Line", value: "Line" }], - readHeatMap: [{ label: "Heat Map", value: "HeatMap" }], - readSampledRecords: [{ label: "Top List", value: "TopList" }], - readRecords: [{ label: "Top List", value: "TopList" }], -}; -export enum ProtocolTypes { - ReadRecords = "readRecords", - ReadSampledRecords = "readSampledRecords", - SortMetrics = "sortMetrics", - ReadLabeledMetricsValues = "readLabeledMetricsValues", - ReadHeatMap = "readHeatMap", - ReadMetricsValues = "readMetricsValues", - ReadMetricsValue = "readMetricsValue", -} - export enum ExpressionResultType { UNKNOWN = "UNKNOWN", SINGLE_VALUE = "SINGLE_VALUE", @@ -124,34 +101,6 @@ export const DefaultGraphConfig: { [key: string]: any } = { }, }; -export enum MetricsType { - UNKNOWN = "UNKNOWN", - REGULAR_VALUE = "REGULAR_VALUE", - LABELED_VALUE = "LABELED_VALUE", - HEATMAP = "HEATMAP", - SAMPLED_RECORD = "SAMPLED_RECORD", -} -export const MetricTypes: { - [key: string]: Array<{ label: string; value: string }>; -} = { - REGULAR_VALUE: [ - { label: "read all values in the duration", value: "readMetricsValues" }, - { - label: "read the single value in the duration", - value: "readMetricsValue", - }, - { label: "get sorted top N values", value: "sortMetrics" }, - ], - LABELED_VALUE: [ - { - label: "read all values of labels in the duration", - value: "readLabeledMetricsValues", - }, - ], - HEATMAP: [{ label: "read heatmap values in the duration", value: "readHeatMap" }], - SAMPLED_RECORD: [{ label: "get sorted topN values", value: "readRecords" }], -}; - export enum MetricCatalog { SERVICE = "Service", SERVICE_INSTANCE = "ServiceInstance", @@ -292,19 +241,6 @@ export const ScopeType = [ { value: "Endpoint", label: "Endpoint", key: 3 }, { value: "ServiceInstance", label: "Service Instance", key: 3 }, ]; -export const LegendConditions = [ - { label: "&&", value: "and" }, - { label: "||", value: "or" }, -]; -export const MetricConditions = [ - { label: ">", value: ">" }, - { label: "<", value: "<" }, -]; -export enum LegendOpt { - NAME = "name", - VALUE = "value", - CONDITION = "condition", -} export const DepthList = [1, 2, 3, 4, 5].map((item: number) => ({ value: item, label: String(item), @@ -329,24 +265,6 @@ export const TextColors: { [key: string]: string } = { purple: "#bf99f8", }; -export const CalculationOpts = [ - { label: "Percentage", value: "percentage" }, - { label: "Apdex", value: "apdex" }, - { label: "Avg-preview", value: "average" }, - { label: "Percentage + Avg-preview", value: "percentageAvg" }, - { label: "Apdex + Avg-preview", value: "apdexAvg" }, - { label: "Byte to KB", value: "byteToKB" }, - { label: "Byte to MB", value: "byteToMB" }, - { label: "Byte to GB", value: "byteToGB" }, - { - label: "Milliseconds to YYYY-MM-DD HH:mm:ss", - value: "convertMilliseconds", - }, - { label: "Seconds to YYYY-MM-DD HH:mm:ss", value: "convertSeconds" }, - { label: "Milliseconds to seconds", value: "msTos" }, - { label: "Seconds to days", value: "secondToDay" }, - { label: "Nanoseconds to milliseconds", value: "nanosecondToMillisecond" }, -]; export const RefIdTypes = [ { label: "Trace ID", value: "traceId" }, { label: "None", value: "none" }, @@ -357,10 +275,6 @@ export const RefreshOptions = [ { label: "Last 7 days", value: "7", step: "DAY" }, ]; -export enum MetricModes { - Expression = "Expression", - General = "General", -} export enum CallTypes { Server = "SERVER", Client = "CLIENT", diff --git a/src/views/dashboard/graphs/EndpointList.vue b/src/views/dashboard/graphs/EndpointList.vue index 4f07cd6d..3831b043 100644 --- a/src/views/dashboard/graphs/EndpointList.vue +++ b/src/views/dashboard/graphs/EndpointList.vue @@ -40,8 +40,7 @@ limitations under the License. --> :config="{ ...config, metricConfig, - metricTypes, - metricMode, + typesOfMQE, }" v-if="colMetrics.length" /> @@ -58,9 +57,8 @@ limitations under the License. --> import type { EndpointListConfig } from "@/types/dashboard"; import type { Endpoint } from "@/types/selector"; import { useDashboardStore } from "@/store/modules/dashboard"; - import { useQueryPodsMetrics, usePodsSource } from "@/hooks/useMetricsProcessor"; import { useExpressionsQueryPodsMetrics } from "@/hooks/useExpressionsProcessor"; - import { EntityType, MetricModes } from "../data"; + import { EntityType } from "../data"; import router from "@/router"; import getDashboard from "@/hooks/useDashboardsSession"; import type { MetricConfigOpt } from "@/types/dashboard"; @@ -75,9 +73,6 @@ limitations under the License. --> type: Object as PropType< EndpointListConfig & { i: string; - metrics: string[]; - metricTypes: string[]; - metricMode: string; expressions: string[]; typesOfMQE: string[]; subExpressions: string[]; @@ -85,8 +80,6 @@ limitations under the License. --> } & { metricConfig: MetricConfigOpt[] } >, default: () => ({ - metrics: [], - metricTypes: [], dashboardName: "", fontSize: 12, i: "", @@ -106,8 +99,7 @@ limitations under the License. --> const colMetrics = ref<string[]>([]); const colSubMetrics = ref<string[]>([]); const metricConfig = ref<MetricConfigOpt[]>(props.config.metricConfig || []); - const metricTypes = ref<string[]>(props.config.metricTypes || []); - const metricMode = ref<string>(props.config.metricMode); + const typesOfMQE = ref<string[]>(props.config.typesOfMQE || []); if (props.needQuery) { queryEndpoints(); @@ -138,34 +130,7 @@ limitations under the License. --> merge: d.merge, }; }); - if (props.config.metricMode === MetricModes.Expression) { - queryEndpointExpressions(currentPods); - return; - } - const metrics = props.config.metrics || []; - const types = props.config.metricTypes || []; - if (metrics.length && metrics[0] && types.length && types[0]) { - const params = await useQueryPodsMetrics(currentPods, props.config, EntityType[2].value); - const json = await dashboardStore.fetchMetricValue(params); - - if (json.errors) { - ElMessage.error(json.errors); - return; - } - const { data, names, metricConfigArr, metricTypesArr } = usePodsSource(currentPods, json, { - ...props.config, - metricConfig: metricConfig.value, - }); - endpoints.value = data; - colMetrics.value = names; - metricTypes.value = metricTypesArr; - metricConfig.value = metricConfigArr; - return; - } - endpoints.value = currentPods; - colMetrics.value = []; - metricTypes.value = []; - metricConfig.value = []; + queryEndpointExpressions(currentPods); } async function queryEndpointExpressions(currentPods: Endpoint[]) { const expressions = props.config.expressions || []; @@ -180,8 +145,8 @@ limitations under the License. --> endpoints.value = params.data; colMetrics.value = params.names; colSubMetrics.value = params.subNames; - metricTypes.value = params.metricTypesArr; metricConfig.value = params.metricConfigArr; + typesOfMQE.value = params.metricTypesArr; emit("expressionTips", { tips: params.expressionsTips, subTips: params.subExpressionsTips }); return; @@ -189,8 +154,8 @@ limitations under the License. --> endpoints.value = currentPods; colMetrics.value = []; colSubMetrics.value = []; - metricTypes.value = []; metricConfig.value = []; + typesOfMQE.value = []; emit("expressionTips", [], []); } function clickEndpoint(scope: any) { @@ -212,19 +177,15 @@ limitations under the License. --> } watch( () => [ - ...(props.config.metricTypes || []), - ...(props.config.metrics || []), ...(props.config.metricConfig || []), ...(props.config.expressions || []), ...(props.config.subExpressions || []), - props.config.metricMode, ], (data, old) => { if (JSON.stringify(data) === JSON.stringify(old)) { return; } metricConfig.value = props.config.metricConfig; - metricMode.value = props.config.metricMode; queryEndpointMetrics(endpoints.value); }, ); diff --git a/src/views/dashboard/graphs/InstanceList.vue b/src/views/dashboard/graphs/InstanceList.vue index 4c9b4d30..f54c8c53 100644 --- a/src/views/dashboard/graphs/InstanceList.vue +++ b/src/views/dashboard/graphs/InstanceList.vue @@ -39,8 +39,7 @@ limitations under the License. --> :config="{ ...config, metricConfig, - metricTypes, - metricMode, + typesOfMQE, }" v-if="colMetrics.length" /> @@ -85,9 +84,8 @@ limitations under the License. --> import { useDashboardStore } from "@/store/modules/dashboard"; import type { InstanceListConfig } from "@/types/dashboard"; import type { Instance } from "@/types/selector"; - import { useQueryPodsMetrics, usePodsSource } from "@/hooks/useMetricsProcessor"; import { useExpressionsQueryPodsMetrics } from "@/hooks/useExpressionsProcessor"; - import { EntityType, MetricModes } from "../data"; + import { EntityType } from "../data"; import router from "@/router"; import getDashboard from "@/hooks/useDashboardsSession"; import type { MetricConfigOpt } from "@/types/dashboard"; @@ -100,9 +98,7 @@ limitations under the License. --> InstanceListConfig & { i: string; metrics: string[]; - metricTypes: string[]; isEdit: boolean; - metricMode: string; expressions: string[]; typesOfMQE: string[]; subExpressions: string[]; @@ -114,7 +110,7 @@ limitations under the License. --> fontSize: 12, i: "", metrics: [], - metricTypes: [], + typesOfMQE: [], }), }, intervalTime: { type: Array as PropType<string[]>, default: () => [] }, @@ -131,9 +127,9 @@ limitations under the License. --> const colMetrics = ref<string[]>([]); const colSubMetrics = ref<string[]>([]); const metricConfig = ref<MetricConfigOpt[]>(props.config.metricConfig || []); - const metricTypes = ref<string[]>(props.config.metricTypes || []); const pods = ref<Instance[]>([]); // all instances - const metricMode = ref<string>(props.config.metricMode); + const typesOfMQE = ref<string[]>(props.config.typesOfMQE || []); + if (props.needQuery) { queryInstance(); } @@ -169,36 +165,7 @@ limitations under the License. --> attributes: d.attributes, }; }); - if (props.config.metricMode === MetricModes.Expression) { - queryInstanceExpressions(currentInstances); - return; - } - const metrics = props.config.metrics || []; - const types = props.config.metricTypes || []; - - if (metrics.length && metrics[0] && types.length && types[0]) { - const params = await useQueryPodsMetrics(currentInstances, props.config, EntityType[3].value); - const json = await dashboardStore.fetchMetricValue(params); - - if (json.errors) { - ElMessage.error(json.errors); - return; - } - const { data, names, metricConfigArr, metricTypesArr } = usePodsSource(currentInstances, json, { - ...props.config, - metricConfig: metricConfig.value, - }); - instances.value = data; - colMetrics.value = names; - metricTypes.value = metricTypesArr; - metricConfig.value = metricConfigArr; - - return; - } - instances.value = currentInstances; - colMetrics.value = []; - metricTypes.value = []; - metricConfig.value = []; + queryInstanceExpressions(currentInstances); } async function queryInstanceExpressions(currentInstances: Instance[]) { @@ -214,7 +181,7 @@ limitations under the License. --> instances.value = params.data; colMetrics.value = params.names; colSubMetrics.value = params.subNames; - metricTypes.value = params.metricTypesArr; + typesOfMQE.value = params.metricTypesArr; metricConfig.value = params.metricConfigArr; emit("expressionTips", { tips: params.expressionsTips, subTips: params.subExpressionsTips }); @@ -223,7 +190,7 @@ limitations under the License. --> instances.value = currentInstances; colSubMetrics.value = []; colMetrics.value = []; - metricTypes.value = []; + typesOfMQE.value = []; metricConfig.value = []; emit("expressionTips", [], []); } @@ -262,19 +229,15 @@ limitations under the License. --> watch( () => [ - ...(props.config.metricTypes || []), - ...(props.config.metrics || []), ...(props.config.metricConfig || []), ...(props.config.expressions || []), ...(props.config.subExpressions || []), - props.config.metricMode, ], (data, old) => { if (JSON.stringify(data) === JSON.stringify(old)) { return; } metricConfig.value = props.config.metricConfig; - metricMode.value = props.config.metricMode; queryInstanceMetrics(instances.value); }, ); diff --git a/src/views/dashboard/graphs/ServiceList.vue b/src/views/dashboard/graphs/ServiceList.vue index 1cf8f641..7a3a8bdd 100644 --- a/src/views/dashboard/graphs/ServiceList.vue +++ b/src/views/dashboard/graphs/ServiceList.vue @@ -51,8 +51,7 @@ limitations under the License. --> :config="{ ...config, metricConfig, - metricTypes, - metricMode, + typesOfMQE, }" v-if="colMetrics.length" /> @@ -78,9 +77,8 @@ limitations under the License. --> import { useDashboardStore } from "@/store/modules/dashboard"; import { useAppStoreWithOut } from "@/store/modules/app"; import type { Service } from "@/types/selector"; - import { useQueryPodsMetrics, usePodsSource } from "@/hooks/useMetricsProcessor"; import { useExpressionsQueryPodsMetrics } from "@/hooks/useExpressionsProcessor"; - import { EntityType, MetricModes } from "../data"; + import { EntityType } from "../data"; import router from "@/router"; import getDashboard from "@/hooks/useDashboardsSession"; import type { MetricConfigOpt } from "@/types/dashboard"; @@ -95,12 +93,9 @@ limitations under the License. --> type: Object as PropType< ServiceListConfig & { i: string; - metrics: string[]; - metricTypes: string[]; isEdit: boolean; names: string[]; metricConfig: MetricConfigOpt[]; - metricMode: string; expressions: string[]; typesOfMQE: string[]; subExpressions: string[]; @@ -125,8 +120,7 @@ limitations under the License. --> const groups = ref<any>({}); const sortServices = ref<(Service & { merge: boolean })[]>([]); const metricConfig = ref<MetricConfigOpt[]>(props.config.metricConfig || []); - const metricTypes = ref<string[]>(props.config.metricTypes || []); - const metricMode = ref<string>(props.config.metricMode); + const typesOfMQE = ref<string[]>(props.config.typesOfMQE || []); queryServices(); @@ -211,43 +205,7 @@ limitations under the License. --> shortName: d.shortName, }; }); - if (props.config.metricMode === MetricModes.Expression) { - queryServiceExpressions(currentServices); - return; - } - const metrics = props.config.metrics || []; - const types = props.config.metricTypes || []; - - if (metrics.length && metrics[0] && types.length && types[0]) { - const params = await useQueryPodsMetrics( - currentServices, - { ...props.config, metricConfig: metricConfig.value || [] }, - EntityType[0].value, - ); - const json = await dashboardStore.fetchMetricValue(params); - - if (json.errors) { - ElMessage.error(json.errors); - return; - } - - const { data, names, metricConfigArr, metricTypesArr } = usePodsSource(currentServices, json, { - ...props.config, - metricConfig: metricConfig.value || [], - }); - - services.value = data; - colMetrics.value = names; - metricTypes.value = metricTypesArr; - metricConfig.value = metricConfigArr; - - return; - } - services.value = currentServices; - colMetrics.value = []; - colMetrics.value = []; - metricTypes.value = []; - metricConfig.value = []; + queryServiceExpressions(currentServices); } async function queryServiceExpressions(currentServices: Service[]) { const expressions = props.config.expressions || []; @@ -262,16 +220,16 @@ limitations under the License. --> services.value = params.data; colMetrics.value = params.names; colSubMetrics.value = params.subNames; - metricTypes.value = params.metricTypesArr; metricConfig.value = params.metricConfigArr; + typesOfMQE.value = params.metricTypesArr; emit("expressionTips", { tips: params.expressionsTips, subTips: params.subExpressionsTips }); return; } services.value = currentServices; colMetrics.value = []; colSubMetrics.value = []; - metricTypes.value = []; metricConfig.value = []; + typesOfMQE.value = []; emit("expressionTips", [], []); } function objectSpanMethod(param: any): any { @@ -306,19 +264,15 @@ limitations under the License. --> watch( () => [ - ...(props.config.metricTypes || []), - ...(props.config.metrics || []), ...(props.config.metricConfig || []), ...(props.config.expressions || []), ...(props.config.subExpressions || []), - props.config.metricMode, ], (data, old) => { if (JSON.stringify(data) === JSON.stringify(old)) { return; } metricConfig.value = props.config.metricConfig; - metricMode.value = props.config.metricMode; queryServiceMetrics(services.value); }, ); diff --git a/src/views/dashboard/graphs/Table.vue b/src/views/dashboard/graphs/Table.vue index 2ab46c05..baaf2190 100644 --- a/src/views/dashboard/graphs/Table.vue +++ b/src/views/dashboard/graphs/Table.vue @@ -56,7 +56,6 @@ limitations under the License. --> type: Object as PropType<{ showTableValues: boolean; tableHeaderCol2: string; - metricTypes: string[]; typesOfMQE: string[]; }>, default: () => ({ showTableValues: true }), @@ -66,10 +65,6 @@ limitations under the License. --> const { t } = useI18n(); const nameWidth = computed(() => (props.config.showTableValues ? 80 : 100)); const dataKeys = computed(() => { - if (props.config.metricTypes && props.config.metricTypes[0] === "readMetricsValue") { - const keys = Object.keys(props.data || {}); - return keys; - } const keys = Object.keys(props.data || {}).filter( (i: string) => Array.isArray(props.data[i]) && props.data[i].length, ); diff --git a/src/views/dashboard/graphs/TopList.vue b/src/views/dashboard/graphs/TopList.vue index 434a18ae..1b5b427d 100644 --- a/src/views/dashboard/graphs/TopList.vue +++ b/src/views/dashboard/graphs/TopList.vue @@ -64,8 +64,7 @@ limitations under the License. --> import copy from "@/utils/copy"; import { TextColors } from "@/views/dashboard/data"; import Trace from "@/views/dashboard/related/trace/Index.vue"; - import { QueryOrders, Status, RefIdTypes, ProtocolTypes, ExpressionResultType } from "../data"; - import { WidgetType } from "@/views/dashboard/data"; + import { WidgetType, QueryOrders, Status, RefIdTypes, ExpressionResultType } from "@/views/dashboard/data"; /*global defineProps */ const props = defineProps({ @@ -77,10 +76,8 @@ limitations under the License. --> }, config: { type: Object as PropType<{ - metricMode: string; color: string; - metrics: string[]; - metricTypes: string[]; + expressions: string[]; typesOfMQE: string[]; relatedTrace: any; }>, @@ -116,11 +113,8 @@ limitations under the License. --> queryOrder: QueryOrders[1].value, status: Status[2].value, id: item.refId, - metricValue: [{ label: props.config.metrics[0], data: item.value, value: item.name }], - isReadRecords: - props.config.typesOfMQE.includes(ExpressionResultType.RECORD_LIST) || - props.config.metricTypes.includes(ProtocolTypes.ReadRecords) || - undefined, + metricValue: [{ label: props.config.expressions[0], data: item.value, value: item.name }], + isReadRecords: props.config.typesOfMQE.includes(ExpressionResultType.RECORD_LIST) || undefined, }; traceOptions.value = { ...traceOptions.value, diff --git a/src/views/dashboard/graphs/components/ColumnGraph.vue b/src/views/dashboard/graphs/components/ColumnGraph.vue index 0e57216e..22be8438 100644 --- a/src/views/dashboard/graphs/components/ColumnGraph.vue +++ b/src/views/dashboard/graphs/components/ColumnGraph.vue @@ -22,23 +22,7 @@ limitations under the License. --> > <template #default="scope"> <div class="chart"> - <Line - v-if="useListConfig(config, index).isLinear && config.metricMode !== MetricModes.Expression" - :data="{ - [metric]: scope.row[metric] && scope.row[metric].values, - }" - :intervalTime="intervalTime" - :config="{ - showXAxis: false, - showYAxis: false, - smallTips: true, - showlabels: false, - }" - /> - <span - class="item flex-h" - v-else-if="useListConfig(config, index).isAvg || config.metricMode === MetricModes.Expression" - > + <span class="item flex-h"> <el-popover placement="left" :width="400" trigger="click"> <template #reference> <span class="trend"> @@ -70,7 +54,6 @@ limitations under the License. --> /> </span> </span> - <Card v-else :data="{ [metric]: scope.row[metric] }" :config="{ textAlign: 'left' }" /> </div> </template> </el-table-column> @@ -79,11 +62,9 @@ limitations under the License. --> <script lang="ts" setup> import type { PropType } from "vue"; import type { MetricConfigOpt } from "@/types/dashboard"; - import { useListConfig } from "@/hooks/useListConfig"; import Line from "../Line.vue"; import Card from "../Card.vue"; - import { MetricQueryTypes } from "@/hooks/data"; - import { ExpressionResultType, MetricModes } from "@/views/dashboard/data"; + import { ExpressionResultType } from "@/views/dashboard/data"; /*global defineProps */ const props = defineProps({ @@ -92,9 +73,8 @@ limitations under the License. --> config: { type: Object as PropType<{ i: string; - metricTypes: string[]; + typesOfMQE: string[]; metricConfig: MetricConfigOpt[]; - metricMode: string; }>, default: () => ({}), }, @@ -120,13 +100,9 @@ limitations under the License. --> } if (label) { if ( - ( - [ - MetricQueryTypes.ReadLabeledMetricsValues, - ExpressionResultType.TIME_SERIES_VALUES, - ExpressionResultType.SINGLE_VALUE, - ] as string[] - ).includes(props.config.metricTypes[i]) + ([ExpressionResultType.TIME_SERIES_VALUES, ExpressionResultType.SINGLE_VALUE] as string[]).includes( + props.config.typesOfMQE[i], + ) ) { const name = (label || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""))[ props.config.metricConfig[i].index || 0 diff --git a/src/views/dashboard/related/topology/config/Metrics.vue b/src/views/dashboard/related/topology/config/Metrics.vue index 6a5d6f7f..d33b759c 100644 --- a/src/views/dashboard/related/topology/config/Metrics.vue +++ b/src/views/dashboard/related/topology/config/Metrics.vue @@ -19,7 +19,7 @@ limitations under the License. --> {{ t("expressions") }} </span> <span class="label" v-else> - {{ t(dashboardStore.selectedGrid.metricMode === MetricModes.General ? "metrics" : "expressions") }} + {{ t("expressions") }} </span> <SelectSingle :value="currentMetric" :options="metricList" @change="changeMetric" class="selectors" /> </div> @@ -43,33 +43,19 @@ limitations under the License. --> @change="changeConfigs({ label: currentConfig.label })" /> </div> - <div - class="item mb-10" - v-if="type !== 'hierarchyServicesConfig' && dashboardStore.selectedGrid.metricMode === MetricModes.General" - > - <span class="label">{{ t("aggregation") }}</span> - <SelectSingle - :value="currentConfig.calculation" - :options="CalculationOpts" - @change="changeConfigs({ calculation: $event })" - class="selectors" - :clearable="true" - /> - </div> </div> </template> <script lang="ts" setup> import { ref, computed, watch } from "vue"; import { useI18n } from "vue-i18n"; import type { Option } from "@/types/app"; - import { CalculationOpts, MetricModes, EntityType, ConfigFieldTypes } from "@/views/dashboard/data"; + import { EntityType, ConfigFieldTypes } from "@/views/dashboard/data"; import { useDashboardStore } from "@/store/modules/dashboard"; import getDashboard from "@/hooks/useDashboardsSession"; /*global defineEmits, defineProps */ const props = defineProps({ type: { type: String, default: "" }, - isExpression: { type: Boolean, default: true }, layer: { type: String, default: "" }, expressions: { type: Array<string>, default: () => [] }, entity: { type: String, default: EntityType[0].value }, @@ -82,23 +68,16 @@ limitations under the License. --> return props.expressions || []; } let metrics: string[] = []; - const { - linkServerExpressions, - linkServerMetrics, - linkClientExpressions, - linkClientMetrics, - nodeExpressions, - nodeMetrics, - } = dashboardStore.selectedGrid; + const { linkServerExpressions, linkClientExpressions, nodeExpressions } = dashboardStore.selectedGrid; switch (props.type) { case "linkServerMetricConfig": - metrics = props.isExpression ? linkServerExpressions : linkServerMetrics; + metrics = linkServerExpressions; break; case "linkClientMetricConfig": - metrics = props.isExpression ? linkClientExpressions : linkClientMetrics; + metrics = linkClientExpressions; break; case "nodeMetricConfig": - metrics = props.isExpression ? nodeExpressions : nodeMetrics; + metrics = nodeExpressions; break; } return metrics || []; diff --git a/src/views/dashboard/related/topology/config/Settings.vue b/src/views/dashboard/related/topology/config/Settings.vue index 45af09ce..1d231a9f 100644 --- a/src/views/dashboard/related/topology/config/Settings.vue +++ b/src/views/dashboard/related/topology/config/Settings.vue @@ -13,17 +13,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <template> - <div class="mt-20"> - <h5 class="title">{{ t("metricMode") }}</h5> - <el-switch - v-model="isExpression" - class="mt-5" - active-text="Expressions" - inactive-text="General" - size="small" - @change="changeMetricMode" - /> - </div> <div class="mb-20"> <h5 class="title">{{ t("callSettings") }}</h5> <div class="label">{{ t("linkDashboard") }}</div> @@ -38,21 +27,16 @@ limitations under the License. --> /> <div class="label"> <span>{{ t("linkServerMetrics") }}</span> - <el-popover - placement="left" - :width="400" - trigger="click" - v-if="isExpression ? states.linkServerExpressions.length : states.linkServerMetrics.length" - > + <el-popover placement="left" :width="400" trigger="click" v-if="states.linkServerExpressions.length"> <template #reference> <span @click="setConfigType('linkServerMetricConfig')"> <Icon class="cp ml-5" iconName="mode_edit" size="middle" /> </span> </template> - <Metrics :type="configType" :isExpression="isExpression" @update="updateSettings" /> + <Metrics :type="configType" @update="updateSettings" /> </el-popover> </div> - <div v-if="isExpression"> + <div> <Tags :tags="states.linkServerExpressions" :vertical="true" @@ -60,34 +44,19 @@ limitations under the License. --> @change="(param: string[]) => changeLinkServerExpressions(param)" /> </div> - <Selector - v-else - class="inputs" - :multiple="true" - :value="states.linkServerMetrics" - :options="states.linkMetricList" - size="small" - placeholder="Select metrics" - @change="updateLinkServerMetrics" - /> <span v-show="dashboardStore.entity !== EntityType[2].value"> <div class="label"> <span>{{ t("linkClientMetrics") }}</span> - <el-popover - placement="left" - :width="400" - trigger="click" - v-if="isExpression ? states.linkClientExpressions.length : states.linkClientMetrics.length" - > + <el-popover placement="left" :width="400" trigger="click" v-if="states.linkClientExpressions.length"> <template #reference> <span @click="setConfigType('linkClientMetricConfig')"> <Icon class="cp ml-5" iconName="mode_edit" size="middle" /> </span> </template> - <Metrics :type="configType" :isExpression="isExpression" @update="updateSettings" /> + <Metrics :type="configType" @update="updateSettings" /> </el-popover> </div> - <div v-if="isExpression"> + <div> <Tags :tags="states.linkClientExpressions" :vertical="true" @@ -95,16 +64,6 @@ limitations under the License. --> @change="(param: string[]) => changeLinkClientExpressions(param)" /> </div> - <Selector - v-else - class="inputs" - :multiple="true" - :value="states.linkClientMetrics" - :options="states.linkMetricList" - size="small" - placeholder="Select metrics" - @change="updateLinkClientMetrics" - /> </span> </div> <div> @@ -149,21 +108,16 @@ limitations under the License. --> </div> <div class="label"> <span>{{ t("nodeMetrics") }}</span> - <el-popover - placement="left" - :width="400" - trigger="click" - v-if="isExpression ? states.nodeExpressions.length : states.nodeMetrics.length" - > + <el-popover placement="left" :width="400" trigger="click" v-if="states.nodeExpressions.length"> <template #reference> <span @click="setConfigType('nodeMetricConfig')"> <Icon class="cp ml-5" iconName="mode_edit" size="middle" /> </span> </template> - <Metrics :type="configType" :isExpression="isExpression" @update="updateSettings" /> + <Metrics :type="configType" @update="updateSettings" /> </el-popover> </div> - <div v-if="isExpression"> + <div> <Tags :tags="states.nodeExpressions" :vertical="true" @@ -171,28 +125,17 @@ limitations under the License. --> @change="(param: string[]) => changeNodeExpressions(param)" /> </div> - <Selector - v-else - class="inputs" - :multiple="true" - :value="states.nodeMetrics" - :options="states.nodeMetricList" - size="small" - placeholder="Select metrics" - @change="updateNodeMetrics" - /> </div> <div v-show="isService"> <h5 class="title">{{ t("legendSettings") }}</h5> - <span v-if="isExpression"> + <span> <div class="label">Healthy Description</div> <el-input v-model="description.healthy" placeholder="Please input description" size="small" class="mt-5" /> </span> <div class="label"> - <span>{{ t(isExpression ? "unhealthyExpression" : "conditions") }}</span> + <span>{{ t("unhealthyExpression") }}</span> <el-tooltip class="cp" - v-if="isExpression" content="The node would be red to indicate unhealthy status when the expression return greater than 0" > <span> @@ -200,50 +143,9 @@ limitations under the License. --> </span> </el-tooltip> </div> - <div v-if="isExpression"> + <div> <el-input v-model="legendMQE.expression" placeholder="Please input a expression" size="small" class="inputs" /> </div> - <div v-for="(metric, index) of legend" :key="index" v-else> - <Selector - class="item" - :value="metric.name" - :options="states.nodeMetricList" - size="small" - placeholder="Select a metric" - @change="changeLegend(LegendOpt.NAME, $event, index)" - /> - <Selector - class="input-small" - :value="metric.condition" - :options="MetricConditions" - size="small" - placeholder="Select a condition" - @change="changeLegend(LegendOpt.CONDITION, $event, index)" - /> - <el-input - v-model="metric.value" - placeholder="Please input a value" - type="number" - @change="changeLegend(LegendOpt.VALUE, $event, index)" - size="small" - class="item" - /> - <span> - <Icon class="cp delete" iconName="remove_circle_outline" size="middle" @click="deleteMetric(index)" /> - <Icon - class="cp" - iconName="add_circle_outlinecontrol_point" - size="middle" - v-show="index === legend.length - 1 && legend.length < 5" - @click="addMetric" - /> - </span> - <div v-show="index !== legend.length - 1">&&</div> - </div> - <span v-if="!isExpression"> - <div class="label">Healthy Description</div> - <el-input v-model="description.healthy" placeholder="Please input description" size="small" class="mt-5" /> - </span> <div class="label">Unhealthy Description</div> <el-input v-model="description.unhealthy" placeholder="Please input description" size="small" class="mt-5" /> <el-button @click="setLegend" class="mt-20" size="small" type="primary"> @@ -257,20 +159,9 @@ limitations under the License. --> import { useDashboardStore } from "@/store/modules/dashboard"; import { useTopologyStore } from "@/store/modules/topology"; import { ElMessage } from "element-plus"; - import { - MetricCatalog, - ScopeType, - MetricConditions, - EntityType, - LegendOpt, - MetricsType, - MetricModes, - CallTypes, - } from "@/views/dashboard/data"; + import { ScopeType, EntityType, CallTypes } from "@/views/dashboard/data"; import type { Option } from "@/types/app"; - import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor"; import { useQueryTopologyExpressionsProcessor } from "@/hooks/useExpressionsProcessor"; - import type { Node } from "@/types/topology"; import type { DashboardItem, MetricConfigOpt } from "@/types/dashboard"; import Metrics from "./Metrics.vue"; @@ -280,7 +171,6 @@ limitations under the License. --> const dashboardStore = useDashboardStore(); const topologyStore = useTopologyStore(); const { selectedGrid } = dashboardStore; - const isExpression = ref<boolean>(dashboardStore.selectedGrid.metricMode === MetricModes.Expression); const nodeDashboard = selectedGrid.nodeDashboard && selectedGrid.nodeDashboard.length ? selectedGrid.nodeDashboard : ""; const isService = [EntityType[0].value, EntityType[1].value].includes(dashboardStore.entity); @@ -296,11 +186,6 @@ limitations under the License. --> scope: string; dashboard: string; }[]; - linkServerMetrics: string[]; - linkClientMetrics: string[]; - nodeMetrics: string[]; - nodeMetricList: Option[]; - linkMetricList: Option[]; linkDashboards: (DashboardItem & { label: string; value: string })[]; nodeDashboards: (DashboardItem & { label: string; value: string })[]; linkServerExpressions: string[]; @@ -309,27 +194,18 @@ limitations under the License. --> }>({ linkDashboard: selectedGrid.linkDashboard || "", nodeDashboard: selectedGrid.nodeDashboard || [], - linkServerMetrics: selectedGrid.linkServerMetrics || [], - linkClientMetrics: selectedGrid.linkClientMetrics || [], - nodeMetrics: selectedGrid.nodeMetrics || [], - nodeMetricList: [], - linkMetricList: [], linkDashboards: [], nodeDashboards: [], linkServerExpressions: selectedGrid.linkServerExpressions || [], linkClientExpressions: selectedGrid.linkClientExpressions || [], nodeExpressions: selectedGrid.nodeExpressions || [], }); - const l = selectedGrid.legend && selectedGrid.legend.length; - const legend = ref<{ name: string; condition: string; value: string }[]>( - l ? selectedGrid.legend : [{ name: "", condition: "", value: "" }], - ); const legendMQE = ref<{ expression: string }>(selectedGrid.legendMQE || { expression: "" }); const configType = ref<string>(""); const description = reactive<any>(selectedGrid.description || {}); - getMetricList(); - async function getMetricList() { + getDashboardList(); + async function getDashboardList() { const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]"); const json = await dashboardStore.fetchMetricList(); if (json.errors) { @@ -351,13 +227,6 @@ limitations under the License. --> }, [], ); - states.nodeMetricList = (json.data.metrics || []).filter( - (d: { type: string }) => d.type === MetricsType.REGULAR_VALUE, - ); - states.linkMetricList = (json.data.metrics || []).filter( - (d: { catalog: string; type: string }) => - entity + "Relation" === (MetricCatalog as any)[d.catalog] && d.type === MetricsType.REGULAR_VALUE, - ); if (isService) { return; } @@ -373,36 +242,15 @@ limitations under the License. --> } async function setLegend() { updateSettings(); - if (isExpression.value) { - const expression = dashboardStore.selectedGrid.legendMQE && dashboardStore.selectedGrid.legendMQE.expression; - if (!expression) { - emit("updateNodes"); - return; - } - const { getExpressionQuery } = useQueryTopologyExpressionsProcessor([expression], topologyStore.nodes); - const param = getExpressionQuery(); - const res = await topologyStore.getNodeExpressionValue(param); - if (res.errors) { - ElMessage.error(res.errors); - } else { - topologyStore.setLegendValues([expression], res.data); - } + const expression = dashboardStore.selectedGrid.legendMQE && dashboardStore.selectedGrid.legendMQE.expression; + const { getExpressionQuery } = useQueryTopologyExpressionsProcessor([expression], topologyStore.nodes); + const param = getExpressionQuery(); + const res = await topologyStore.getNodeExpressionValue(param); + if (res.errors) { + ElMessage.error(res.errors); } else { - const names = dashboardStore.selectedGrid.legend.map((d: any) => d.name && d.condition && d.value); - if (!names.length) { - emit("updateNodes"); - return; - } - const ids = topologyStore.nodes.map((d: Node) => d.id); - const param = await useQueryTopologyMetrics(names, ids); - const res = await topologyStore.getLegendMetrics(param); - - if (res.errors) { - ElMessage.error(res.errors); - } + topologyStore.setLegendValues([expression], res.data); } - - emit("updateNodes"); } function changeNodeDashboard(opt: any) { states.nodeDashboard = opt[0].value; @@ -412,9 +260,6 @@ limitations under the License. --> states.linkDashboard = opt[0].value; updateSettings(); } - function changeLegend(type: string, opt: any, index: number) { - (legend.value[index] as any)[type] = opt[0].value || opt; - } function changeScope(index: number, opt: Option[] | any) { items[index].scope = opt[0].value; const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]"); @@ -445,27 +290,15 @@ limitations under the License. --> updateSettings(); } function updateSettings(metricConfig?: { [key: string]: MetricConfigOpt[] }) { - let metrics = []; - if (isExpression.value) { - metrics = legend.value.filter((d: any) => d.name); - } else { - metrics = legend.value.filter((d: any) => d.name && d.value && d.condition); - } - const param = { ...dashboardStore.selectedGrid, linkDashboard: states.linkDashboard, nodeDashboard: isService ? items.filter((d: { scope: string; dashboard: string }) => d.dashboard) : states.nodeDashboard, - linkServerMetrics: states.linkServerMetrics, - linkClientMetrics: states.linkClientMetrics, - nodeMetrics: states.nodeMetrics, linkServerExpressions: states.linkServerExpressions, linkClientExpressions: states.linkClientExpressions, nodeExpressions: states.nodeExpressions, - metricMode: isExpression.value ? MetricModes.Expression : MetricModes.General, - legend: metrics, legendMQE: legendMQE.value, ...metricConfig, description, @@ -474,30 +307,8 @@ limitations under the License. --> dashboardStore.setConfigs(param); emit("update", param); } - function updateLinkServerMetrics(options: Option[] | any) { - const opt = options.map((d: Option) => d.value); - const index = states.linkServerMetrics.findIndex((d: any) => !opt.includes(d)); - states.linkServerMetrics = opt; - if (index < 0) { - changeLinkServerMetrics(); - return; - } - const origin = dashboardStore.selectedGrid.linkServerMetricConfig || []; - const config = origin.length === 1 ? [] : origin.splice(index, 1); - changeLinkServerMetrics({ linkServerMetricConfig: config }); - } - async function changeLinkServerMetrics(config?: { [key: string]: MetricConfigOpt[] }) { - updateSettings(config); - if (!states.linkServerMetrics.length) { - topologyStore.setLinkServerMetrics({}); - return; - } - topologyStore.getLinkServerMetrics(states.linkServerMetrics); - } + function changeLinkServerExpressions(param: string[]) { - if (!isExpression.value) { - return; - } states.linkServerExpressions = param; updateSettings(); if (!states.linkServerExpressions.length) { @@ -507,9 +318,6 @@ limitations under the License. --> topologyStore.getLinkExpressions(states.linkServerExpressions, CallTypes.Server); } function changeLinkClientExpressions(param: string[]) { - if (!isExpression.value) { - return; - } states.linkClientExpressions = param; updateSettings(); if (!states.linkClientExpressions.length) { @@ -518,63 +326,11 @@ limitations under the License. --> } topologyStore.getLinkExpressions(states.linkClientExpressions, CallTypes.Client); } - function updateLinkClientMetrics(options: Option[] | any) { - const opt = options.map((d: Option) => d.value); - const index = states.linkClientMetrics.findIndex((d: any) => !opt.includes(d)); - states.linkClientMetrics = opt; - if (index < 0) { - changeLinkClientMetrics(); - return; - } - const origin = dashboardStore.selectedGrid.linkClientMetricConfig || []; - const config = origin.length === 1 ? [] : origin.splice(index, 1); - changeLinkClientMetrics({ linkClientMetricConfig: config }); - } - async function changeLinkClientMetrics(config?: { [key: string]: MetricConfigOpt[] }) { - updateSettings(config); - if (!states.linkClientMetrics.length) { - topologyStore.setLinkClientMetrics({}); - return; - } - topologyStore.getLinkClientMetrics(states.linkClientMetrics); - } - function updateNodeMetrics(options: Option[] | any) { - const opt = options.map((d: Option) => d.value); - const index = states.nodeMetrics.findIndex((d: any) => !opt.includes(d)); - states.nodeMetrics = opt; - if (index < 0) { - changeNodeMetrics(); - return; - } - const origin = dashboardStore.selectedGrid.nodeMetricConfig || []; - const config = origin.length === 1 ? [] : origin.splice(index, 1); - changeNodeMetrics({ nodeMetricConfig: config }); - } - async function changeNodeMetrics(config?: { [key: string]: MetricConfigOpt[] }) { - updateSettings(config); - if (!states.nodeMetrics.length) { - topologyStore.setNodeMetricValue({}); - return; - } - topologyStore.queryNodeMetrics(states.nodeMetrics); - } - function deleteMetric(index: number) { - if (legend.value.length === 1) { - legend.value = [{ name: "", condition: "", value: "" }]; - return; - } - legend.value.splice(index, 1); - } - function addMetric() { - legend.value.push({ name: "", condition: "", value: "" }); - } + function setConfigType(type: string) { configType.value = type; } function changeNodeExpressions(param: string[]) { - if (!isExpression.value) { - return; - } states.nodeExpressions = param; updateSettings(); if (!states.nodeExpressions.length) { @@ -583,25 +339,6 @@ limitations under the License. --> } topologyStore.queryNodeExpressions(states.nodeExpressions); } - function changeMetricMode() { - legend.value = [{ name: "", condition: "", value: "" }]; - const config = { - linkServerMetricConfig: [], - linkClientMetricConfig: [], - nodeMetricConfig: [], - }; - if (isExpression.value) { - states.linkServerMetrics = []; - states.linkClientMetrics = []; - states.nodeMetrics = []; - } else { - states.linkServerExpressions = []; - states.linkClientExpressions = []; - states.nodeExpressions = []; - } - - updateSettings(config); - } </script> <style lang="scss" scoped> .inputs { diff --git a/src/views/dashboard/related/topology/pod/InstanceMap.vue b/src/views/dashboard/related/topology/pod/InstanceMap.vue index f0b12857..9e389d86 100644 --- a/src/views/dashboard/related/topology/pod/InstanceMap.vue +++ b/src/views/dashboard/related/topology/pod/InstanceMap.vue @@ -41,7 +41,6 @@ limitations under the License. --> import router from "@/router"; import { ElMessage } from "element-plus"; import type { MetricConfigOpt } from "@/types/dashboard"; - import { aggregation } from "@/hooks/useMetricsProcessor"; import getDashboard from "@/hooks/useDashboardsSession"; import Graph from "../components/Graph.vue"; @@ -129,8 +128,8 @@ limitations under the License. --> (val: { id: string; value: unknown }) => val.id === data.id, ) || {}; const opt: MetricConfigOpt = nodeMetricConfig[index] || {}; - const v = aggregation(metric.value, opt); - return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`; + + return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${opt.unit || ""}</div>`; }); const tipHtml = [ `<div class="mb-5"><span class="grey">name: </span>${data.name}</div><div class="mb-5"><span class="grey">layer: </span>${data.layer}</div>`, diff --git a/src/views/dashboard/related/topology/pod/PodMap.vue b/src/views/dashboard/related/topology/pod/PodMap.vue index 30e61037..92c4fa1f 100644 --- a/src/views/dashboard/related/topology/pod/PodMap.vue +++ b/src/views/dashboard/related/topology/pod/PodMap.vue @@ -69,7 +69,7 @@ limitations under the License. --> import { useDashboardStore } from "@/store/modules/dashboard"; import { useSelectorStore } from "@/store/modules/selectors"; import { useAppStoreWithOut } from "@/store/modules/app"; - import { EntityType, DepthList, MetricModes, CallTypes } from "@/views/dashboard/data"; + import { EntityType, DepthList, CallTypes } from "@/views/dashboard/data"; import { ElMessage } from "element-plus"; import Sankey from "./Sankey.vue"; import Settings from "../config/Settings.vue"; @@ -119,15 +119,9 @@ limitations under the License. --> }; height.value = dom.height - 70; width.value = dom.width - 5; - if (settings.value.metricMode === MetricModes.Expression) { - topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []); - topologyStore.getLinkExpressions(settings.value.linkClientExpressions || [], CallTypes.Client); - topologyStore.getLinkExpressions(settings.value.linkServerExpressions || [], CallTypes.Server); - } else { - topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []); - topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || []); - topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []); - } + topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []); + topologyStore.getLinkExpressions(settings.value.linkClientExpressions || [], CallTypes.Client); + topologyStore.getLinkExpressions(settings.value.linkServerExpressions || [], CallTypes.Server); } function resize() { diff --git a/src/views/dashboard/related/topology/pod/Sankey.vue b/src/views/dashboard/related/topology/pod/Sankey.vue index 231b366f..5b45e0b6 100644 --- a/src/views/dashboard/related/topology/pod/Sankey.vue +++ b/src/views/dashboard/related/topology/pod/Sankey.vue @@ -22,8 +22,6 @@ limitations under the License. --> import { useTopologyStore } from "@/store/modules/topology"; import type { Node, Call } from "@/types/topology"; import type { MetricConfigOpt } from "@/types/dashboard"; - import { aggregation } from "@/hooks/useMetricsProcessor"; - import { MetricModes } from "@/views/dashboard/data"; import { useAppStoreWithOut } from "@/store/modules/app"; import { Themes } from "@/constants/data"; @@ -85,14 +83,8 @@ limitations under the License. --> }; } function linkTooltip(data: Call) { - const clientMetrics: string[] = - props.settings.metricMode === MetricModes.Expression - ? props.settings.linkClientExpressions - : props.settings.linkClientMetrics; - const serverMetrics: string[] = - props.settings.metricMode === MetricModes.Expression - ? props.settings.linkServerExpressions - : props.settings.linkServerMetrics; + const clientMetrics: string[] = props.settings.linkClientExpressions; + const serverMetrics: string[] = props.settings.linkServerExpressions; const linkServerMetricConfig: MetricConfigOpt[] = props.settings.linkServerMetricConfig || []; const linkClientMetricConfig: MetricConfigOpt[] = props.settings.linkClientMetricConfig || []; @@ -102,8 +94,10 @@ limitations under the License. --> {}; if (metric) { const opt: MetricConfigOpt = linkServerMetricConfig[index] || {}; - const v = aggregation(metric.value, opt); - return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`; + + return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${ + opt.unit || "" + }</div>`; } }); const htmlClient = clientMetrics.map((m, index) => { @@ -111,8 +105,8 @@ limitations under the License. --> const metric = topologyStore.linkClientMetrics[m].values.find((val: { id: string; value: unknown }) => val.id === data.id) || {}; - const v = aggregation(metric.value, opt); - return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`; + + return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${opt.unit || ""}</div>`; }); const html = [ `<div>${data.sourceObj.serviceName} -> ${data.targetObj.serviceName}</div>`, @@ -124,17 +118,14 @@ limitations under the License. --> } function nodeTooltip(data: Node) { - const nodeMetrics: string[] = - props.settings.metricMode === MetricModes.Expression - ? props.settings.nodeExpressions - : props.settings.nodeMetrics; + const nodeMetrics: string[] = props.settings.nodeExpressions; const nodeMetricConfig = props.settings.nodeMetricConfig || []; const html = nodeMetrics.map((m, index) => { const metric = topologyStore.nodeMetricValue[m].values.find((val: { id: string; value: unknown }) => val.id === data.id) || {}; const opt: MetricConfigOpt = nodeMetricConfig[index] || {}; - const v = aggregation(metric.value, opt); - return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`; + + return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${opt.unit || ""}</div>`; }); return [` <div><span>name: </span>${data.serviceName}</div>`, ...html].join(" "); } diff --git a/src/views/dashboard/related/topology/service/HierarchyMap.vue b/src/views/dashboard/related/topology/service/HierarchyMap.vue index 4f0265a7..6eb8c33d 100644 --- a/src/views/dashboard/related/topology/service/HierarchyMap.vue +++ b/src/views/dashboard/related/topology/service/HierarchyMap.vue @@ -43,7 +43,6 @@ limitations under the License. --> import router from "@/router"; import { ElMessage } from "element-plus"; import type { MetricConfigOpt } from "@/types/dashboard"; - import { aggregation } from "@/hooks/useMetricsProcessor"; import getDashboard from "@/hooks/useDashboardsSession"; import Graph from "../components/Graph.vue"; @@ -137,8 +136,7 @@ limitations under the License. --> (val: { id: string; value: unknown }) => val.id === data.id, ) || {}; const opt: MetricConfigOpt = nodeMetricConfig[index] || {}; - const v = aggregation(metric.value, opt); - return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`; + return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${opt.unit || ""}</div>`; }); const tipHtml = [ `<div class="mb-5"><span class="grey">name: </span>${data.name}</div><div class="mb-5"><span class="grey">layer: </span>${data.layer}</div>`, diff --git a/src/views/dashboard/related/topology/service/ServiceMap.vue b/src/views/dashboard/related/topology/service/ServiceMap.vue index e6bb226e..10433cca 100644 --- a/src/views/dashboard/related/topology/service/ServiceMap.vue +++ b/src/views/dashboard/related/topology/service/ServiceMap.vue @@ -144,7 +144,7 @@ limitations under the License. --> import { useSelectorStore } from "@/store/modules/selectors"; import { useTopologyStore } from "@/store/modules/topology"; import { useDashboardStore } from "@/store/modules/dashboard"; - import { EntityType, DepthList, MetricModes, CallTypes } from "@/views/dashboard/data"; + import { EntityType, DepthList, CallTypes } from "@/views/dashboard/data"; import router from "@/router"; import { ElMessage } from "element-plus"; import Settings from "../config/Settings.vue"; @@ -154,9 +154,7 @@ limitations under the License. --> import { useAppStoreWithOut } from "@/store/modules/app"; import getDashboard from "@/hooks/useDashboardsSession"; import type { MetricConfigOpt } from "@/types/dashboard"; - import { aggregation } from "@/hooks/useMetricsProcessor"; import icons from "@/assets/img/icons"; - import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor"; import { layout, computeLevels, changeNode } from "../components/utils/layout"; import zoom from "@/views/dashboard/related/components/utils/zoom"; import { useQueryTopologyExpressionsProcessor } from "@/hooks/useExpressionsProcessor"; @@ -231,15 +229,9 @@ limitations under the License. --> } async function update() { - if (settings.value.metricMode === MetricModes.Expression) { - topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []); - topologyStore.getLinkExpressions(settings.value.linkClientExpressions || [], CallTypes.Client); - topologyStore.getLinkExpressions(settings.value.linkServerExpressions || [], CallTypes.Server); - } else { - topologyStore.queryNodeMetrics(settings.value.nodeMetrics || []); - topologyStore.getLinkClientMetrics(settings.value.linkClientMetrics || []); - topologyStore.getLinkServerMetrics(settings.value.linkServerMetrics || []); - } + topologyStore.queryNodeExpressions(settings.value.nodeExpressions || []); + topologyStore.getLinkExpressions(settings.value.linkClientExpressions || [], CallTypes.Client); + topologyStore.getLinkExpressions(settings.value.linkServerExpressions || [], CallTypes.Server); window.addEventListener("resize", resize); await initLegendMetrics(); @@ -288,67 +280,33 @@ limitations under the License. --> if (!topologyStore.nodes.length) { return; } - if (settings.value.metricMode === MetricModes.Expression) { - const expression = props.config.legendMQE && props.config.legendMQE.expression; - if (!expression) { - return; - } - const { getExpressionQuery } = useQueryTopologyExpressionsProcessor([expression], topologyStore.nodes); - const param = getExpressionQuery(); - const res = await topologyStore.getNodeExpressionValue(param); - if (res.errors) { - ElMessage.error(res.errors); - } else { - topologyStore.setLegendValues([expression], res.data); - } + + const expression = props.config.legendMQE && props.config.legendMQE.expression; + if (!expression) { + return; + } + const { getExpressionQuery } = useQueryTopologyExpressionsProcessor([expression], topologyStore.nodes); + const param = getExpressionQuery(); + const res = await topologyStore.getNodeExpressionValue(param); + if (res.errors) { + ElMessage.error(res.errors); } else { - const names = props.config.legend.map((d: any) => d.name); - if (!names.length) { - return; - } - const ids = topologyStore.nodes.map((d: Node) => d.id); - if (ids.length) { - const param = await useQueryTopologyMetrics(names, ids); - const res = await topologyStore.getLegendMetrics(param); - if (res.errors) { - ElMessage.error(res.errors); - } - } + topologyStore.setLegendValues([expression], res.data); } } function getNodeStatus(d: any) { - const { legend, legendMQE } = settings.value; - if (settings.value.metricMode === MetricModes.Expression) { - if (!legendMQE) { - return icons.CUBE; - } - if (!legendMQE.expression) { - return icons.CUBE; - } - return Number(d[legendMQE.expression]) && d.isReal ? icons.CUBEERROR : icons.CUBE; - } - if (!legend) { + const { legendMQE } = settings.value; + if (!legendMQE) { return icons.CUBE; } - if (!legend.length) { + if (!legendMQE.expression) { return icons.CUBE; } - let c = true; - for (const l of legend) { - if (l.condition === "<") { - c = c && d[l.name] < Number(l.value); - } else { - c = c && d[l.name] > Number(l.value); - } - } - return c && d.isReal ? icons.CUBEERROR : icons.CUBE; + return Number(d[legendMQE.expression]) && d.isReal ? icons.CUBEERROR : icons.CUBE; } function showNodeTip(event: MouseEvent, data: Node) { - const nodeMetrics: string[] = - (settings.value.metricMode === MetricModes.Expression - ? settings.value.nodeExpressions - : settings.value.nodeMetrics) || []; + const nodeMetrics: string[] = settings.value.nodeExpressions || []; const nodeMetricConfig = settings.value.nodeMetricConfig || []; const html = nodeMetrics.map((m, index) => { const metric = @@ -356,8 +314,9 @@ limitations under the License. --> topologyStore.nodeMetricValue[m].values.find((val: { id: string; value: unknown }) => val.id === data.id)) || {}; const opt: MetricConfigOpt = nodeMetricConfig[index] || {}; - const v = aggregation(metric.value, opt); - return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || "unknown"}</div>`; + return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${ + opt.unit || "unknown" + }</div>`; }); const tipHtml = [ `<div class="mb-5"><span class="grey">name: </span>${ @@ -373,24 +332,19 @@ limitations under the License. --> .html(tipHtml); } function showLinkTip(event: MouseEvent, data: Call) { - const linkClientMetrics: string[] = - settings.value.metricMode === MetricModes.Expression - ? settings.value.linkClientExpressions - : settings.value.linkClientMetrics || []; + const linkClientMetrics: string[] = settings.value.linkClientExpressions || []; const linkServerMetricConfig: MetricConfigOpt[] = settings.value.linkServerMetricConfig || []; const linkClientMetricConfig: MetricConfigOpt[] = settings.value.linkClientMetricConfig || []; - const linkServerMetrics: string[] = - settings.value.metricMode === MetricModes.Expression - ? settings.value.linkServerExpressions - : settings.value.linkServerMetrics || []; + const linkServerMetrics: string[] = settings.value.linkServerExpressions || []; const htmlServer = linkServerMetrics.map((m, index) => { const metric = topologyStore.linkServerMetrics[m].values.find( (val: { id: string; value: unknown }) => val.id === data.id, ); if (metric) { const opt: MetricConfigOpt = linkServerMetricConfig[index] || {}; - const v = aggregation(metric.value, opt); - return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`; + return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${ + opt.unit || "" + }</div>`; } }); const htmlClient = linkClientMetrics.map((m: string, index: number) => { @@ -399,8 +353,9 @@ limitations under the License. --> (val: { id: string; value: unknown }) => val.id === data.id, ); if (metric) { - const v = aggregation(metric.value, opt); - return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${v} ${opt.unit || ""}</div>`; + return ` <div class="mb-5"><span class="grey">${opt.label || m}: </span>${metric.value} ${ + opt.unit || "" + }</div>`; } }); const html = [