feat: update task timeline

This commit is contained in:
Fine 2023-06-09 13:14:28 +08:00
parent fcf4cc3b92
commit dfe9c54d8d
6 changed files with 29 additions and 163 deletions

View File

@ -129,7 +129,7 @@ export async function useExpressionsQueryProcessor(config: Indexable) {
} }
} }
if (type === ExpressionResultType.SINGLE_VALUE) { if (type === ExpressionResultType.SINGLE_VALUE) {
source[c.label || name] = results[0].values[0].value; source[c.label || name] = (results[0].values[0] || {}).value;
} }
if (([ExpressionResultType.RECORD_LIST, ExpressionResultType.SORTED_LIST] as string[]).includes(type)) { if (([ExpressionResultType.RECORD_LIST, ExpressionResultType.SORTED_LIST] as string[]).includes(type)) {
source[name] = results[0].values; source[name] = results[0].values;
@ -259,7 +259,7 @@ export async function useExpressionsQueryPodsMetrics(
if (subValues) { if (subValues) {
d[name]["values"] = subValues; d[name]["values"] = subValues;
} }
d[name]["avg"] = results[i].values[0].value; d[name]["avg"] = (results[i].values[0] || {}).value;
const j = names.find((d: string) => d === name); const j = names.find((d: string) => d === name);
@ -278,7 +278,7 @@ export async function useExpressionsQueryPodsMetrics(
if (!d[name]) { if (!d[name]) {
d[name] = {}; d[name] = {};
} }
d[name]["avg"] = [results[0].values[0].value]; d[name]["avg"] = [(results[0].values[0] || {}).value];
if (subResults[0]) { if (subResults[0]) {
if (!d[subName]) { if (!d[subName]) {
d[subName] = {}; d[subName] = {};

View File

@ -22,7 +22,7 @@ import type { AxiosResponse } from "axios";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import type { EBPFTaskList } from "@/types/ebpf"; import type { EBPFTaskList } from "@/types/ebpf";
import { useNetworkProfilingStore } from "@/store/modules/network-profiling"; import { useNetworkProfilingStore } from "@/store/modules/network-profiling";
import { useContinousProfilingStore } from "@/store/modules/continous-profiling"; import { useSelectorStore } from "@/store/modules/selectors";
import { useEbpfStore } from "@/store/modules/ebpf"; import { useEbpfStore } from "@/store/modules/ebpf";
import dateFormatStep from "@/utils/dateFormat"; import dateFormatStep from "@/utils/dateFormat";
import getLocalTime from "@/utils/localtime"; import getLocalTime from "@/utils/localtime";
@ -72,15 +72,13 @@ export const taskTimelineStore = defineStore({
return; return;
} }
// this.selectedTask = this.taskList[0] || {}; // this.selectedTask = this.taskList[0] || {};
// this.setselectedTask(this.selectedTask);
// await this.getGraphData(); // await this.getGraphData();
return res.data; return res.data;
}, },
async getGraphData() { async getGraphData() {
let res: any = {}; let res: any = {};
const continousProfilingStore = useContinousProfilingStore();
if (continousProfilingStore.selectedStrategy.type === TargetTypes[2].value) { if (this.selectedTask.targetType === TargetTypes[2].value) {
res = await this.getTopology(); res = await this.getTopology();
} else { } else {
const ebpfStore = useEbpfStore(); const ebpfStore = useEbpfStore();
@ -96,6 +94,7 @@ export const taskTimelineStore = defineStore({
async getTopology() { async getTopology() {
const networkProfilingStore = useNetworkProfilingStore(); const networkProfilingStore = useNetworkProfilingStore();
const appStore = useAppStoreWithOut(); const appStore = useAppStoreWithOut();
const selectorStore = useSelectorStore();
networkProfilingStore.setSelectedNetworkTask(this.selectedTask); networkProfilingStore.setSelectedNetworkTask(this.selectedTask);
const { taskStartTime, fixedTriggerDuration } = this.selectedTask; const { taskStartTime, fixedTriggerDuration } = this.selectedTask;
const startTime = const startTime =
@ -105,7 +104,7 @@ export const taskTimelineStore = defineStore({
endTime = new Date().getTime(); endTime = new Date().getTime();
} }
const resp = await networkProfilingStore.getProcessTopology({ const resp = await networkProfilingStore.getProcessTopology({
serviceInstanceId: this.instance.id || "", serviceInstanceId: (selectorStore.currentPod || {}).id || "",
duration: { duration: {
start: dateFormatStep(getLocalTime(appStore.utc, new Date(startTime)), appStore.duration.step, true), start: dateFormatStep(getLocalTime(appStore.utc, new Date(startTime)), appStore.duration.step, true),
end: dateFormatStep(getLocalTime(appStore.utc, new Date(endTime)), appStore.duration.step, true), end: dateFormatStep(getLocalTime(appStore.utc, new Date(endTime)), appStore.duration.step, true),

View File

@ -1,141 +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. -->
<template>
<div class="profile-task-list flex-v">
<div class="profile-task-wrapper flex-v">
<div class="profile-t-tool flex-h">{{ t("taskList") }}</div>
<div class="profile-t-wrapper">
<div class="no-data" v-show="!continousProfilingStore.taskList.length">
{{ t("noData") }}
</div>
<table class="profile-t">
<tr
class="profile-tr cp"
v-for="(i, index) in continousProfilingStore.taskList"
@click="changeTask(i)"
:key="index"
>
<td
class="profile-td"
:class="{
selected: continousProfilingStore.selectedTask.taskId === i.taskId,
}"
>
<div class="ell" v-for="(cause, j) in i.continuousProfilingCauses" :key="j">
<span>
{{ `${cause.type}: ${getURI(cause.uri)}${cause.uri.threshold}>=${cause.uri.current}` }}
</span>
</div>
<div class="ell sm">
<span class="mr-10 sm">{{ dateFormat(i.taskStartTime) }}</span>
<span class="mr-10 sm">
{{ dateFormat(i.taskStartTime + i.fixedTriggerDuration * 1000) }}
</span>
<span class="profile-view r" @click="viewDetail = true">
<Icon iconName="view" size="middle" />
</span>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<el-dialog v-model="viewDetail" :destroy-on-close="true" fullscreen @closed="viewDetail = false">
<TaskDetails :details="continousProfilingStore.selectedTask" />
</el-dialog>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { useI18n } from "vue-i18n";
import type { EBPFTaskList } from "@/types/ebpf";
import TaskDetails from "../../components/TaskDetails.vue";
import { dateFormat } from "@/utils/dateFormat";
import { useContinousProfilingStore } from "@/store/modules/continous-profiling";
const { t } = useI18n();
const continousProfilingStore = useContinousProfilingStore();
const viewDetail = ref<boolean>(false);
async function changeTask(item: EBPFTaskList) {
continousProfilingStore.setselectedTask(item);
continousProfilingStore.getGraphData();
}
function getURI(uri: { uriRegex: string; uriPath: string }) {
return uri ? `(${uri.uriRegex || ""} | ${uri.uriPath || ""})` : "";
}
</script>
<style lang="scss" scoped>
.profile-task-list {
width: 300px;
height: 48%;
overflow: auto;
border-right: 1px solid rgba(0, 0, 0, 0.1);
}
.item span {
height: 21px;
}
.profile-td {
padding: 5px 10px;
border-bottom: 1px solid rgba(0, 0, 0, 0.07);
&.selected {
background-color: #ededed;
}
}
.no-data {
text-align: center;
margin-top: 10px;
}
.profile-t-wrapper {
overflow: auto;
flex-grow: 1;
}
.profile-t {
width: 100%;
border-spacing: 0;
table-layout: fixed;
flex-grow: 1;
position: relative;
border: none;
}
.profile-tr {
&:hover {
background-color: rgba(0, 0, 0, 0.04);
}
}
.profile-t-tool {
padding: 10px;
font-weight: bold;
border-right: 1px solid rgba(0, 0, 0, 0.07);
border-bottom: 1px solid rgba(0, 0, 0, 0.07);
background: #f3f4f9;
}
.profile-view {
color: #3d444f;
padding: 1px 3px;
border-radius: 2px;
font-size: 10px;
}
</style>

View File

@ -15,7 +15,7 @@ limitations under the License. -->
<template> <template>
<div class="flex-v content"> <div class="flex-v content">
<Timeline /> <Timeline />
<profiling-panel :config="config" /> <ProfilingPanel :config="config" />
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>

View File

@ -13,13 +13,16 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. --> limitations under the License. -->
<template> <template>
<div class="content" v-if="continousProfilingStore.selectedStrategy.type === TargetTypes[2].value"> <div class="content" v-if="taskTimelineStore.selectedTask.targetType === TargetTypes[2].value">
<process-topology v-if="networkProfilingStore.nodes.length" :config="config" /> <process-topology v-if="networkProfilingStore.nodes.length" :config="config" />
<div class="text" v-else> <div class="text" v-else>
{{ t("noData") }} {{ t("noData") }}
</div> </div>
</div> </div>
<div class="content" v-else> <div
class="content"
v-if="[TargetTypes[1].value, TargetTypes[0].value].includes(taskTimelineStore.selectedTask.targetType)"
>
<div class="schedules"> <div class="schedules">
<EBPFSchedules /> <EBPFSchedules />
</div> </div>
@ -31,7 +34,7 @@ limitations under the License. -->
<script lang="ts" setup> <script lang="ts" setup>
import type { PropType } from "vue"; import type { PropType } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useContinousProfilingStore } from "@/store/modules/continous-profiling"; import { useTaskTimelineStore } from "@/store/modules/task-timeline";
import { useNetworkProfilingStore } from "@/store/modules/network-profiling"; import { useNetworkProfilingStore } from "@/store/modules/network-profiling";
import { TargetTypes } from "../../continuous-profiling/data"; import { TargetTypes } from "../../continuous-profiling/data";
import ProcessTopology from "@/views/dashboard/related/network-profiling/components/ProcessTopology.vue"; import ProcessTopology from "@/views/dashboard/related/network-profiling/components/ProcessTopology.vue";
@ -46,7 +49,7 @@ limitations under the License. -->
}, },
}); });
const { t } = useI18n(); const { t } = useI18n();
const continousProfilingStore = useContinousProfilingStore(); const taskTimelineStore = useTaskTimelineStore();
const networkProfilingStore = useNetworkProfilingStore(); const networkProfilingStore = useNetworkProfilingStore();
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -61,12 +61,14 @@ limitations under the License. -->
const res = await taskTimelineStore.getContinousTaskList({ const res = await taskTimelineStore.getContinousTaskList({
serviceId, serviceId,
serviceInstanceId, serviceInstanceId,
targets: [type], targets: type ? [type] : null,
triggerType: EBPFProfilingTriggerType.CONTINUOUS_PROFILING, triggerType: EBPFProfilingTriggerType.CONTINUOUS_PROFILING,
}); });
if (res.errors) { if (res.errors) {
ElMessage.error(res.errors); ElMessage.error(res.errors);
return;
} }
visTimeline();
} }
function visTimeline() { function visTimeline() {
@ -80,7 +82,7 @@ limitations under the License. -->
const taskList = taskTimelineStore.taskList.map((d: EBPFTaskList, index: number) => { const taskList = taskTimelineStore.taskList.map((d: EBPFTaskList, index: number) => {
return { return {
id: index + 1, id: index + 1,
content: d.triggerType, // content: d.triggerType,
start: new Date(Number(d.taskStartTime)), start: new Date(Number(d.taskStartTime)),
end: new Date(Number(d.taskStartTime + d.fixedTriggerDuration * 1000)), end: new Date(Number(d.taskStartTime + d.fixedTriggerDuration * 1000)),
data: d, data: d,
@ -98,6 +100,8 @@ limitations under the License. -->
overflowMethod: "cap", overflowMethod: "cap",
template(item: EBPFTaskList | any) { template(item: EBPFTaskList | any) {
const data = item.data || {}; const data = item.data || {};
const end = data.taskStartTime ? visDate(data.taskStartTime + data.fixedTriggerDuration * 1000) : "";
let tmp = ` let tmp = `
<div>Task ID: ${data.taskId || ""}</div> <div>Task ID: ${data.taskId || ""}</div>
<div>Service Name: ${data.serviceName || ""}</div> <div>Service Name: ${data.serviceName || ""}</div>
@ -105,11 +109,11 @@ limitations under the License. -->
<div>Service Process Name: ${data.processName || ""}</div> <div>Service Process Name: ${data.processName || ""}</div>
<div>Trigger Type: ${data.triggerType || ""}</div> <div>Trigger Type: ${data.triggerType || ""}</div>
<div>Target Type: ${data.targetType || ""}</div> <div>Target Type: ${data.targetType || ""}</div>
<div>Start Time: ${data.startTime ? visDate(data.startTime) : ""}</div> <div>Start Time: ${data.taskStartTime ? visDate(data.taskStartTime) : ""}</div>
<div>End Time: ${data.endTime ? visDate(data.endTime) : ""}</div> <div>End Time: ${end}</div>
<div>Process Labels: ${data.processLabels.join("; ") || ""}</div>`; <div>Process Labels: ${data.processLabels.join("; ") || ""}</div>`;
let str = ""; let str = "";
for (const item of data.continuousProfilingCauses) { for (const item of data.continuousProfilingCauses || []) {
str += `<div>${item.type}: ${getURI(item.uri)}${item.uri.threshold}>=${item.uri.current}</div>`; str += `<div>${item.type}: ${getURI(item.uri)}${item.uri.threshold}>=${item.uri.current}</div>`;
} }
return tmp + str; return tmp + str;
@ -120,7 +124,8 @@ limitations under the License. -->
visGraph.value.on("select", async (properties: { items: number[] }) => { visGraph.value.on("select", async (properties: { items: number[] }) => {
dashboardStore.selectWidget(props.data); dashboardStore.selectWidget(props.data);
const index = properties.items[0]; const index = properties.items[0];
const task = taskList[index]; const task = taskTimelineStore.taskList[index];
await taskTimelineStore.setSelectedTask(task); await taskTimelineStore.setSelectedTask(task);
await taskTimelineStore.getGraphData(); await taskTimelineStore.getGraphData();
}); });
@ -145,9 +150,9 @@ limitations under the License. -->
} }
} }
watch( watch(
() => taskTimelineStore.taskList, () => selectorStore.currentPod,
() => { () => {
visTimeline(); init();
}, },
); );
</script> </script>
@ -155,7 +160,7 @@ limitations under the License. -->
.task-timeline { .task-timeline {
width: calc(100% - 5px); width: calc(100% - 5px);
margin: 0 5px 5px 0; margin: 0 5px 5px 0;
height: 300px; height: 200px;
} }
.message { .message {