From e876010975edc382a45ed206d45ff9f3270821d9 Mon Sep 17 00:00:00 2001 From: Fine Date: Thu, 18 May 2023 17:37:30 +0800 Subject: [PATCH] feat: add Policy list --- src/graphql/fragments/profile.ts | 29 +++ src/graphql/query/profile.ts | 6 + src/store/modules/continous-profiling.ts | 171 +++++++++++++++++ src/types/continous-profiling.d.ts | 29 +++ .../components/EditStrategy.vue | 51 ++++++ .../components/StrategyList.vue | 172 ++++++++++++++++++ 6 files changed, 458 insertions(+) create mode 100644 src/store/modules/continous-profiling.ts create mode 100644 src/types/continous-profiling.d.ts create mode 100644 src/views/dashboard/related/continuous-profiling/components/EditStrategy.vue create mode 100644 src/views/dashboard/related/continuous-profiling/components/StrategyList.vue diff --git a/src/graphql/fragments/profile.ts b/src/graphql/fragments/profile.ts index 01744eea..90a70b22 100644 --- a/src/graphql/fragments/profile.ts +++ b/src/graphql/fragments/profile.ts @@ -123,3 +123,32 @@ export const GetProfileTaskLogs = { } `, }; +export const GetStrategyList = { + variable: "$serviceId: ID", + query: ` + strategyList: getStrategyList(serviceId: $serviceId) { + serviceId + targets { + targetType + checkItems { + type + threshold + period + count + uriList + uriRegex + } + } + } + `, +}; + +export const EditStrategy = { + variable: "$request: ContinuousProfilingPolicyCreation!", + query: ` + strategy: setContinuousProfilingPolicy(request: $request) { + errorReason + status + } + `, +}; diff --git a/src/graphql/query/profile.ts b/src/graphql/query/profile.ts index 6b762f02..2394dfa0 100644 --- a/src/graphql/query/profile.ts +++ b/src/graphql/query/profile.ts @@ -21,6 +21,8 @@ import { GetProfileTaskSegmentList, GetProfileAnalyze, GetProfileTaskLogs, + GetStrategyList, + EditStrategy, } from "../fragments/profile"; export const saveProfileTask = `mutation createProfileTask(${CreateProfileTask.variable}) {${CreateProfileTask.query}}`; @@ -34,3 +36,7 @@ export const getProfileTaskSegmentList = `query getProfileTaskSegmentList(${GetP export const getProfileAnalyze = `query getProfileAnalyze(${GetProfileAnalyze.variable}) {${GetProfileAnalyze.query}}`; export const getProfileTaskLogs = `query profileTaskLogs(${GetProfileTaskLogs.variable}) {${GetProfileTaskLogs.query}}`; + +export const getStrategyList = `query GetStrategyList(${GetStrategyList.variable}) {${GetStrategyList.query}}`; + +export const editStrategy = `query GetStrategyList(${EditStrategy.variable}) {${EditStrategy.query}}`; diff --git a/src/store/modules/continous-profiling.ts b/src/store/modules/continous-profiling.ts new file mode 100644 index 00000000..09ef105e --- /dev/null +++ b/src/store/modules/continous-profiling.ts @@ -0,0 +1,171 @@ +/** + * 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 { defineStore } from "pinia"; +import type { StrategyItem, CheckItems } from "@/types/continous-profiling"; +import type { ProcessNode } from "@/types/ebpf"; +import { store } from "@/store"; +import graphql from "@/graphql"; +import type { AxiosResponse } from "axios"; +import type { Call } from "@/types/topology"; +import type { LayoutConfig } from "@/types/dashboard"; +import type { DurationTime } from "@/types/app"; + +interface ContinousProfilingState { + strategyList: Array>; + selectedStrategyTask: Recordable; + errorReason: string; + nodes: ProcessNode[]; + calls: Call[]; + node: Nullable; + call: Nullable; + metricsLayout: LayoutConfig[]; + selectedMetric: Nullable; + activeMetricIndex: string; + aliveNetwork: boolean; + loadNodes: boolean; +} + +export const continousProfilingStore = defineStore({ + id: "continousProfiling", + state: (): ContinousProfilingState => ({ + strategyList: [], + selectedStrategyTask: {}, + errorReason: "", + nodes: [], + calls: [], + node: null, + call: null, + metricsLayout: [], + selectedMetric: null, + activeMetricIndex: "", + aliveNetwork: false, + loadNodes: false, + }), + actions: { + setSelectedStrategyTask(task: Recordable) { + this.selectedStrategyTask = task || {}; + }, + setNode(node: Nullable) { + this.node = node; + }, + setLink(link: Call) { + this.call = link; + }, + setMetricsLayout(layout: LayoutConfig[]) { + this.metricsLayout = layout; + }, + setSelectedMetric(item: LayoutConfig) { + this.selectedMetric = item; + }, + setActiveItem(index: string) { + this.activeMetricIndex = index; + }, + setTopology(data: { nodes: ProcessNode[]; calls: Call[] }) { + const obj = {} as Recordable; + let calls = (data.calls || []).reduce((prev: Call[], next: Call) => { + if (!obj[next.id]) { + obj[next.id] = true; + next.value = next.value || 1; + for (const node of data.nodes) { + if (next.source === node.id) { + next.sourceObj = node; + } + if (next.target === node.id) { + next.targetObj = node; + } + } + next.value = next.value || 1; + prev.push(next); + } + return prev; + }, []); + const param = {} as Recordable; + calls = data.calls.reduce((prev: (Call & Recordable)[], next: Call & Recordable) => { + if (param[next.targetId + next.sourceId]) { + next.lowerArc = true; + } + param[next.sourceId + next.targetId] = true; + next.sourceId = next.source; + next.targetId = next.target; + next.source = next.sourceObj; + next.target = next.targetObj; + delete next.sourceObj; + delete next.targetObj; + prev.push(next); + return prev; + }, []); + this.calls = calls; + this.nodes = data.nodes; + }, + async setContinuousProfilingPolicy( + serviceId: string, + targets: { + targetType: string; + checkItems: CheckItems[]; + }[], + ) { + const res: AxiosResponse = await graphql.query("editStrategy").params({ + request: { + serviceId, + targets, + }, + }); + + if (res.data.errors) { + return res.data; + } + + return res.data; + }, + async getStrategyList(params: { serviceId: string }) { + if (!params.serviceId) { + return new Promise((resolve) => resolve({})); + } + const res: AxiosResponse = await graphql.query("getStrategyList").params(params); + + if (res.data.errors) { + return res.data; + } + this.strategyList = res.data.data.queryEBPFTasks || []; + this.selectedStrategyTask = this.strategyList[0] || {}; + this.setSelectedStrategyTask(this.selectedStrategyTask); + if (!this.strategyList.length) { + this.nodes = []; + this.calls = []; + } + return res.data; + }, + async getProcessTopology(params: { duration: DurationTime; serviceInstanceId: string }) { + this.loadNodes = true; + const res: AxiosResponse = await graphql.query("getProcessTopology").params(params); + this.loadNodes = false; + if (res.data.errors) { + this.nodes = []; + this.calls = []; + return res.data; + } + const { topology } = res.data.data; + + this.setTopology(topology); + return res.data; + }, + }, +}); + +export function useContinousProfilingStore(): Recordable { + return continousProfilingStore(store); +} diff --git a/src/types/continous-profiling.d.ts b/src/types/continous-profiling.d.ts new file mode 100644 index 00000000..91017dbc --- /dev/null +++ b/src/types/continous-profiling.d.ts @@ -0,0 +1,29 @@ +/** + * 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. + */ + +export interface StrategyItem { + type: string; + checkItems: CheckItems[]; +} +export type CheckItems = { + type: string; + threshold: string; + period: number; + count: number; + uriList: string[]; + uriRegex: string; +}; diff --git a/src/views/dashboard/related/continuous-profiling/components/EditStrategy.vue b/src/views/dashboard/related/continuous-profiling/components/EditStrategy.vue new file mode 100644 index 00000000..4cedbb49 --- /dev/null +++ b/src/views/dashboard/related/continuous-profiling/components/EditStrategy.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/src/views/dashboard/related/continuous-profiling/components/StrategyList.vue b/src/views/dashboard/related/continuous-profiling/components/StrategyList.vue new file mode 100644 index 00000000..d29c7965 --- /dev/null +++ b/src/views/dashboard/related/continuous-profiling/components/StrategyList.vue @@ -0,0 +1,172 @@ + + + +