mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-07-18 11:05:24 +00:00
fix: update profile
This commit is contained in:
parent
1ea3e4a04a
commit
eab42fa1c6
@ -40,6 +40,7 @@ interface ProfileState {
|
|||||||
currentSpan: SegmentSpan | Record<string, never>;
|
currentSpan: SegmentSpan | Record<string, never>;
|
||||||
analyzeTrees: ProfileAnalyzationTrees;
|
analyzeTrees: ProfileAnalyzationTrees;
|
||||||
taskLogs: TaskLog[];
|
taskLogs: TaskLog[];
|
||||||
|
highlightTop: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const traceStore = defineStore({
|
export const traceStore = defineStore({
|
||||||
@ -55,6 +56,7 @@ export const traceStore = defineStore({
|
|||||||
currentSpan: {},
|
currentSpan: {},
|
||||||
analyzeTrees: [],
|
analyzeTrees: [],
|
||||||
taskLogs: [],
|
taskLogs: [],
|
||||||
|
highlightTop: true,
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
setConditions(data: { serviceId?: string; endpointName?: string }) {
|
setConditions(data: { serviceId?: string; endpointName?: string }) {
|
||||||
@ -69,6 +71,9 @@ export const traceStore = defineStore({
|
|||||||
setCurrentSegment(s: Trace) {
|
setCurrentSegment(s: Trace) {
|
||||||
this.currentSegment = s;
|
this.currentSegment = s;
|
||||||
},
|
},
|
||||||
|
setHighlightTop() {
|
||||||
|
this.highlightTop = !this.highlightTop;
|
||||||
|
},
|
||||||
async getServices(layer: string) {
|
async getServices(layer: string) {
|
||||||
const res: AxiosResponse = await graphql.query("queryServices").params({
|
const res: AxiosResponse = await graphql.query("queryServices").params({
|
||||||
layer,
|
layer,
|
||||||
|
@ -31,7 +31,7 @@ limitations under the License. -->
|
|||||||
:key="item.i"
|
:key="item.i"
|
||||||
@click="clickGrid(item)"
|
@click="clickGrid(item)"
|
||||||
:class="{ active: dashboardStore.activedGridItem === item.i }"
|
:class="{ active: dashboardStore.activedGridItem === item.i }"
|
||||||
drag-ignore-from="svg.d3-trace-tree"
|
drag-ignore-from="svg.d3-trace-tree, .dragger"
|
||||||
>
|
>
|
||||||
<component :is="item.type" :data="item" />
|
<component :is="item.type" :data="item" />
|
||||||
</grid-item>
|
</grid-item>
|
||||||
|
@ -32,13 +32,13 @@ import ThreadStack from "./components/ThreadStack.vue";
|
|||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.content {
|
.content {
|
||||||
height: 100%;
|
height: calc(100% - 30px);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: calc(100% - 290px);
|
width: calc(100% - 300px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
|
@ -13,14 +13,11 @@ 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
|
<div class="profile-trace-dashboard" v-if="profileStore.currentSegment">
|
||||||
class="profile-trace-dashboard flex-v"
|
|
||||||
v-if="profileStore.currentSegment"
|
|
||||||
>
|
|
||||||
<div class="profile-trace-detail-wrapper">
|
<div class="profile-trace-detail-wrapper">
|
||||||
<Selector
|
<Selector
|
||||||
size="small"
|
size="small"
|
||||||
:value="traceId"
|
:value="traceId || (traceIds[0] && traceIds[0].value) || ''"
|
||||||
:options="traceIds"
|
:options="traceIds"
|
||||||
placeholder="Select a trace id"
|
placeholder="Select a trace id"
|
||||||
@change="changeTraceId"
|
@change="changeTraceId"
|
||||||
@ -159,7 +156,7 @@ function updateTimeRange() {
|
|||||||
.profile-trace-dashboard {
|
.profile-trace-dashboard {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
height: calc(50% + 95);
|
height: 50%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,128 @@
|
|||||||
|
<!-- 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">
|
||||||
|
<div class="profile-header">
|
||||||
|
<div class="thread" :style="`width: ${thread}px`">
|
||||||
|
Thread Stack
|
||||||
|
<span class="r cp dragger" ref="dragger">
|
||||||
|
<Icon iconName="settings_ethernet" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="self">Duration (ms)</div>
|
||||||
|
<div class="exec-ms">
|
||||||
|
Self Duration (ms)
|
||||||
|
<a
|
||||||
|
class="profile-set-btn"
|
||||||
|
@click="updateHighlightTop()"
|
||||||
|
title="Highlight top 10 slow methods"
|
||||||
|
:style="{ color: highlightTop ? '#448dfe' : '#484b55' }"
|
||||||
|
>
|
||||||
|
top slow
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="dump-count">Dump Count</div>
|
||||||
|
</div>
|
||||||
|
<TableItem
|
||||||
|
:thread="thread"
|
||||||
|
v-for="(item, index) in tableData"
|
||||||
|
:data="item"
|
||||||
|
:key="'key' + index"
|
||||||
|
/>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useProfileStore } from "@/store/modules/profile";
|
||||||
|
import { ref, onMounted } from "vue";
|
||||||
|
import type { PropType } from "vue";
|
||||||
|
import TableItem from "./Item.vue";
|
||||||
|
|
||||||
|
/* global defineProps */
|
||||||
|
defineProps({
|
||||||
|
tableData: { type: Array as PropType<any>, default: () => [] },
|
||||||
|
highlightTop: { type: Boolean, default: false },
|
||||||
|
});
|
||||||
|
const dragger = ref<any>(null);
|
||||||
|
const thread = ref<number>(500);
|
||||||
|
const profileStore = useProfileStore();
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
dragger.value.onmousedown = (event: any) => {
|
||||||
|
const diffX = event.clientX;
|
||||||
|
const copy = thread.value;
|
||||||
|
document.onmousemove = (documentEvent) => {
|
||||||
|
const moveX = documentEvent.clientX - diffX;
|
||||||
|
thread.value = copy + moveX;
|
||||||
|
};
|
||||||
|
document.onmouseup = () => {
|
||||||
|
document.onmousemove = null;
|
||||||
|
document.onmouseup = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateHighlightTop() {
|
||||||
|
profileStore.setHighlightTop();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "./profile.scss";
|
||||||
|
|
||||||
|
.dragger {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile {
|
||||||
|
font-size: 12px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.profile-set-btn {
|
||||||
|
font-size: 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 3px;
|
||||||
|
text-align: center;
|
||||||
|
width: 57px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: inline-block;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
right: 3px;
|
||||||
|
padding: 0 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-header {
|
||||||
|
white-space: nowrap;
|
||||||
|
user-select: none;
|
||||||
|
border-left: 0;
|
||||||
|
border-right: 0;
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-header div {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 4px;
|
||||||
|
border-right: 1px dotted silver;
|
||||||
|
line-height: 30px;
|
||||||
|
background-color: #f3f4f9;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
</style>
|
109
src/views/dashboard/related/profile/components/Stack/Index.vue
Normal file
109
src/views/dashboard/related/profile/components/Stack/Index.vue
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<!-- 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-detail-chart-table">
|
||||||
|
<Container :tableData="tableData" :highlightTop="highlightTop">
|
||||||
|
<div class="profile-tips" v-if="!tableData.length">{{ t("noData") }}</div>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { ref, onMounted, watch } from "vue";
|
||||||
|
import type { PropType } from "vue";
|
||||||
|
import Container from "./Container.vue";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
/* global defineProps */
|
||||||
|
const props = defineProps({
|
||||||
|
data: { type: Array as PropType<any>, default: () => [] },
|
||||||
|
highlightTop: { type: Boolean, default: false },
|
||||||
|
});
|
||||||
|
const tableData = ref<any>([]);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
tableData.value = processTree();
|
||||||
|
});
|
||||||
|
function processTree() {
|
||||||
|
if (!props.data.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const durationChildExcluded = props.data
|
||||||
|
.map((d: any) => {
|
||||||
|
return d.elements.map((item: any) => item.durationChildExcluded);
|
||||||
|
})
|
||||||
|
.flat(1);
|
||||||
|
function compare(val: number, val1: number) {
|
||||||
|
return val1 - val;
|
||||||
|
}
|
||||||
|
const topDur = durationChildExcluded
|
||||||
|
.sort(compare)
|
||||||
|
.filter((item: any, index: number) => index < 10 && item !== 0);
|
||||||
|
const trees = [];
|
||||||
|
|
||||||
|
for (const item of props.data) {
|
||||||
|
const newArr = sortArr(item.elements, topDur);
|
||||||
|
trees.push(...newArr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return trees;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortArr(arr: any[], topDur: any) {
|
||||||
|
const copyArr = JSON.parse(JSON.stringify(arr));
|
||||||
|
const obj: any = {};
|
||||||
|
const res = [];
|
||||||
|
for (const item of copyArr) {
|
||||||
|
obj[item.id] = item;
|
||||||
|
}
|
||||||
|
for (const item of copyArr) {
|
||||||
|
item.topDur =
|
||||||
|
topDur.includes(item.durationChildExcluded) && props.highlightTop;
|
||||||
|
if (item.parentId === "0") {
|
||||||
|
res.push(item);
|
||||||
|
}
|
||||||
|
for (const key in obj) {
|
||||||
|
if (item.id === obj[key].parentId) {
|
||||||
|
if (item.children) {
|
||||||
|
item.children.push(obj[key]);
|
||||||
|
} else {
|
||||||
|
item.children = [obj[key]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => [props.data, props.highlightTop],
|
||||||
|
() => {
|
||||||
|
if (!props.data.length) {
|
||||||
|
tableData.value = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tableData.value = processTree();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.profile-detail-chart-table {
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
153
src/views/dashboard/related/profile/components/Stack/Item.vue
Normal file
153
src/views/dashboard/related/profile/components/Stack/Item.vue
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
<!-- 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>
|
||||||
|
<div
|
||||||
|
:class="['profile-item', 'level' + data.parentId]"
|
||||||
|
:style="{ color: data.topDur ? '#448dfe' : '#3d444f' }"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:class="['thread', 'level' + data.parentId]"
|
||||||
|
:style="{
|
||||||
|
'text-indent': data.parentId * 4 + 'px',
|
||||||
|
width: `${thread}px`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
class="icon vm cp trans"
|
||||||
|
:style="!displayChildren ? 'transform: rotate(-90deg);' : ''"
|
||||||
|
@click.stop="toggle"
|
||||||
|
v-if="data.children && data.children.length"
|
||||||
|
iconName="arrow-down"
|
||||||
|
/>
|
||||||
|
<el-tooltip :content="data.codeSignature" placement="bottom">
|
||||||
|
<span>
|
||||||
|
{{ data.codeSignature }}
|
||||||
|
</span>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
<div class="self">{{ data.duration }}</div>
|
||||||
|
<div class="exec-ms">{{ data.durationChildExcluded }}</div>
|
||||||
|
<div class="dump-count">{{ data.count }}</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-show="data.children && data.children.length && displayChildren"
|
||||||
|
class="children-trace"
|
||||||
|
>
|
||||||
|
<table-item
|
||||||
|
:thread="thread"
|
||||||
|
v-for="(item, index) in data.children"
|
||||||
|
:key="index"
|
||||||
|
:data="item"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { ref, defineComponent, toRefs } from "vue";
|
||||||
|
import type { PropType } from "vue";
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
data: { type: Object as PropType<any>, default: () => ({}) },
|
||||||
|
thread: { type: Number, default: 0 },
|
||||||
|
};
|
||||||
|
export default defineComponent({
|
||||||
|
name: "TableItem",
|
||||||
|
props,
|
||||||
|
setup(props) {
|
||||||
|
const displayChildren = ref<boolean>(true);
|
||||||
|
function toggle() {
|
||||||
|
displayChildren.value = !displayChildren.value;
|
||||||
|
}
|
||||||
|
return { toggle, displayChildren, ...toRefs(props) };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "./profile.scss";
|
||||||
|
|
||||||
|
.profile-item.level0 {
|
||||||
|
background: rgba(0, 0, 0, 0.04);
|
||||||
|
color: #448dfe;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.04);
|
||||||
|
color: #448dfe;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
width: 5px;
|
||||||
|
height: 100%;
|
||||||
|
background: #448dfe;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-item {
|
||||||
|
position: relative;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-item.selected {
|
||||||
|
background: rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-item:not(.level0):hover {
|
||||||
|
background: rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-item > div {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 5px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-right: 1px dotted silver;
|
||||||
|
overflow: hidden;
|
||||||
|
line-height: 30px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-item > div.method {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-item div.exec-percent {
|
||||||
|
width: 10%;
|
||||||
|
height: 30px;
|
||||||
|
padding: 0 8px;
|
||||||
|
|
||||||
|
.outer-progress_bar {
|
||||||
|
width: 100%;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: rgb(63, 177, 227);
|
||||||
|
position: relative;
|
||||||
|
margin-top: 11px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner-progress_bar {
|
||||||
|
position: absolute;
|
||||||
|
background: rgb(110, 64, 170);
|
||||||
|
height: 4px;
|
||||||
|
border-radius: 2px;
|
||||||
|
left: 0;
|
||||||
|
border: none;
|
||||||
|
top: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
.dump-count {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exec-ms {
|
||||||
|
width: 200px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.self {
|
||||||
|
width: 100px;
|
||||||
|
}
|
@ -12,7 +12,33 @@ distributed under the License is distributed on an "AS IS" BASIS,
|
|||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
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>stack</div>
|
<div v-if="profileStore.analyzeTrees.length" class="thread-stack">
|
||||||
|
<StackTable
|
||||||
|
:data="profileStore.analyzeTrees"
|
||||||
|
:highlightTop="profileStore.highlightTop"
|
||||||
|
/>
|
||||||
|
<div class="rk-trace-t-loading" v-show="loading">
|
||||||
|
<Icon iconName="spinner" />
|
||||||
|
</div>
|
||||||
|
<div v-if="message">{{ message }}</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup></script>
|
<script lang="ts" setup>
|
||||||
|
import { ref } from "vue";
|
||||||
|
import StackTable from "./Stack/Index.vue";
|
||||||
|
import { useProfileStore } from "@/store/modules/profile";
|
||||||
|
|
||||||
|
const profileStore = useProfileStore();
|
||||||
|
const loading = ref<boolean>(false);
|
||||||
|
const message = ref<string>("");
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.thread-stack {
|
||||||
|
padding: 5px 12px;
|
||||||
|
height: calc(50% - 50px);
|
||||||
|
overflow: auto;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -123,14 +123,16 @@ limitations under the License. -->
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="no-data" v-else>{{ t("noData") }}</div>
|
<div class="no-data" v-else>{{ t("noData") }}</div>
|
||||||
<component
|
<div class="trace-chart">
|
||||||
v-if="traceStore.currentTrace.endpointNames"
|
<component
|
||||||
:is="displayMode"
|
v-if="traceStore.currentTrace.endpointNames"
|
||||||
:data="traceStore.traceSpans"
|
:is="displayMode"
|
||||||
:traceId="traceStore.currentTrace.traceIds[0].value"
|
:data="traceStore.traceSpans"
|
||||||
:showBtnDetail="false"
|
:traceId="traceStore.currentTrace.traceIds[0].value"
|
||||||
HeaderType="trace"
|
:showBtnDetail="false"
|
||||||
/>
|
HeaderType="trace"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
@ -227,6 +229,10 @@ export default defineComponent({
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.trace-chart {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.trace-detail-wrapper {
|
.trace-detail-wrapper {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
|
@ -88,7 +88,7 @@ function downloadTrace() {
|
|||||||
.charts {
|
.charts {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
height: calc(100% - 95px);
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,8 +105,7 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.trace-table {
|
.trace-table {
|
||||||
padding: 10px;
|
height: 100%;
|
||||||
height: calc(100% - 95px);
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -30,7 +30,7 @@ limitations under the License. -->
|
|||||||
</div>
|
</div>
|
||||||
<div class="trace-header" v-else>
|
<div class="trace-header" v-else>
|
||||||
<div class="method" :style="`width: ${method}px`">
|
<div class="method" :style="`width: ${method}px`">
|
||||||
<span class="r cp" ref="dragger">
|
<span class="cp dragger" ref="dragger">
|
||||||
<Icon iconName="settings_ethernet" size="sm" />
|
<Icon iconName="settings_ethernet" size="sm" />
|
||||||
</span>
|
</span>
|
||||||
{{ headerData[0].value }}
|
{{ headerData[0].value }}
|
||||||
@ -158,6 +158,10 @@ function sortStatistics(key: string) {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dragger {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
.trace-header {
|
.trace-header {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
@ -15,7 +15,7 @@ limitations under the License. -->
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="type === 'statistics'">
|
<div v-if="type === 'statistics'">
|
||||||
<div :class="['trace-item']" ref="traceItem">
|
<div class="trace-item">
|
||||||
<div :class="['method']">
|
<div :class="['method']">
|
||||||
<el-tooltip :content="data.groupRef.endpointName" placement="bottom">
|
<el-tooltip :content="data.groupRef.endpointName" placement="bottom">
|
||||||
<span>
|
<span>
|
||||||
@ -49,7 +49,7 @@ limitations under the License. -->
|
|||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div
|
<div
|
||||||
@click="viewSpanDetail"
|
@click="selectSpan"
|
||||||
:class="[
|
:class="[
|
||||||
'trace-item',
|
'trace-item',
|
||||||
'level' + (data.level - 1),
|
'level' + (data.level - 1),
|
||||||
@ -106,7 +106,7 @@ limitations under the License. -->
|
|||||||
<span>{{ data.serviceCode }}</span>
|
<span>{{ data.serviceCode }}</span>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="application" v-show="type === 'profile'">
|
<div class="application" v-show="headerType === 'profile'">
|
||||||
<span @click="viewSpanDetail">{{ t("view") }}</span>
|
<span @click="viewSpanDetail">{{ t("view") }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -120,6 +120,7 @@ limitations under the License. -->
|
|||||||
:key="index"
|
:key="index"
|
||||||
:data="child"
|
:data="child"
|
||||||
:type="type"
|
:type="type"
|
||||||
|
:headerType="headerType"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
@ -183,7 +184,7 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
displayChildren.value = !this.displayChildren.value;
|
displayChildren.value = !displayChildren.value;
|
||||||
}
|
}
|
||||||
function showSelectSpan() {
|
function showSelectSpan() {
|
||||||
const items: any = document.querySelectorAll(".trace-item");
|
const items: any = document.querySelectorAll(".trace-item");
|
||||||
@ -196,11 +197,16 @@ export default defineComponent({
|
|||||||
|
|
||||||
traceItem.value.style.background = "rgba(0, 0, 0, 1)";
|
traceItem.value.style.background = "rgba(0, 0, 0, 1)";
|
||||||
}
|
}
|
||||||
|
function selectSpan() {
|
||||||
|
if (props.headerType === "profile") {
|
||||||
|
showSelectSpan();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
viewSpanDetail();
|
||||||
|
}
|
||||||
function viewSpanDetail() {
|
function viewSpanDetail() {
|
||||||
showSelectSpan();
|
showSelectSpan();
|
||||||
if (props.headerType === "trace") {
|
showDetail.value = true;
|
||||||
showDetail.value = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -218,6 +224,7 @@ export default defineComponent({
|
|||||||
dateFormat,
|
dateFormat,
|
||||||
showSelectSpan,
|
showSelectSpan,
|
||||||
showDetail,
|
showDetail,
|
||||||
|
selectSpan,
|
||||||
t,
|
t,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -86,7 +86,7 @@ function computedScale(i: number) {
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: calc(100% - 95px);
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user