mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-14 09:00:50 +00:00
split ebpf store
This commit is contained in:
parent
b9b41f8627
commit
ab1ae85694
@ -21,16 +21,12 @@ import {
|
|||||||
EBPFProfilingSchedule,
|
EBPFProfilingSchedule,
|
||||||
EBPFTaskList,
|
EBPFTaskList,
|
||||||
AnalyzationTrees,
|
AnalyzationTrees,
|
||||||
ProcessNode,
|
|
||||||
} from "@/types/ebpf";
|
} from "@/types/ebpf";
|
||||||
import { store } from "@/store";
|
import { store } from "@/store";
|
||||||
import graphql from "@/graphql";
|
import graphql from "@/graphql";
|
||||||
import { AxiosResponse } from "axios";
|
import { AxiosResponse } from "axios";
|
||||||
import { Call } from "@/types/topology";
|
interface EbpfState {
|
||||||
import { LayoutConfig } from "@/types/dashboard";
|
|
||||||
interface EbpfStore {
|
|
||||||
taskList: EBPFTaskList[];
|
taskList: EBPFTaskList[];
|
||||||
networkTasks: EBPFTaskList[];
|
|
||||||
eBPFSchedules: EBPFProfilingSchedule[];
|
eBPFSchedules: EBPFProfilingSchedule[];
|
||||||
currentSchedule: EBPFProfilingSchedule | Record<string, never>;
|
currentSchedule: EBPFProfilingSchedule | Record<string, never>;
|
||||||
analyzeTrees: AnalyzationTrees[];
|
analyzeTrees: AnalyzationTrees[];
|
||||||
@ -39,22 +35,13 @@ interface EbpfStore {
|
|||||||
tip: string;
|
tip: string;
|
||||||
networkTip: string;
|
networkTip: string;
|
||||||
selectedTask: Recordable<EBPFTaskList>;
|
selectedTask: Recordable<EBPFTaskList>;
|
||||||
selectedNetworkTask: Recordable<EBPFTaskList>;
|
|
||||||
aggregateType: string;
|
aggregateType: string;
|
||||||
nodes: ProcessNode[];
|
|
||||||
calls: Call[];
|
|
||||||
node: Nullable<ProcessNode>;
|
|
||||||
call: Nullable<Call>;
|
|
||||||
metricsLayout: LayoutConfig[];
|
|
||||||
selectedMetric: Nullable<LayoutConfig>;
|
|
||||||
activeMetricIndex: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ebpfStore = defineStore({
|
export const ebpfStore = defineStore({
|
||||||
id: "eBPF",
|
id: "eBPF",
|
||||||
state: (): EbpfStore => ({
|
state: (): EbpfState => ({
|
||||||
taskList: [],
|
taskList: [],
|
||||||
networkTasks: [],
|
|
||||||
eBPFSchedules: [],
|
eBPFSchedules: [],
|
||||||
currentSchedule: {},
|
currentSchedule: {},
|
||||||
analyzeTrees: [],
|
analyzeTrees: [],
|
||||||
@ -63,15 +50,7 @@ export const ebpfStore = defineStore({
|
|||||||
tip: "",
|
tip: "",
|
||||||
networkTip: "",
|
networkTip: "",
|
||||||
selectedTask: {},
|
selectedTask: {},
|
||||||
selectedNetworkTask: {},
|
|
||||||
aggregateType: "COUNT",
|
aggregateType: "COUNT",
|
||||||
nodes: [],
|
|
||||||
calls: [],
|
|
||||||
node: null,
|
|
||||||
call: null,
|
|
||||||
metricsLayout: [],
|
|
||||||
selectedMetric: null,
|
|
||||||
activeMetricIndex: "",
|
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
setSelectedTask(task: EBPFTaskList) {
|
setSelectedTask(task: EBPFTaskList) {
|
||||||
@ -86,44 +65,6 @@ export const ebpfStore = defineStore({
|
|||||||
setAnalyzeTrees(tree: AnalyzationTrees[]) {
|
setAnalyzeTrees(tree: AnalyzationTrees[]) {
|
||||||
this.analyzeTrees = tree;
|
this.analyzeTrees = tree;
|
||||||
},
|
},
|
||||||
setNode(node: Node) {
|
|
||||||
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 any;
|
|
||||||
const 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;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
this.calls = calls;
|
|
||||||
this.nodes = data.nodes;
|
|
||||||
},
|
|
||||||
async getCreateTaskData(serviceId: string) {
|
async getCreateTaskData(serviceId: string) {
|
||||||
const res: AxiosResponse = await graphql
|
const res: AxiosResponse = await graphql
|
||||||
.query("getCreateTaskData")
|
.query("getCreateTaskData")
|
||||||
@ -153,23 +94,6 @@ export const ebpfStore = defineStore({
|
|||||||
});
|
});
|
||||||
return res.data;
|
return res.data;
|
||||||
},
|
},
|
||||||
async createNetworkTask(param: {
|
|
||||||
serviceId: string;
|
|
||||||
serviceInstanceId: string;
|
|
||||||
}) {
|
|
||||||
const res: AxiosResponse = await graphql
|
|
||||||
.query("newNetworkProfiling")
|
|
||||||
.params({ request: { instanceId: param.serviceInstanceId } });
|
|
||||||
|
|
||||||
if (res.data.errors) {
|
|
||||||
return res.data;
|
|
||||||
}
|
|
||||||
this.getTaskList({
|
|
||||||
...param,
|
|
||||||
targets: ["NETWORK"],
|
|
||||||
});
|
|
||||||
return res.data;
|
|
||||||
},
|
|
||||||
async getTaskList(params: {
|
async getTaskList(params: {
|
||||||
serviceId: string;
|
serviceId: string;
|
||||||
serviceInstanceId: string;
|
serviceInstanceId: string;
|
||||||
@ -182,27 +106,17 @@ export const ebpfStore = defineStore({
|
|||||||
.query("getEBPFTasks")
|
.query("getEBPFTasks")
|
||||||
.params(params);
|
.params(params);
|
||||||
|
|
||||||
if (params.serviceInstanceId) {
|
this.tip = "";
|
||||||
this.networkTip = "";
|
if (res.data.errors) {
|
||||||
if (res.data.errors) {
|
return res.data;
|
||||||
return res.data;
|
|
||||||
}
|
|
||||||
this.networkTasks = res.data.data.queryEBPFTasks || [];
|
|
||||||
this.selectedNetworkTask = this.networkTasks[0] || {};
|
|
||||||
this.setSelectedNetworkTask(this.selectedNetworkTask);
|
|
||||||
} else {
|
|
||||||
this.tip = "";
|
|
||||||
if (res.data.errors) {
|
|
||||||
return res.data;
|
|
||||||
}
|
|
||||||
this.taskList = res.data.data.queryEBPFTasks || [];
|
|
||||||
this.selectedTask = this.taskList[0] || {};
|
|
||||||
this.setSelectedTask(this.selectedTask);
|
|
||||||
if (!this.taskList.length) {
|
|
||||||
return res.data;
|
|
||||||
}
|
|
||||||
this.getEBPFSchedules({ taskId: this.taskList[0].taskId });
|
|
||||||
}
|
}
|
||||||
|
this.taskList = res.data.data.queryEBPFTasks || [];
|
||||||
|
this.selectedTask = this.taskList[0] || {};
|
||||||
|
this.setSelectedTask(this.selectedTask);
|
||||||
|
if (!this.taskList.length) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
this.getEBPFSchedules({ taskId: this.taskList[0].taskId });
|
||||||
return res.data;
|
return res.data;
|
||||||
},
|
},
|
||||||
async getEBPFSchedules(params: { taskId: string }) {
|
async getEBPFSchedules(params: { taskId: string }) {
|
||||||
@ -260,23 +174,6 @@ export const ebpfStore = defineStore({
|
|||||||
this.analyzeTrees = analysisEBPFResult.trees;
|
this.analyzeTrees = analysisEBPFResult.trees;
|
||||||
return res.data;
|
return res.data;
|
||||||
},
|
},
|
||||||
async getProcessTopology(params: {
|
|
||||||
duration: any;
|
|
||||||
serviceInstanceId: string;
|
|
||||||
}) {
|
|
||||||
const res: AxiosResponse = await graphql
|
|
||||||
.query("getProcessTopology")
|
|
||||||
.params(params);
|
|
||||||
if (res.data.errors) {
|
|
||||||
this.nodes = [];
|
|
||||||
this.calls = [];
|
|
||||||
return res.data;
|
|
||||||
}
|
|
||||||
const { topology } = res.data.data;
|
|
||||||
|
|
||||||
this.setTopology(topology);
|
|
||||||
return res.data;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
154
src/store/modules/network-profiling.ts
Normal file
154
src/store/modules/network-profiling.ts
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/**
|
||||||
|
* 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 { EBPFTaskList, ProcessNode } from "@/types/ebpf";
|
||||||
|
import { store } from "@/store";
|
||||||
|
import graphql from "@/graphql";
|
||||||
|
import { AxiosResponse } from "axios";
|
||||||
|
import { Call } from "@/types/topology";
|
||||||
|
import { LayoutConfig } from "@/types/dashboard";
|
||||||
|
|
||||||
|
interface NetworkProfilingState {
|
||||||
|
networkTasks: EBPFTaskList[];
|
||||||
|
networkTip: string;
|
||||||
|
selectedNetworkTask: Recordable<EBPFTaskList>;
|
||||||
|
nodes: ProcessNode[];
|
||||||
|
calls: Call[];
|
||||||
|
node: Nullable<ProcessNode>;
|
||||||
|
call: Nullable<Call>;
|
||||||
|
metricsLayout: LayoutConfig[];
|
||||||
|
selectedMetric: Nullable<LayoutConfig>;
|
||||||
|
activeMetricIndex: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const networkProfilingStore = defineStore({
|
||||||
|
id: "networkProfiling",
|
||||||
|
state: (): NetworkProfilingState => ({
|
||||||
|
networkTasks: [],
|
||||||
|
networkTip: "",
|
||||||
|
selectedNetworkTask: {},
|
||||||
|
nodes: [],
|
||||||
|
calls: [],
|
||||||
|
node: null,
|
||||||
|
call: null,
|
||||||
|
metricsLayout: [],
|
||||||
|
selectedMetric: null,
|
||||||
|
activeMetricIndex: "",
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
setSelectedNetworkTask(task: EBPFTaskList) {
|
||||||
|
this.selectedNetworkTask = task || {};
|
||||||
|
},
|
||||||
|
setNode(node: Node) {
|
||||||
|
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 any;
|
||||||
|
const 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;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
this.calls = calls;
|
||||||
|
this.nodes = data.nodes;
|
||||||
|
},
|
||||||
|
async createNetworkTask(param: {
|
||||||
|
serviceId: string;
|
||||||
|
serviceInstanceId: string;
|
||||||
|
}) {
|
||||||
|
const res: AxiosResponse = await graphql
|
||||||
|
.query("newNetworkProfiling")
|
||||||
|
.params({ request: { instanceId: param.serviceInstanceId } });
|
||||||
|
|
||||||
|
if (res.data.errors) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
this.getTaskList({
|
||||||
|
...param,
|
||||||
|
targets: ["NETWORK"],
|
||||||
|
});
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
async getTaskList(params: {
|
||||||
|
serviceId: string;
|
||||||
|
serviceInstanceId: string;
|
||||||
|
targets: string[];
|
||||||
|
}) {
|
||||||
|
if (!params.serviceId) {
|
||||||
|
return new Promise((resolve) => resolve({}));
|
||||||
|
}
|
||||||
|
const res: AxiosResponse = await graphql
|
||||||
|
.query("getEBPFTasks")
|
||||||
|
.params(params);
|
||||||
|
|
||||||
|
this.networkTip = "";
|
||||||
|
if (res.data.errors) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
this.networkTasks = res.data.data.queryEBPFTasks || [];
|
||||||
|
this.selectedNetworkTask = this.networkTasks[0] || {};
|
||||||
|
this.setSelectedNetworkTask(this.selectedNetworkTask);
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
async getProcessTopology(params: {
|
||||||
|
duration: any;
|
||||||
|
serviceInstanceId: string;
|
||||||
|
}) {
|
||||||
|
const res: AxiosResponse = await graphql
|
||||||
|
.query("getProcessTopology")
|
||||||
|
.params(params);
|
||||||
|
if (res.data.errors) {
|
||||||
|
this.nodes = [];
|
||||||
|
this.calls = [];
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
const { topology } = res.data.data;
|
||||||
|
|
||||||
|
this.setTopology(topology);
|
||||||
|
return res.data;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function useNetworkProfilingStore(): any {
|
||||||
|
return networkProfilingStore(store);
|
||||||
|
}
|
@ -20,7 +20,7 @@ import type { PropType } from "vue";
|
|||||||
import { ref, onMounted, watch } from "vue";
|
import { ref, onMounted, watch } from "vue";
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useEbpfStore } from "@/store/modules/ebpf";
|
import { useNetworkProfilingStore } from "@/store/modules/network-profiling";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
import d3tip from "d3-tip";
|
import d3tip from "d3-tip";
|
||||||
import {
|
import {
|
||||||
@ -47,7 +47,7 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
const ebpfStore = useEbpfStore();
|
const networkProfilingStore = useNetworkProfilingStore();
|
||||||
const height = ref<number>(100);
|
const height = ref<number>(100);
|
||||||
const width = ref<number>(100);
|
const width = ref<number>(100);
|
||||||
const simulation = ref<any>(null);
|
const simulation = ref<any>(null);
|
||||||
@ -71,7 +71,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
svg.value = d3.select(chart.value).append("svg").attr("class", "process-svg");
|
svg.value = d3.select(chart.value).append("svg").attr("class", "process-svg");
|
||||||
if (!ebpfStore.nodes.length) {
|
if (!networkProfilingStore.nodes.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
drawGraph();
|
drawGraph();
|
||||||
@ -94,8 +94,8 @@ function drawGraph() {
|
|||||||
graph.value.call(tip.value);
|
graph.value.call(tip.value);
|
||||||
simulation.value = simulationInit(
|
simulation.value = simulationInit(
|
||||||
d3,
|
d3,
|
||||||
ebpfStore.nodes,
|
networkProfilingStore.nodes,
|
||||||
ebpfStore.calls,
|
networkProfilingStore.calls,
|
||||||
ticked
|
ticked
|
||||||
);
|
);
|
||||||
node.value = graph.value.append("g").selectAll(".topo-node");
|
node.value = graph.value.append("g").selectAll(".topo-node");
|
||||||
@ -106,8 +106,8 @@ function drawGraph() {
|
|||||||
svg.value.on("click", (event: any) => {
|
svg.value.on("click", (event: any) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
ebpfStore.setNode(null);
|
networkProfilingStore.setNode(null);
|
||||||
ebpfStore.setLink(null);
|
networkProfilingStore.setLink(null);
|
||||||
dashboardStore.selectWidget(props.config);
|
dashboardStore.selectWidget(props.config);
|
||||||
});
|
});
|
||||||
useThrottleFn(resize, 500)();
|
useThrottleFn(resize, 500)();
|
||||||
@ -117,7 +117,10 @@ function update() {
|
|||||||
if (!node.value || !link.value) {
|
if (!node.value || !link.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
node.value = node.value.data(ebpfStore.nodes, (d: ProcessNode) => d.id);
|
node.value = node.value.data(
|
||||||
|
networkProfilingStore.nodes,
|
||||||
|
(d: ProcessNode) => d.id
|
||||||
|
);
|
||||||
node.value.exit().remove();
|
node.value.exit().remove();
|
||||||
node.value = nodeElement(
|
node.value = nodeElement(
|
||||||
d3,
|
d3,
|
||||||
@ -130,11 +133,14 @@ function update() {
|
|||||||
tip.value
|
tip.value
|
||||||
).merge(node.value);
|
).merge(node.value);
|
||||||
// line element
|
// line element
|
||||||
link.value = link.value.data(ebpfStore.calls, (d: Call) => d.id);
|
link.value = link.value.data(networkProfilingStore.calls, (d: Call) => d.id);
|
||||||
link.value.exit().remove();
|
link.value.exit().remove();
|
||||||
link.value = linkElement(link.value.enter()).merge(link.value);
|
link.value = linkElement(link.value.enter()).merge(link.value);
|
||||||
// anchorElement
|
// anchorElement
|
||||||
anchor.value = anchor.value.data(ebpfStore.calls, (d: Call) => d.id);
|
anchor.value = anchor.value.data(
|
||||||
|
networkProfilingStore.calls,
|
||||||
|
(d: Call) => d.id
|
||||||
|
);
|
||||||
anchor.value.exit().remove();
|
anchor.value.exit().remove();
|
||||||
anchor.value = anchorElement(
|
anchor.value = anchorElement(
|
||||||
anchor.value.enter(),
|
anchor.value.enter(),
|
||||||
@ -150,25 +156,28 @@ function update() {
|
|||||||
tip.value
|
tip.value
|
||||||
).merge(anchor.value);
|
).merge(anchor.value);
|
||||||
// arrow marker
|
// arrow marker
|
||||||
arrow.value = arrow.value.data(ebpfStore.calls, (d: Call) => d.id);
|
arrow.value = arrow.value.data(
|
||||||
|
networkProfilingStore.calls,
|
||||||
|
(d: Call) => d.id
|
||||||
|
);
|
||||||
arrow.value.exit().remove();
|
arrow.value.exit().remove();
|
||||||
arrow.value = arrowMarker(arrow.value.enter()).merge(arrow.value);
|
arrow.value = arrowMarker(arrow.value.enter()).merge(arrow.value);
|
||||||
// force element
|
// force element
|
||||||
simulation.value.nodes(ebpfStore.nodes);
|
simulation.value.nodes(networkProfilingStore.nodes);
|
||||||
simulation.value
|
simulation.value
|
||||||
.force("link")
|
.force("link")
|
||||||
.links(ebpfStore.calls)
|
.links(networkProfilingStore.calls)
|
||||||
.id((d: Call) => d.id);
|
.id((d: Call) => d.id);
|
||||||
simulationSkip(d3, simulation.value, ticked);
|
simulationSkip(d3, simulation.value, ticked);
|
||||||
const loopMap: any = {};
|
const loopMap: any = {};
|
||||||
for (let i = 0; i < ebpfStore.calls.length; i++) {
|
for (let i = 0; i < networkProfilingStore.calls.length; i++) {
|
||||||
const link: any = ebpfStore.calls[i];
|
const link: any = networkProfilingStore.calls[i];
|
||||||
link.loopFactor = 1;
|
link.loopFactor = 1;
|
||||||
for (let j = 0; j < ebpfStore.calls.length; j++) {
|
for (let j = 0; j < networkProfilingStore.calls.length; j++) {
|
||||||
if (i === j || loopMap[i]) {
|
if (i === j || loopMap[i]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const otherLink = ebpfStore.calls[j];
|
const otherLink = networkProfilingStore.calls[j];
|
||||||
if (
|
if (
|
||||||
link.source.id === otherLink.target.id &&
|
link.source.id === otherLink.target.id &&
|
||||||
link.target.id === otherLink.source.id
|
link.target.id === otherLink.source.id
|
||||||
@ -189,8 +198,8 @@ function handleLinkClick(event: any, d: Call) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
ebpfStore.setNode(null);
|
networkProfilingStore.setNode(null);
|
||||||
ebpfStore.setLink(d);
|
networkProfilingStore.setLink(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ticked() {
|
function ticked() {
|
||||||
@ -234,14 +243,14 @@ function resize() {
|
|||||||
|
|
||||||
async function freshNodes() {
|
async function freshNodes() {
|
||||||
svg.value.selectAll(".svg-graph").remove();
|
svg.value.selectAll(".svg-graph").remove();
|
||||||
if (!ebpfStore.nodes.length) {
|
if (!networkProfilingStore.nodes.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
drawGraph();
|
drawGraph();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
watch(
|
watch(
|
||||||
() => ebpfStore.nodes,
|
() => networkProfilingStore.nodes,
|
||||||
() => {
|
() => {
|
||||||
freshNodes();
|
freshNodes();
|
||||||
}
|
}
|
||||||
|
@ -21,14 +21,14 @@ limitations under the License. -->
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted, watch } from "vue";
|
import { ref, onMounted, watch } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useEbpfStore } from "@/store/modules/ebpf";
|
import { useNetworkProfilingStore } from "@/store/modules/network-profiling";
|
||||||
import { DataSet, Timeline } from "vis-timeline/standalone";
|
import { DataSet, Timeline } from "vis-timeline/standalone";
|
||||||
import "vis-timeline/styles/vis-timeline-graph2d.css";
|
import "vis-timeline/styles/vis-timeline-graph2d.css";
|
||||||
import { useThrottleFn } from "@vueuse/core";
|
import { useThrottleFn } from "@vueuse/core";
|
||||||
|
|
||||||
/*global Nullable */
|
/*global Nullable */
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const ebpfStore = useEbpfStore();
|
const networkProfilingStore = useNetworkProfilingStore();
|
||||||
const timeRange = ref<Nullable<HTMLDivElement>>(null);
|
const timeRange = ref<Nullable<HTMLDivElement>>(null);
|
||||||
const visGraph = ref<Nullable<any>>(null);
|
const visGraph = ref<Nullable<any>>(null);
|
||||||
const oldVal = ref<{ width: number; height: number }>({ width: 0, height: 0 });
|
const oldVal = ref<{ width: number; height: number }>({ width: 0, height: 0 });
|
||||||
@ -49,23 +49,25 @@ function visTimeline() {
|
|||||||
if (visGraph.value) {
|
if (visGraph.value) {
|
||||||
visGraph.value.destroy();
|
visGraph.value.destroy();
|
||||||
}
|
}
|
||||||
if (!ebpfStore.selectedNetworkTask.taskId) {
|
if (!networkProfilingStore.selectedNetworkTask.taskId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const h = timeRange.value.getBoundingClientRect().height;
|
const h = timeRange.value.getBoundingClientRect().height;
|
||||||
const task = [
|
const task = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
content: ebpfStore.selectedNetworkTask.name,
|
content: networkProfilingStore.selectedNetworkTask.name,
|
||||||
start: new Date(Number(ebpfStore.selectedNetworkTask.taskStartTime)),
|
start: new Date(
|
||||||
|
Number(networkProfilingStore.selectedNetworkTask.taskStartTime)
|
||||||
|
),
|
||||||
end: new Date(
|
end: new Date(
|
||||||
Number(
|
Number(
|
||||||
ebpfStore.selectedNetworkTask.taskStartTime +
|
networkProfilingStore.selectedNetworkTask.taskStartTime +
|
||||||
ebpfStore.selectedNetworkTask.fixedTriggerDuration
|
networkProfilingStore.selectedNetworkTask.fixedTriggerDuration
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
data: ebpfStore.selectedNetworkTask,
|
data: networkProfilingStore.selectedNetworkTask,
|
||||||
className: ebpfStore.selectedNetworkTask.type,
|
className: networkProfilingStore.selectedNetworkTask.type,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const items = new DataSet(task);
|
const items = new DataSet(task);
|
||||||
@ -96,7 +98,7 @@ function resize() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
watch(
|
watch(
|
||||||
() => ebpfStore.selectedNetworkTask,
|
() => networkProfilingStore.selectedNetworkTask,
|
||||||
() => {
|
() => {
|
||||||
visTimeline();
|
visTimeline();
|
||||||
}
|
}
|
||||||
|
@ -29,20 +29,24 @@ limitations under the License. -->
|
|||||||
</el-popconfirm>
|
</el-popconfirm>
|
||||||
</div>
|
</div>
|
||||||
<div class="profile-t-wrapper">
|
<div class="profile-t-wrapper">
|
||||||
<div class="no-data" v-show="!ebpfStore.networkTasks.length">
|
<div
|
||||||
|
class="no-data"
|
||||||
|
v-show="!networkProfilingStore.networkTasks.length"
|
||||||
|
>
|
||||||
{{ t("noData") }}
|
{{ t("noData") }}
|
||||||
</div>
|
</div>
|
||||||
<table class="profile-t">
|
<table class="profile-t">
|
||||||
<tr
|
<tr
|
||||||
class="profile-tr cp"
|
class="profile-tr cp"
|
||||||
v-for="(i, index) in ebpfStore.networkTasks"
|
v-for="(i, index) in networkProfilingStore.networkTasks"
|
||||||
@click="changeTask(i)"
|
@click="changeTask(i)"
|
||||||
:key="index"
|
:key="index"
|
||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
class="profile-td"
|
class="profile-td"
|
||||||
:class="{
|
:class="{
|
||||||
selected: ebpfStore.selectedNetworkTask.taskId === i.taskId,
|
selected:
|
||||||
|
networkProfilingStore.selectedNetworkTask.taskId === i.taskId,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="ell">
|
<div class="ell">
|
||||||
@ -73,14 +77,14 @@ limitations under the License. -->
|
|||||||
fullscreen
|
fullscreen
|
||||||
@closed="viewDetail = false"
|
@closed="viewDetail = false"
|
||||||
>
|
>
|
||||||
<TaskDetails :details="ebpfStore.selectedNetworkTask" />
|
<TaskDetails :details="networkProfilingStore.selectedNetworkTask" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useEbpfStore } from "@/store/modules/ebpf";
|
import { useNetworkProfilingStore } from "@/store/modules/network-profiling";
|
||||||
import { useSelectorStore } from "@/store/modules/selectors";
|
import { useSelectorStore } from "@/store/modules/selectors";
|
||||||
import { EBPFTaskList } from "@/types/ebpf";
|
import { EBPFTaskList } from "@/types/ebpf";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
@ -91,7 +95,7 @@ import { useAppStoreWithOut } from "@/store/modules/app";
|
|||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const selectorStore = useSelectorStore();
|
const selectorStore = useSelectorStore();
|
||||||
const ebpfStore = useEbpfStore();
|
const networkProfilingStore = useNetworkProfilingStore();
|
||||||
const appStore = useAppStoreWithOut();
|
const appStore = useAppStoreWithOut();
|
||||||
const dateFormat = (date: number, pattern = "YYYY-MM-DD HH:mm:ss") =>
|
const dateFormat = (date: number, pattern = "YYYY-MM-DD HH:mm:ss") =>
|
||||||
dayjs(date).format(pattern);
|
dayjs(date).format(pattern);
|
||||||
@ -100,19 +104,19 @@ const viewDetail = ref<boolean>(false);
|
|||||||
fetchTasks();
|
fetchTasks();
|
||||||
|
|
||||||
async function changeTask(item: EBPFTaskList) {
|
async function changeTask(item: EBPFTaskList) {
|
||||||
ebpfStore.setSelectedNetworkTask(item);
|
networkProfilingStore.setSelectedNetworkTask(item);
|
||||||
getTopology();
|
getTopology();
|
||||||
}
|
}
|
||||||
async function getTopology() {
|
async function getTopology() {
|
||||||
const serviceInstanceId =
|
const serviceInstanceId =
|
||||||
(selectorStore.currentPod && selectorStore.currentPod.id) || "";
|
(selectorStore.currentPod && selectorStore.currentPod.id) || "";
|
||||||
const resp = await ebpfStore.getProcessTopology({
|
const resp = await networkProfilingStore.getProcessTopology({
|
||||||
serviceInstanceId,
|
serviceInstanceId,
|
||||||
duration: {
|
duration: {
|
||||||
start: dateFormatStep(
|
start: dateFormatStep(
|
||||||
getLocalTime(
|
getLocalTime(
|
||||||
appStore.utc,
|
appStore.utc,
|
||||||
new Date(ebpfStore.selectedNetworkTask.taskStartTime)
|
new Date(networkProfilingStore.selectedNetworkTask.taskStartTime)
|
||||||
),
|
),
|
||||||
appStore.duration.step,
|
appStore.duration.step,
|
||||||
true
|
true
|
||||||
@ -121,8 +125,9 @@ async function getTopology() {
|
|||||||
getLocalTime(
|
getLocalTime(
|
||||||
appStore.utc,
|
appStore.utc,
|
||||||
new Date(
|
new Date(
|
||||||
ebpfStore.selectedNetworkTask.taskStartTime +
|
networkProfilingStore.selectedNetworkTask.taskStartTime +
|
||||||
ebpfStore.selectedNetworkTask.fixedTriggerDuration * 1000
|
networkProfilingStore.selectedNetworkTask.fixedTriggerDuration *
|
||||||
|
1000
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
appStore.duration.step,
|
appStore.duration.step,
|
||||||
@ -144,7 +149,7 @@ async function createTask() {
|
|||||||
if (!serviceInstanceId) {
|
if (!serviceInstanceId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ebpfStore.createNetworkTask({
|
networkProfilingStore.createNetworkTask({
|
||||||
serviceId,
|
serviceId,
|
||||||
serviceInstanceId,
|
serviceInstanceId,
|
||||||
});
|
});
|
||||||
@ -154,7 +159,7 @@ async function fetchTasks() {
|
|||||||
(selectorStore.currentService && selectorStore.currentService.id) || "";
|
(selectorStore.currentService && selectorStore.currentService.id) || "";
|
||||||
const serviceInstanceId =
|
const serviceInstanceId =
|
||||||
(selectorStore.currentPod && selectorStore.currentPod.id) || "";
|
(selectorStore.currentPod && selectorStore.currentPod.id) || "";
|
||||||
const res = await ebpfStore.getTaskList({
|
const res = await networkProfilingStore.getTaskList({
|
||||||
serviceId,
|
serviceId,
|
||||||
serviceInstanceId,
|
serviceInstanceId,
|
||||||
targets: ["NETWORK"],
|
targets: ["NETWORK"],
|
||||||
|
@ -30,9 +30,12 @@ limitations under the License. -->
|
|||||||
:i="item.i"
|
:i="item.i"
|
||||||
:key="item.i"
|
:key="item.i"
|
||||||
@click="clickGrid(item)"
|
@click="clickGrid(item)"
|
||||||
:class="{ active: ebpfStore.activeMetricIndex === item.i }"
|
:class="{ active: networkProfilingStore.activeMetricIndex === item.i }"
|
||||||
>
|
>
|
||||||
<metric-widget :data="item" :activeIndex="ebpfStore.activeMetricIndex" />
|
<metric-widget
|
||||||
|
:data="item"
|
||||||
|
:activeIndex="networkProfilingStore.activeMetricIndex"
|
||||||
|
/>
|
||||||
</grid-item>
|
</grid-item>
|
||||||
</grid-layout>
|
</grid-layout>
|
||||||
<div class="no-data-tips" v-else>{{ t("noWidget") }}</div>
|
<div class="no-data-tips" v-else>{{ t("noWidget") }}</div>
|
||||||
@ -43,7 +46,7 @@ import { onBeforeUnmount, defineProps, ref } from "vue";
|
|||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { LayoutConfig } from "@/types/dashboard";
|
import { LayoutConfig } from "@/types/dashboard";
|
||||||
import MetricWidget from "./MetricWidget.vue";
|
import MetricWidget from "./MetricWidget.vue";
|
||||||
import { useEbpfStore } from "@/store/modules/ebpf";
|
import { useNetworkProfilingStore } from "@/store/modules/network-profiling";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
widgets: {
|
widgets: {
|
||||||
@ -52,14 +55,14 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const ebpfStore = useEbpfStore();
|
const networkProfilingStore = useNetworkProfilingStore();
|
||||||
const layout = ref<LayoutConfig[]>(props.widgets);
|
const layout = ref<LayoutConfig[]>(props.widgets);
|
||||||
|
|
||||||
function clickGrid(item: LayoutConfig) {
|
function clickGrid(item: LayoutConfig) {
|
||||||
ebpfStore.setActiveItem(item.i);
|
networkProfilingStore.setActiveItem(item.i);
|
||||||
ebpfStore.setSelectedMetric(item);
|
networkProfilingStore.setSelectedMetric(item);
|
||||||
}
|
}
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
ebpfStore.setMetricsLayout([]);
|
networkProfilingStore.setMetricsLayout([]);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -72,7 +72,7 @@ limitations under the License. -->
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { toRefs, reactive, defineComponent, ref, watch, computed } from "vue";
|
import { toRefs, reactive, defineComponent, ref, computed } from "vue";
|
||||||
import type { PropType } from "vue";
|
import type { PropType } from "vue";
|
||||||
import { LayoutConfig } from "@/types/dashboard";
|
import { LayoutConfig } from "@/types/dashboard";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
|
Loading…
Reference in New Issue
Block a user