mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-06-29 18:07:35 +00:00
fix: update process widget and query process metrics (#145)
This commit is contained in:
parent
e17562a766
commit
87a5553e6d
@ -46,6 +46,7 @@ export function useQueryProcessor(config: any) {
|
|||||||
"ServiceRelation",
|
"ServiceRelation",
|
||||||
"ServiceInstanceRelation",
|
"ServiceInstanceRelation",
|
||||||
"EndpointRelation",
|
"EndpointRelation",
|
||||||
|
"ProcessRelation",
|
||||||
].includes(dashboardStore.entity);
|
].includes(dashboardStore.entity);
|
||||||
if (isRelation && !selectorStore.currentDestService) {
|
if (isRelation && !selectorStore.currentDestService) {
|
||||||
return;
|
return;
|
||||||
@ -93,28 +94,40 @@ export function useQueryProcessor(config: any) {
|
|||||||
dashboardStore.entity === "All"
|
dashboardStore.entity === "All"
|
||||||
? undefined
|
? undefined
|
||||||
: selectorStore.currentService.normal,
|
: selectorStore.currentService.normal,
|
||||||
serviceInstanceName: dashboardStore.entity.includes("ServiceInstance")
|
serviceInstanceName: [
|
||||||
|
"ServiceInstance",
|
||||||
|
"ServiceInstanceRelation",
|
||||||
|
"ProcessRelation",
|
||||||
|
].includes(dashboardStore.entity)
|
||||||
? selectorStore.currentPod && selectorStore.currentPod.value
|
? selectorStore.currentPod && selectorStore.currentPod.value
|
||||||
: undefined,
|
: undefined,
|
||||||
endpointName: dashboardStore.entity.includes("Endpoint")
|
endpointName: dashboardStore.entity.includes("Endpoint")
|
||||||
? selectorStore.currentPod && selectorStore.currentPod.value
|
? selectorStore.currentPod && selectorStore.currentPod.value
|
||||||
: undefined,
|
: undefined,
|
||||||
|
processName: dashboardStore.entity.includes("Process")
|
||||||
|
? selectorStore.currentProcess && selectorStore.currentProcess.value
|
||||||
|
: undefined,
|
||||||
destNormal: isRelation
|
destNormal: isRelation
|
||||||
? selectorStore.currentDestService.normal
|
? selectorStore.currentDestService.normal
|
||||||
: undefined,
|
: undefined,
|
||||||
destServiceName: isRelation
|
destServiceName: isRelation
|
||||||
? selectorStore.currentDestService.value
|
? selectorStore.currentDestService.value
|
||||||
: undefined,
|
: undefined,
|
||||||
destServiceInstanceName:
|
destServiceInstanceName: [
|
||||||
dashboardStore.entity === "ServiceInstanceRelation"
|
"ServiceInstanceRelation",
|
||||||
? selectorStore.currentDestPod &&
|
"ProcessRelation",
|
||||||
selectorStore.currentDestPod.value
|
].includes(dashboardStore.entity)
|
||||||
|
? selectorStore.currentDestPod && selectorStore.currentDestPod.value
|
||||||
: undefined,
|
: undefined,
|
||||||
destEndpointName:
|
destEndpointName:
|
||||||
dashboardStore.entity === "EndpointRelation"
|
dashboardStore.entity === "EndpointRelation"
|
||||||
? selectorStore.currentDestPod &&
|
? selectorStore.currentDestPod &&
|
||||||
selectorStore.currentDestPod.value
|
selectorStore.currentDestPod.value
|
||||||
: undefined,
|
: undefined,
|
||||||
|
destProcessName: dashboardStore.entity.includes("ProcessRelation")
|
||||||
|
? selectorStore.currentDestProcess &&
|
||||||
|
selectorStore.currentDestProcess.value
|
||||||
|
: undefined,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,7 @@ import type { PropType } from "vue";
|
|||||||
import { ServiceListConfig } from "@/types/dashboard";
|
import { ServiceListConfig } from "@/types/dashboard";
|
||||||
import { useSelectorStore } from "@/store/modules/selectors";
|
import { useSelectorStore } from "@/store/modules/selectors";
|
||||||
import { useDashboardStore } from "@/store/modules/dashboard";
|
import { useDashboardStore } from "@/store/modules/dashboard";
|
||||||
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
import { Service } from "@/types/selector";
|
import { Service } from "@/types/selector";
|
||||||
import { useQueryPodsMetrics, usePodsSource } from "@/hooks/useProcessor";
|
import { useQueryPodsMetrics, usePodsSource } from "@/hooks/useProcessor";
|
||||||
import { EntityType } from "../data";
|
import { EntityType } from "../data";
|
||||||
@ -111,6 +112,7 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
const selectorStore = useSelectorStore();
|
const selectorStore = useSelectorStore();
|
||||||
const dashboardStore = useDashboardStore();
|
const dashboardStore = useDashboardStore();
|
||||||
|
const appStore = useAppStoreWithOut();
|
||||||
const chartLoading = ref<boolean>(false);
|
const chartLoading = ref<boolean>(false);
|
||||||
const pageSize = 10;
|
const pageSize = 10;
|
||||||
const services = ref<Service[]>([]);
|
const services = ref<Service[]>([]);
|
||||||
@ -273,6 +275,14 @@ watch(
|
|||||||
queryServiceMetrics(services.value);
|
queryServiceMetrics(services.value);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
watch(
|
||||||
|
() => appStore.durationTime,
|
||||||
|
() => {
|
||||||
|
if (dashboardStore.entity === EntityType[1].value) {
|
||||||
|
queryServices();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "./style.scss";
|
@import "./style.scss";
|
||||||
|
@ -27,6 +27,9 @@ export const linkElement = (graph: any) => {
|
|||||||
[d.target.x, d.target.y - 5],
|
[d.target.x, d.target.y - 5],
|
||||||
0.5
|
0.5
|
||||||
);
|
);
|
||||||
|
if (d.lowerArc) {
|
||||||
|
controlPos[1] = -controlPos[1];
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
"M" +
|
"M" +
|
||||||
d.source.x +
|
d.source.x +
|
||||||
@ -57,6 +60,9 @@ export const anchorElement = (graph: any, funcs: any, tip: any) => {
|
|||||||
[d.target.x, d.target.y - 5],
|
[d.target.x, d.target.y - 5],
|
||||||
0.5
|
0.5
|
||||||
);
|
);
|
||||||
|
if (d.lowerArc) {
|
||||||
|
controlPos[1] = -controlPos[1];
|
||||||
|
}
|
||||||
const p = quadraticBezier(
|
const p = quadraticBezier(
|
||||||
0.5,
|
0.5,
|
||||||
{ x: d.source.x, y: d.source.y - 5 },
|
{ x: d.source.x, y: d.source.y - 5 },
|
||||||
|
@ -107,14 +107,7 @@ function drawGraph() {
|
|||||||
width.value = dom.width;
|
width.value = dom.width;
|
||||||
svg.value.attr("height", height.value).attr("width", width.value);
|
svg.value.attr("height", height.value).attr("width", width.value);
|
||||||
tip.value = (d3tip as any)().attr("class", "d3-tip").offset([-8, 0]);
|
tip.value = (d3tip as any)().attr("class", "d3-tip").offset([-8, 0]);
|
||||||
const outNodes = networkProfilingStore.nodes.filter(
|
|
||||||
(d: ProcessNode) => d.serviceInstanceId !== selectorStore.currentPod.id
|
|
||||||
);
|
|
||||||
if (outNodes.length) {
|
|
||||||
diff.value[0] = (dom.width - radius * 4) / 2 + radius;
|
|
||||||
} else {
|
|
||||||
diff.value[0] = (dom.width - radius * 2) / 2 + radius;
|
diff.value[0] = (dom.width - radius * 2) / 2 + radius;
|
||||||
}
|
|
||||||
graph.value = svg.value
|
graph.value = svg.value
|
||||||
.append("g")
|
.append("g")
|
||||||
.attr("class", "svg-graph")
|
.attr("class", "svg-graph")
|
||||||
@ -162,13 +155,17 @@ function createPolygon(radius: number, sides = 6, offset = 0) {
|
|||||||
}
|
}
|
||||||
return poly;
|
return poly;
|
||||||
}
|
}
|
||||||
|
function getCirclePoint(radius: number, p = 1) {
|
||||||
function getArcPoint(angle: number, radius: number) {
|
const data = [];
|
||||||
const origin = [0, 0];
|
const origin = [0, 0];
|
||||||
const x1 = radius + origin[0] * Math.cos((angle * Math.PI) / 180);
|
for (let index = 0; index < 360; index = index + p) {
|
||||||
const y1 = origin[1] + radius * Math.sin((angle * Math.PI) / 180);
|
if (index < 230 || index > 310) {
|
||||||
|
let x = radius * Math.cos((Math.PI * 2 * index) / 360);
|
||||||
return [x1, y1];
|
let y = radius * Math.sin((Math.PI * 2 * index) / 360);
|
||||||
|
data.push([x + origin[0], y + origin[1]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
function createLayout() {
|
function createLayout() {
|
||||||
if (!node.value || !link.value) {
|
if (!node.value || !link.value) {
|
||||||
@ -205,7 +202,7 @@ function createLayout() {
|
|||||||
.attr("fill", "#000")
|
.attr("fill", "#000")
|
||||||
.attr("text-anchor", "middle")
|
.attr("text-anchor", "middle")
|
||||||
.attr("x", 0)
|
.attr("x", 0)
|
||||||
.attr("y", p.radius)
|
.attr("y", p.radius - 15)
|
||||||
.text(() => selectorStore.currentPod.label);
|
.text(() => selectorStore.currentPod.label);
|
||||||
const nodeArr = networkProfilingStore.nodes.filter(
|
const nodeArr = networkProfilingStore.nodes.filter(
|
||||||
(d: ProcessNode) => d.isReal || d.name === "UNKNOWN_LOCAL"
|
(d: ProcessNode) => d.isReal || d.name === "UNKNOWN_LOCAL"
|
||||||
@ -270,21 +267,16 @@ function createLayout() {
|
|||||||
const outNodes = networkProfilingStore.nodes.filter(
|
const outNodes = networkProfilingStore.nodes.filter(
|
||||||
(d: ProcessNode) => !(d.isReal || d.name === "UNKNOWN_LOCAL")
|
(d: ProcessNode) => !(d.isReal || d.name === "UNKNOWN_LOCAL")
|
||||||
);
|
);
|
||||||
let angle = 10;
|
const interval = 30;
|
||||||
let r = 230;
|
let r = 250;
|
||||||
|
let pointArr = getCirclePoint(r, interval);
|
||||||
for (let v = 0; v < outNodes.length; v++) {
|
for (let v = 0; v < outNodes.length; v++) {
|
||||||
const pos = getArcPoint(angle, r); // angle is [-120, 120]
|
if (!pointArr[v]) {
|
||||||
outNodes[v].x = pos[0];
|
r = r + 80;
|
||||||
outNodes[v].y = pos[1];
|
pointArr = [...pointArr, ...getCirclePoint(r, interval)];
|
||||||
angle = angle + 20;
|
|
||||||
if (angle * (v + 1) > 120) {
|
|
||||||
angle = -10;
|
|
||||||
r = r + 60;
|
|
||||||
}
|
|
||||||
if (angle * (v + 1) < -120) {
|
|
||||||
r = r + 60;
|
|
||||||
angle = 10;
|
|
||||||
}
|
}
|
||||||
|
outNodes[v].x = pointArr[v][0];
|
||||||
|
outNodes[v].y = pointArr[v][1];
|
||||||
}
|
}
|
||||||
drawTopology([...nodeArr, ...outNodes]);
|
drawTopology([...nodeArr, ...outNodes]);
|
||||||
}
|
}
|
||||||
@ -305,15 +297,11 @@ function drawTopology(nodeArr: any[]) {
|
|||||||
// line element
|
// line element
|
||||||
const obj = {} as any;
|
const obj = {} as any;
|
||||||
const calls = networkProfilingStore.calls.reduce((prev: any[], next: any) => {
|
const calls = networkProfilingStore.calls.reduce((prev: any[], next: any) => {
|
||||||
if (
|
if (obj[next.targetId + next.sourceId]) {
|
||||||
!(
|
next.lowerArc = true;
|
||||||
obj[next.sourceId + next.targetId] && obj[next.targetId + next.sourceId]
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
obj[next.sourceId + next.targetId] = true;
|
|
||||||
obj[next.targetId + next.sourceId] = true;
|
|
||||||
prev.push(next);
|
|
||||||
}
|
}
|
||||||
|
obj[next.sourceId + next.targetId] = true;
|
||||||
|
prev.push(next);
|
||||||
return prev;
|
return prev;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -66,10 +66,10 @@ limitations under the License. -->
|
|||||||
dateFormat(i.taskStartTime + i.fixedTriggerDuration * 1000)
|
dateFormat(i.taskStartTime + i.fixedTriggerDuration * 1000)
|
||||||
}}
|
}}
|
||||||
</span>
|
</span>
|
||||||
<span class="ml-10" @click="viewDetail = true">
|
<span class="new-task" @click="viewDetail = true">
|
||||||
<Icon iconName="view" size="middle" />
|
<Icon iconName="view" size="middle" />
|
||||||
</span>
|
</span>
|
||||||
<span class="ml-5" v-if="index === 0 && inProcess">
|
<span class="reload" v-if="index === 0 && inProcess">
|
||||||
<Icon iconName="retry" :loading="true" size="middle" />
|
<Icon iconName="retry" :loading="true" size="middle" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -107,7 +107,9 @@ const appStore = useAppStoreWithOut();
|
|||||||
const viewDetail = ref<boolean>(false);
|
const viewDetail = ref<boolean>(false);
|
||||||
/*global Nullable */
|
/*global Nullable */
|
||||||
const intervalFn = ref<Nullable<any>>(null);
|
const intervalFn = ref<Nullable<any>>(null);
|
||||||
const inProcess = ref<boolean>(true);
|
const intervalKeepAlive = ref<Nullable<any>>(null);
|
||||||
|
const inProcess = ref<boolean>(false);
|
||||||
|
|
||||||
fetchTasks();
|
fetchTasks();
|
||||||
|
|
||||||
async function changeTask(item: EBPFTaskList) {
|
async function changeTask(item: EBPFTaskList) {
|
||||||
@ -157,6 +159,7 @@ async function getTopology() {
|
|||||||
}
|
}
|
||||||
if (!inProcess.value) {
|
if (!inProcess.value) {
|
||||||
intervalFn.value && clearInterval(intervalFn.value);
|
intervalFn.value && clearInterval(intervalFn.value);
|
||||||
|
intervalKeepAlive.value && clearInterval(intervalKeepAlive.value);
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
@ -184,19 +187,31 @@ async function createTask() {
|
|||||||
}
|
}
|
||||||
await fetchTasks();
|
await fetchTasks();
|
||||||
}
|
}
|
||||||
async function enableInterval() {
|
function enableInterval() {
|
||||||
|
intervalFn.value = setInterval(getTopology, 30000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function networkInterval() {
|
||||||
|
intervalKeepAlive.value = setInterval(keepAliveNetwork, 60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function keepAliveNetwork() {
|
||||||
const res = await networkProfilingStore.keepNetworkProfiling(
|
const res = await networkProfilingStore.keepNetworkProfiling(
|
||||||
networkProfilingStore.selectedNetworkTask.taskId
|
networkProfilingStore.selectedNetworkTask.taskId
|
||||||
);
|
);
|
||||||
if (res.errors) {
|
if (res.errors) {
|
||||||
|
intervalKeepAlive.value && clearInterval(intervalKeepAlive.value);
|
||||||
return ElMessage.error(res.errors);
|
return ElMessage.error(res.errors);
|
||||||
}
|
}
|
||||||
if (networkProfilingStore.aliveNetwork) {
|
if (!networkProfilingStore.aliveNetwork) {
|
||||||
intervalFn.value = setInterval(getTopology, 60000);
|
intervalFn.value && clearInterval(intervalFn.value);
|
||||||
|
intervalKeepAlive.value && clearInterval(intervalKeepAlive.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchTasks() {
|
async function fetchTasks() {
|
||||||
intervalFn.value && clearInterval(intervalFn.value);
|
intervalFn.value && clearInterval(intervalFn.value);
|
||||||
|
intervalKeepAlive.value && clearInterval(intervalKeepAlive.value);
|
||||||
const serviceId =
|
const serviceId =
|
||||||
(selectorStore.currentService && selectorStore.currentService.id) || "";
|
(selectorStore.currentService && selectorStore.currentService.id) || "";
|
||||||
const serviceInstanceId =
|
const serviceInstanceId =
|
||||||
@ -210,9 +225,14 @@ async function fetchTasks() {
|
|||||||
if (res.errors) {
|
if (res.errors) {
|
||||||
return ElMessage.error(res.errors);
|
return ElMessage.error(res.errors);
|
||||||
}
|
}
|
||||||
|
if (!networkProfilingStore.networkTasks.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
await getTopology();
|
await getTopology();
|
||||||
if (inProcess.value) {
|
if (inProcess.value) {
|
||||||
enableInterval();
|
enableInterval();
|
||||||
|
networkInterval();
|
||||||
|
keepAliveNetwork();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +256,7 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.profile-td {
|
.profile-td {
|
||||||
padding: 10px 0 10px 10px;
|
padding: 10px 5px 10px 10px;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.07);
|
border-bottom: 1px solid rgba(0, 0, 0, 0.07);
|
||||||
|
|
||||||
&.selected {
|
&.selected {
|
||||||
@ -270,7 +290,7 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.profile-t-tool {
|
.profile-t-tool {
|
||||||
padding: 5px 10px;
|
padding: 10px 5px 10px 10px;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.07);
|
border-bottom: 1px solid rgba(0, 0, 0, 0.07);
|
||||||
background: #f3f4f9;
|
background: #f3f4f9;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -279,4 +299,8 @@ watch(
|
|||||||
.new-task {
|
.new-task {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reload {
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user