diff --git a/src/graphql/fragments/profile.ts b/src/graphql/fragments/profile.ts index cfe9a4f9..d1237d49 100644 --- a/src/graphql/fragments/profile.ts +++ b/src/graphql/fragments/profile.ts @@ -184,3 +184,14 @@ export const GetAsyncProfileTaskProcess = { } `, }; + +export const CreateAsyncProfileTask = { + variable: "$asyncProfilerTaskCreationRequest: AsyncProfilerTaskCreationRequest!", + query: ` + task: createAsyncProfilerTask(asyncProfilerTaskCreationRequest: $asyncProfilerTaskCreationRequest) { + id + errorReason + code + } + `, +}; diff --git a/src/graphql/query/profile.ts b/src/graphql/query/profile.ts index 273636a0..b9ea3476 100644 --- a/src/graphql/query/profile.ts +++ b/src/graphql/query/profile.ts @@ -25,6 +25,7 @@ import { EditStrategy, GetAsyncTaskList, GetAsyncProfileTaskProcess, + CreateAsyncProfileTask, } from "../fragments/profile"; export const saveProfileTask = `mutation createProfileTask(${CreateProfileTask.variable}) {${CreateProfileTask.query}}`; @@ -46,3 +47,5 @@ export const editStrategy = `mutation editStrategy(${EditStrategy.variable}) {${ export const getAsyncTaskList = `query getAsyncTaskList(${GetAsyncTaskList.variable}) {${GetAsyncTaskList.query}}`; export const getAsyncProfileTaskProcess = `query getAsyncProfileTaskProcess(${GetAsyncProfileTaskProcess.variable}) {${GetAsyncProfileTaskProcess.query}}`; + +export const saveAsyncProfileTask = `mutation createAsyncProfileTask(${CreateAsyncProfileTask.variable}) {${CreateAsyncProfileTask.query}}`; diff --git a/src/locales/lang/en.ts b/src/locales/lang/en.ts index 65722791..ed89f05b 100644 --- a/src/locales/lang/en.ts +++ b/src/locales/lang/en.ts @@ -390,5 +390,8 @@ const msg = { mappingTip: "Notice: The mapping key is a Regex string, e.g. ^([0-9])$", valueDashboard: "Data Value Related Dashboard", viewValueDashboard: "View Dashboard", + errorInstances: "Error Instances", + successInstances: "Success Instances", + profilingEvents: "Async Profiling Events", }; export default msg; diff --git a/src/locales/lang/es.ts b/src/locales/lang/es.ts index aff70878..8fd5f82a 100644 --- a/src/locales/lang/es.ts +++ b/src/locales/lang/es.ts @@ -390,5 +390,8 @@ const msg = { mappingTip: "Aviso: La clave de mapeo es una cadena Regex, p. ej. ^([0-9])$", valueDashboard: "Data Value Related Dashboard", viewValueDashboard: "View Dashboard", + errorInstances: "Error Instances", + successInstances: "Success Instances", + profilingEvents: "Async Profiling Events", }; export default msg; diff --git a/src/locales/lang/zh.ts b/src/locales/lang/zh.ts index dca5b0bb..961c3094 100644 --- a/src/locales/lang/zh.ts +++ b/src/locales/lang/zh.ts @@ -388,5 +388,8 @@ const msg = { mappingTip: "注意: 映射键是一个正则表达式字符串,比如 ^([0-9])$", valueDashboard: "数据值相关的仪表板", viewValueDashboard: "查看仪表板", + errorInstances: "错误的实例", + successInstances: "成功的实例", + profilingEvents: "异步分析事件", }; export default msg; diff --git a/src/store/modules/async-profiling.ts b/src/store/modules/async-profiling.ts index 6a71c0d2..7234aa78 100644 --- a/src/store/modules/async-profiling.ts +++ b/src/store/modules/async-profiling.ts @@ -16,7 +16,7 @@ */ import { defineStore } from "pinia"; import type { Option } from "@/types/app"; -import type { AsyncProfilingTaskList } from "@/types/async-profiling"; +import type { AsyncProfilingTaskList, AsyncProfileTaskCreationRequest } from "@/types/async-profiling"; import { store } from "@/store"; import graphql from "@/graphql"; import { useAppStoreWithOut } from "@/store/modules/app"; @@ -46,11 +46,11 @@ export const asyncProfilingStore = defineStore({ setSelectedTask(task: Recordable) { this.selectedTask = task || {}; }, - async getTaskList(params: { serviceId: string; targets: string[] }) { + async getTaskList(params: { serviceId: string; startTime: number; endTime: number }) { if (!params.serviceId) { return new Promise((resolve) => resolve({})); } - const res: AxiosResponse = await graphql.query("getAsyncTaskList").params(params); + const res: AxiosResponse = await graphql.query("getAsyncTaskList").params({ ...params, limit: 10000 }); this.asyncProfilingTips = ""; if (res.data.errors) { @@ -87,6 +87,17 @@ export const asyncProfilingStore = defineStore({ } return res.data; }, + async createTask(param: AsyncProfileTaskCreationRequest) { + const res: AxiosResponse = await graphql + .query("saveAsyncProfileTask") + .params({ asyncProfilerTaskCreationRequest: param }); + + if (res.data.errors) { + return res.data; + } + this.getTaskList(); + return res.data; + }, }, }); diff --git a/src/types/async-profiling.ts b/src/types/async-profiling.ts index 86e6b302..79623c3d 100644 --- a/src/types/async-profiling.ts +++ b/src/types/async-profiling.ts @@ -24,3 +24,11 @@ export type AsyncProfilingTaskList = { duration: number; execArgs: string; }; + +export type AsyncProfileTaskCreationRequest = { + serviceId: string; + serviceInstanceIds: string[]; + duration: number; + events: string[]; + execArgs: string; +}; diff --git a/src/types/components.d.ts b/src/types/components.d.ts index 78897e22..247c6b27 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -12,6 +12,8 @@ declare module 'vue' { ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem'] ElButton: typeof import('element-plus/es')['ElButton'] ElCard: typeof import('element-plus/es')['ElCard'] + ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] + ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] ElCollapse: typeof import('element-plus/es')['ElCollapse'] ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem'] ElDialog: typeof import('element-plus/es')['ElDialog'] diff --git a/src/views/dashboard/controls/AsyncProfiling.vue b/src/views/dashboard/controls/AsyncProfiling.vue index 99bec1ca..2618f160 100644 --- a/src/views/dashboard/controls/AsyncProfiling.vue +++ b/src/views/dashboard/controls/AsyncProfiling.vue @@ -25,6 +25,7 @@ limitations under the License. --> {{ t("delete") }} +
@@ -33,6 +34,7 @@ limitations under the License. --> import { useI18n } from "vue-i18n"; import { useDashboardStore } from "@/store/modules/dashboard"; import Content from "../related/async-profiling/Content.vue"; + import Header from "../related/async-profiling/Header.vue"; /*global defineProps*/ const props = defineProps({ diff --git a/src/views/dashboard/related/async-profiling/Content.vue b/src/views/dashboard/related/async-profiling/Content.vue index db79628e..9b7ddfd8 100644 --- a/src/views/dashboard/related/async-profiling/Content.vue +++ b/src/views/dashboard/related/async-profiling/Content.vue @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. --> @@ -25,6 +25,7 @@ limitations under the License. --> import { ElMessage } from "element-plus"; import { useAsyncProfilingStore } from "@/store/modules/async-profiling"; + import TaskList from "./components/TaskList.vue"; const asyncProfilingStore = useAsyncProfilingStore(); diff --git a/src/views/dashboard/related/async-profiling/Header.vue b/src/views/dashboard/related/async-profiling/Header.vue new file mode 100644 index 00000000..9b6c92f0 --- /dev/null +++ b/src/views/dashboard/related/async-profiling/Header.vue @@ -0,0 +1,102 @@ + + + + diff --git a/src/views/dashboard/related/async-profiling/components/NewTask.vue b/src/views/dashboard/related/async-profiling/components/NewTask.vue new file mode 100644 index 00000000..daeb4b51 --- /dev/null +++ b/src/views/dashboard/related/async-profiling/components/NewTask.vue @@ -0,0 +1,125 @@ + + + + + diff --git a/src/views/dashboard/related/async-profiling/components/TaskList.vue b/src/views/dashboard/related/async-profiling/components/TaskList.vue index 4c39d7be..9912bbb4 100644 --- a/src/views/dashboard/related/async-profiling/components/TaskList.vue +++ b/src/views/dashboard/related/async-profiling/components/TaskList.vue @@ -103,7 +103,7 @@ limitations under the License. -->
-
{{ t("errorInstanceIds") }}.
+
{{ t("errorInstances") }}.
{{ t("instance") }}: @@ -115,6 +115,19 @@ limitations under the License. -->
+
+
{{ t("successInstances") }}.
+
+
+ {{ t("instance") }}: + {{ instance.label }} +
+
+ {{ d.name }}: + {{ d.value }} +
+
+
@@ -138,6 +151,17 @@ limitations under the License. --> const errorInstances = ref([]); const successInstances = ref([]); + fetchTasks(); + + async function fetchTasks() { + const res = await asyncProfilingStore.getTaskList({ + serviceId: selectorStore.currentService.id, + }); + if (res.errors) { + ElMessage.error(res.errors); + } + } + async function changeTask(item: TaskListItem) { asyncProfilingStore.setCurrentSegment({}); asyncProfilingStore.setCurrentTask(item); diff --git a/src/views/dashboard/related/async-profiling/components/data.ts b/src/views/dashboard/related/async-profiling/components/data.ts new file mode 100644 index 00000000..d2b7f19d --- /dev/null +++ b/src/views/dashboard/related/async-profiling/components/data.ts @@ -0,0 +1,27 @@ +/** + * 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 const DurationOptions = [ + { value: "5", label: "5 min" }, + { value: "10", label: "10 min" }, + { value: "15", label: "15 min" }, +]; + +export const ProfilingEvents = [ + { value: "CPU", label: "CPU" }, + { value: "ALLOC", label: "ALLOC" }, +];