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, - 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" /> -
{{ t("metrics") }}
- - -
+
{{ t("summary") }} {{ t("detail") }}
- +
{{ metric }}
@@ -59,24 +51,6 @@ limitations under the License. --> {{ states.subMetrics[index] }}
- - - -