From 7d1bb43adb0e3db02327c8cd55e6812955754592 Mon Sep 17 00:00:00 2001 From: Fine0830 Date: Wed, 4 May 2022 14:28:27 +0800 Subject: [PATCH 01/37] fix: view spans details and task logs (#76) --- src/store/modules/profile.ts | 8 ++++++- .../components/LogTable/LogService.vue | 4 ++-- .../related/profile/components/TaskList.vue | 4 +++- .../trace/components/D3Graph/SpanDetail.vue | 2 +- .../trace/components/Table/TableItem.vue | 22 ++++++++++++++----- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/store/modules/profile.ts b/src/store/modules/profile.ts index 9209e395..6dc8301a 100644 --- a/src/store/modules/profile.ts +++ b/src/store/modules/profile.ts @@ -161,7 +161,13 @@ export const profileStore = defineStore({ this.analyzeTrees = []; return res.data; } - this.segmentSpans = segment.spans; + this.segmentSpans = segment.spans.map((d: SegmentSpan) => { + return { + ...d, + segmentId: this.currentSegment.segmentId, + traceId: this.currentSegment.traceIds[0], + }; + }); if (!(segment.spans && segment.spans.length)) { this.analyzeTrees = []; return res.data; diff --git a/src/views/dashboard/related/components/LogTable/LogService.vue b/src/views/dashboard/related/components/LogTable/LogService.vue index c91b1efe..4b40ff80 100644 --- a/src/views/dashboard/related/components/LogTable/LogService.vue +++ b/src/views/dashboard/related/components/LogTable/LogService.vue @@ -22,12 +22,12 @@ limitations under the License. --> {{ tags }} - {{ data[item.label] }} - + --> {{ data[item.label] }} diff --git a/src/views/dashboard/related/profile/components/TaskList.vue b/src/views/dashboard/related/profile/components/TaskList.vue index efcbb03f..ce18c162 100644 --- a/src/views/dashboard/related/profile/components/TaskList.vue +++ b/src/views/dashboard/related/profile/components/TaskList.vue @@ -124,12 +124,14 @@ limitations under the License. --> import { ref } from "vue"; import dayjs from "dayjs"; import { useI18n } from "vue-i18n"; +import { useSelectorStore } from "@/store/modules/selectors"; import { useProfileStore } from "@/store/modules/profile"; import { TaskLog, TaskListItem } from "@/types/profile"; import { ElMessage } from "element-plus"; const { t } = useI18n(); const profileStore = useProfileStore(); +const selectorStore = useSelectorStore(); const dateFormat = (date: number, pattern = "YYYY-MM-DD HH:mm:ss") => dayjs(date).format(pattern); const viewDetail = ref(false); @@ -150,7 +152,7 @@ async function viewTask(e: Event, item: TaskListItem) { viewDetail.value = true; selectedTask.value = item; service.value = ( - profileStore.services.filter((s: any) => s.id === item.serviceId)[0] || {} + selectorStore.services.filter((s: any) => s.id === item.serviceId)[0] || {} ).label; const res = await profileStore.getTaskLogs({ taskID: item.id }); diff --git a/src/views/dashboard/related/trace/components/D3Graph/SpanDetail.vue b/src/views/dashboard/related/trace/components/D3Graph/SpanDetail.vue index e6390ff7..a34db4e9 100644 --- a/src/views/dashboard/related/trace/components/D3Graph/SpanDetail.vue +++ b/src/views/dashboard/related/trace/components/D3Graph/SpanDetail.vue @@ -40,7 +40,7 @@ limitations under the License. --> {{ currentSpan.peer || "No Peer" }}
- {{ t("error") }}: + {{ t("isError") }}: {{ currentSpan.isError }}
diff --git a/src/views/dashboard/related/trace/components/Table/TableItem.vue b/src/views/dashboard/related/trace/components/Table/TableItem.vue index 7f032fda..4becc9a1 100644 --- a/src/views/dashboard/related/trace/components/Table/TableItem.vue +++ b/src/views/dashboard/related/trace/components/Table/TableItem.vue @@ -105,8 +105,12 @@ limitations under the License. --> {{ data.serviceCode }}
-
- {{ t("view") }} +
+ {{ t("view") }}
+ d.className.includes("trace-item") + ); + emit("select", props.data); + viewSpanDetail(dom); + } - function selectedItem(data: any) { + function selectedItem(data: HTMLSpanElement) { emit("select", data); } - function viewSpanDetail(dom: any) { + function viewSpanDetail(dom: HTMLSpanElement) { showSelectSpan(dom); showDetail.value = true; } @@ -226,6 +237,7 @@ export default defineComponent({ showDetail, selectSpan, selectedItem, + viewSpan, t, }; }, From 2a2500a28d28e52e989891b5b03c4f4466eeaa64 Mon Sep 17 00:00:00 2001 From: Fine0830 Date: Thu, 5 May 2022 19:12:32 +0800 Subject: [PATCH 02/37] fix: verify query params to avoid invalid queries (#77) --- src/store/modules/ebpf.ts | 12 ++++++++++++ src/store/modules/profile.ts | 12 ++++++++++++ .../related/profile/components/TaskList.vue | 1 + 3 files changed, 25 insertions(+) diff --git a/src/store/modules/ebpf.ts b/src/store/modules/ebpf.ts index b03bed73..d59f317b 100644 --- a/src/store/modules/ebpf.ts +++ b/src/store/modules/ebpf.ts @@ -85,6 +85,9 @@ export const ebpfStore = defineStore({ return res.data; }, async getTaskList(serviceId: string) { + if (!serviceId) { + return new Promise((resolve) => resolve({})); + } const res: AxiosResponse = await graphql .query("getEBPFTasks") .params({ serviceId }); @@ -101,6 +104,9 @@ export const ebpfStore = defineStore({ return res.data; }, async getEBPFSchedules(params: { taskId: string; duration?: Duration }) { + if (!params.taskId) { + return new Promise((resolve) => resolve({})); + } const duration = useAppStoreWithOut().durationTime; const res: AxiosResponse = await graphql .query("getEBPFSchedules") @@ -124,6 +130,12 @@ export const ebpfStore = defineStore({ scheduleIdList: string[]; timeRanges: Array<{ start: number; end: number }>; }) { + if (!params.scheduleIdList.length) { + return new Promise((resolve) => resolve({})); + } + if (!params.timeRanges.length) { + return new Promise((resolve) => resolve({})); + } const res: AxiosResponse = await graphql .query("getEBPFResult") .params(params); diff --git a/src/store/modules/profile.ts b/src/store/modules/profile.ts index 6dc8301a..670ccdb3 100644 --- a/src/store/modules/profile.ts +++ b/src/store/modules/profile.ts @@ -122,6 +122,9 @@ export const profileStore = defineStore({ return res.data; }, async getSegmentList(params: { taskID: string }) { + if (!params.taskID) { + return new Promise((resolve) => resolve({})); + } const res: AxiosResponse = await graphql .query("getProfileTaskSegmentList") .params(params); @@ -148,6 +151,9 @@ export const profileStore = defineStore({ return res.data; }, async getSegmentSpans(params: { segmentId: string }) { + if (!params.segmentId) { + return new Promise((resolve) => resolve({})); + } const res: AxiosResponse = await graphql .query("queryProfileSegment") .params(params); @@ -180,6 +186,12 @@ export const profileStore = defineStore({ segmentId: string; timeRanges: Array<{ start: number; end: number }>; }) { + if (!params.segmentId) { + return new Promise((resolve) => resolve({})); + } + if (!params.timeRanges.length) { + return new Promise((resolve) => resolve({})); + } const res: AxiosResponse = await graphql .query("getProfileAnalyze") .params(params); diff --git a/src/views/dashboard/related/profile/components/TaskList.vue b/src/views/dashboard/related/profile/components/TaskList.vue index ce18c162..1b4bd5bc 100644 --- a/src/views/dashboard/related/profile/components/TaskList.vue +++ b/src/views/dashboard/related/profile/components/TaskList.vue @@ -140,6 +140,7 @@ const selectedTask = ref>({}); const instanceLogs = ref({}); async function changeTask(item: TaskListItem) { + profileStore.setCurrentSegment({}); selectedTask.value = item; const res = await profileStore.getSegmentList({ taskID: item.id }); if (res.errors) { From d93a7cead2a9e3a5e98172c960d6818fa2207afa Mon Sep 17 00:00:00 2001 From: Fine0830 Date: Mon, 9 May 2022 14:54:08 +0800 Subject: [PATCH 03/37] feat: mobile terminal adaptation (#78) --- src/App.vue | 2 + src/layout/components/SideBar.vue | 9 +- src/store/modules/app.ts | 5 + src/styles/grid.scss | 418 +----------------- src/styles/lib.scss | 18 + src/styles/reset.scss | 1 + src/views/dashboard/controls/Log.vue | 3 +- src/views/dashboard/controls/Tab.vue | 11 +- src/views/dashboard/controls/Trace.vue | 3 + src/views/dashboard/panel/Tool.vue | 2 +- .../related/components/LogTable/Index.vue | 2 +- .../related/ebpf/components/EBPFSchedules.vue | 2 + .../dashboard/related/profile/Content.vue | 1 + .../related/profile/components/SpanTree.vue | 2 + src/views/dashboard/related/trace/Filter.vue | 9 - 15 files changed, 56 insertions(+), 432 deletions(-) diff --git a/src/App.vue b/src/App.vue index 3f4af22a..edb2bce3 100644 --- a/src/App.vue +++ b/src/App.vue @@ -19,5 +19,7 @@ limitations under the License. --> #app { color: #2c3e50; height: 100%; + overflow: auto; + min-width: 1024px; } diff --git a/src/layout/components/SideBar.vue b/src/layout/components/SideBar.vue index 6bb75048..138082fc 100644 --- a/src/layout/components/SideBar.vue +++ b/src/layout/components/SideBar.vue @@ -109,14 +109,21 @@ import { ref } from "vue"; import { useRouter, RouteRecordRaw } from "vue-router"; import { useI18n } from "vue-i18n"; import Icon from "@/components/Icon.vue"; +import { useAppStoreWithOut } from "@/store/modules/app"; +const appStore = useAppStoreWithOut(); const { t } = useI18n(); const name = ref(String(useRouter().currentRoute.value.name)); const theme = ["VirtualMachine", "Kubernetes"].includes(name.value || "") ? ref("light") : ref("black"); const routes = ref(useRouter().options.routes); -const isCollapse = ref(false); +if (/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) { + appStore.setIsMobile(true); +} else { + appStore.setIsMobile(false); +} +const isCollapse = ref(appStore.isMobile ? true : false); const controlMenu = () => { isCollapse.value = !isCollapse.value; }; diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts index 8e3de407..e3121c0a 100644 --- a/src/store/modules/app.ts +++ b/src/store/modules/app.ts @@ -33,6 +33,7 @@ interface AppState { autoRefresh: boolean; pageTitle: string; version: string; + isMobile: boolean; } export const appStore = defineStore({ @@ -51,6 +52,7 @@ export const appStore = defineStore({ autoRefresh: false, pageTitle: "", version: "", + isMobile: false, }), getters: { duration(): Duration { @@ -121,6 +123,9 @@ export const appStore = defineStore({ this.utcHour = utcHour; this.utc = `${utcHour}:${utcMin}`; }, + setIsMobile(mode: boolean) { + this.isMobile = mode; + }, setEventStack(funcs: (() => void)[]): void { this.eventStack = funcs; }, diff --git a/src/styles/grid.scss b/src/styles/grid.scss index 29b4dac9..be0d07e3 100644 --- a/src/styles/grid.scss +++ b/src/styles/grid.scss @@ -15,10 +15,7 @@ * limitations under the License. */ -.show-xs, -.show-sm, -.show-md, -.show-lg { +.show-xs { display: none !important; } @media (max-width: 767px) { @@ -30,145 +27,6 @@ display: none !important; } } -@media (min-width: 768px) and (max-width: 1023px) { - .show-sm { - display: block !important; - } - - .hide-sm { - display: none !important; - } -} -@media (min-width: 1024px) and (max-width: 1279px) { - .show-md { - display: block !important; - } - - .hide-md { - display: none !important; - } -} -@media (min-width: 1280px) { - .show-lg { - display: block !important; - } - - .hide-lg { - display: none !important; - } -} - -.g-xs-1, -.g-xs-2, -.g-xs-3, -.g-xs-4, -.g-xs-5, -.g-xs-6, -.g-xs-7, -.g-xs-8, -.g-xs-9, -.g-xs-10, -.g-xs-11, -.g-xs-12 { - float: left; - min-height: 1px; -} - -.g-xs-12 { - width: 100%; -} - -.g-xs-11 { - width: 91.666%; -} - -.g-xs-10 { - width: 83.333%; -} - -.g-xs-9 { - width: 75%; -} - -.g-xs-8 { - width: 66.666%; -} - -.g-xs-7 { - width: 58.333%; -} - -.g-xs-6 { - width: 50%; -} - -.g-xs-5 { - width: 41.666%; -} - -.g-xs-4 { - width: 33.333%; -} - -.g-xs-3 { - width: 25%; -} - -.g-xs-2 { - width: 16.666%; -} - -.g-xs-1 { - width: 8.333%; -} - -.g-xs-space-12 { - margin-left: 100%; -} - -.g-xs-space-11 { - margin-left: 91.666%; -} - -.g-xs-space-10 { - margin-left: 83.333%; -} - -.g-xs-space-9 { - margin-left: 75%; -} - -.g-xs-space-8 { - margin-left: 66.666%; -} - -.g-xs-space-7 { - margin-left: 58.333%; -} - -.g-xs-space-6 { - margin-left: 50%; -} - -.g-xs-space-5 { - margin-left: 41.666%; -} - -.g-xs-space-4 { - margin-left: 33.333%; -} - -.g-xs-space-3 { - margin-left: 25%; -} - -.g-xs-space-2 { - margin-left: 16.666%; -} - -.g-xs-space-1 { - margin-left: 8.333%; -} @media (min-width: 768px) { .g-sm-1, .g-sm-2, @@ -233,278 +91,4 @@ .g-sm-1 { width: 8.333%; } - - .g-sm-space-12 { - margin-left: 100%; - } - - .g-sm-space-11 { - margin-left: 91.666%; - } - - .g-sm-space-10 { - margin-left: 83.333%; - } - - .g-sm-space-9 { - margin-left: 75%; - } - - .g-sm-space-8 { - margin-left: 66.666%; - } - - .g-sm-space-7 { - margin-left: 58.333%; - } - - .g-sm-space-6 { - margin-left: 50%; - } - - .g-sm-space-5 { - margin-left: 41.666%; - } - - .g-sm-space-4 { - margin-left: 33.333%; - } - - .g-sm-space-3 { - margin-left: 25%; - } - - .g-sm-space-2 { - margin-left: 16.666%; - } - - .g-sm-space-1 { - margin-left: 8.333%; - } -} -@media (min-width: 1024px) { - .g-md-1, - .g-md-2, - .g-md-3, - .g-md-4, - .g-md-5, - .g-md-6, - .g-md-7, - .g-md-8, - .g-md-9, - .g-md-10, - .g-md-11, - .g-md-12 { - float: left; - min-height: 1px; - } - - .g-md-12 { - width: 100%; - } - - .g-md-11 { - width: 91.666%; - } - - .g-md-10 { - width: 83.333%; - } - - .g-md-9 { - width: 75%; - } - - .g-md-8 { - width: 66.666%; - } - - .g-md-7 { - width: 58.333%; - } - - .g-md-6 { - width: 50%; - } - - .g-md-5 { - width: 41.666%; - } - - .g-md-4 { - width: 33.333%; - } - - .g-md-3 { - width: 25%; - } - - .g-md-2 { - width: 16.666%; - } - - .g-md-1 { - width: 8.333%; - } - - .g-md-space-12 { - margin-left: 100%; - } - - .g-md-space-11 { - margin-left: 91.666%; - } - - .g-md-space-10 { - margin-left: 83.333%; - } - - .g-md-space-9 { - margin-left: 75%; - } - - .g-md-space-8 { - margin-left: 66.666%; - } - - .g-md-space-7 { - margin-left: 58.333%; - } - - .g-md-space-6 { - margin-left: 50%; - } - - .g-md-space-5 { - margin-left: 41.666%; - } - - .g-md-space-4 { - margin-left: 33.333%; - } - - .g-md-space-3 { - margin-left: 25%; - } - - .g-md-space-2 { - margin-left: 16.666%; - } - - .g-md-space-1 { - margin-left: 8.333%; - } -} -@media (min-width: 1280px) { - .g-lg-1, - .g-lg-2, - .g-lg-3, - .g-lg-4, - .g-lg-5, - .g-lg-6, - .g-lg-7, - .g-lg-8, - .g-lg-9, - .g-lg-10, - .g-lg-11, - .g-lg-12 { - float: left; - min-height: 1px; - } - - .g-lg-12 { - width: 100%; - } - - .g-lg-11 { - width: 91.666%; - } - - .g-lg-10 { - width: 83.333%; - } - - .g-lg-9 { - width: 75%; - } - - .g-lg-8 { - width: 66.666%; - } - - .g-lg-7 { - width: 58.333%; - } - - .g-lg-6 { - width: 50%; - } - - .g-lg-5 { - width: 41.666%; - } - - .g-lg-4 { - width: 33.333%; - } - - .g-lg-3 { - width: 25%; - } - - .g-lg-2 { - width: 16.666%; - } - - .g-lg-1 { - width: 8.333%; - } - - .g-lg-space-12 { - margin-left: 100%; - } - - .g-lg-space-11 { - margin-left: 91.666%; - } - - .g-lg-space-10 { - margin-left: 83.333%; - } - - .g-lg-space-9 { - margin-left: 75%; - } - - .g-lg-space-8 { - margin-left: 66.666%; - } - - .g-lg-space-7 { - margin-left: 58.333%; - } - - .g-lg-space-6 { - margin-left: 50%; - } - - .g-lg-space-5 { - margin-left: 41.666%; - } - - .g-lg-space-4 { - margin-left: 33.333%; - } - - .g-lg-space-3 { - margin-left: 25%; - } - - .g-lg-space-2 { - margin-left: 16.666%; - } - - .g-lg-space-1 { - margin-left: 8.333%; - } } diff --git a/src/styles/lib.scss b/src/styles/lib.scss index 34083a5b..1d2a5084 100644 --- a/src/styles/lib.scss +++ b/src/styles/lib.scss @@ -171,3 +171,21 @@ color: #ddd; } } + +.scroll_bar_style::-webkit-scrollbar { + width: 9px; + height: 4px; + background-color: #eee; +} + +.scroll_bar_style::-webkit-scrollbar-track { + background-color: #eee; + border-radius: 3px; + box-shadow: inset 0 0 6px #ccc; +} + +.scroll_bar_style::-webkit-scrollbar-thumb { + border-radius: 3px; + box-shadow: inset 0 0 6px #ccc; + background-color: #aaa; +} diff --git a/src/styles/reset.scss b/src/styles/reset.scss index 0446f4fb..9a95d713 100644 --- a/src/styles/reset.scss +++ b/src/styles/reset.scss @@ -29,6 +29,7 @@ body { html, body { height: 100%; + overflow-y: hidden; } div, diff --git a/src/views/dashboard/controls/Log.vue b/src/views/dashboard/controls/Log.vue index ead077b8..ea80a786 100644 --- a/src/views/dashboard/controls/Log.vue +++ b/src/views/dashboard/controls/Log.vue @@ -64,6 +64,7 @@ function removeWidget() { height: 100%; font-size: 12px; position: relative; + overflow: auto; } .delete { @@ -76,6 +77,7 @@ function removeWidget() { padding: 10px; font-size: 12px; border-bottom: 1px solid #dcdfe6; + min-width: 1024px; } .tools { @@ -93,6 +95,5 @@ function removeWidget() { .log { width: 100%; - overflow: auto; } diff --git a/src/views/dashboard/controls/Tab.vue b/src/views/dashboard/controls/Tab.vue index 3ce22394..e500337a 100644 --- a/src/views/dashboard/controls/Tab.vue +++ b/src/views/dashboard/controls/Tab.vue @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. --> diff --git a/src/views/dashboard/related/ebpf/components/EBPFSchedules.vue b/src/views/dashboard/related/ebpf/components/EBPFSchedules.vue index a584e40f..2e144ad4 100644 --- a/src/views/dashboard/related/ebpf/components/EBPFSchedules.vue +++ b/src/views/dashboard/related/ebpf/components/EBPFSchedules.vue @@ -34,7 +34,7 @@ limitations under the License. --> placeholder="Please input name" class="input-with-search" size="small" - @change="searchProcesses" + @change="searchProcesses(0)" >