fix: update trace list

This commit is contained in:
Qiuxia Fan 2022-02-24 17:45:46 +08:00
parent ceceabec66
commit 437ed482be
5 changed files with 151 additions and 119 deletions

View File

@ -89,7 +89,8 @@
"@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-function-return-type": "off",
"no-use-before-define": "off", "no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": "off", "@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-non-null-assertion": "off" "@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-this-alias": "off"
}, },
"overrides": [ "overrides": [
{ {

View File

@ -0,0 +1,16 @@
<!-- 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. -->
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>icn/issue-open-m</title><path d="M8 13A5 5 0 1 0 8 3a5 5 0 0 0 0 10zm0 2A7 7 0 1 1 8 1a7 7 0 0 1 0 14z" id="a"/></svg>

After

Width:  |  Height:  |  Size: 1017 B

View File

@ -11,92 +11,96 @@ 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="trace-detail">
class="trace-detail-wrapper clear" <div
v-if="traceStore.currentTrace.endpointNames" class="trace-detail-wrapper clear"
> v-if="traceStore.currentTrace.endpointNames"
<h5 class="mb-5 mt-0"> >
<Icon <h5 class="mb-5 mt-0">
icon="clear" <Icon
v-if="traceStore.currentTrace.isError" icon="clear"
class="red mr-5 sm" v-if="traceStore.currentTrace.isError"
/> class="red mr-5 sm"
<span class="vm">{{ traceStore.currentTrace.endpointNames[0] }}</span> />
<!-- <div class="trace-log-btn bg-blue r mr-10" @click="searchTraceLogs"> <span class="vm">{{ traceStore.currentTrace.endpointNames[0] }}</span>
<!-- <div class="trace-log-btn bg-blue r mr-10" @click="searchTraceLogs">
{{ t("viewLogs") }} {{ t("viewLogs") }}
</div> --> </div> -->
</h5> </h5>
<div class="mb-5 blue sm"> <div class="mb-5 blue sm">
<Selector <Selector
size="small" size="small"
:value=" :value="
traceStore.currentTrace.traceIds && traceStore.currentTrace.traceIds &&
traceStore.currentTrace.traceIds[0] && traceStore.currentTrace.traceIds[0] &&
traceStore.currentTrace.traceIds[0].value traceStore.currentTrace.traceIds[0].value
" "
:options="traceStore.currentTrace.traceIds" :options="traceStore.currentTrace.traceIds"
@change="changeTraceId" @change="changeTraceId"
class="trace-detail-ids" class="trace-detail-ids"
/> />
<Icon <Icon
size="sm" size="sm"
class="icon grey link-hover cp ml-5" class="icon grey link-hover cp ml-5"
iconName="review-list" iconName="review-list"
@click="handleClick" @click="handleClick"
/> />
</div>
<div class="flex-h item">
<div>
<div class="tag mr-5">{{ t("start") }}</div>
<span class="mr-15 sm">
{{ dateFormat(parseInt(traceStore.currentTrace.start)) }}
</span>
<div class="tag mr-5">{{ t("duration") }}</div>
<span class="mr-15 sm">{{ traceStore.currentTrace.duration }} ms</span>
<div class="tag mr-5">{{ t("spans") }}</div>
<span class="sm">{{ traceStore.traceSpans.length }}</span>
</div> </div>
<div> <div class="flex-h item">
<el-button <div>
class="grey" <div class="tag mr-5">{{ t("start") }}</div>
:class="{ ghost: displayMode !== 'list' }" <span class="mr-15 sm">
@click="displayMode = 'list'" {{ dateFormat(parseInt(traceStore.currentTrace.start)) }}
> </span>
<Icon class="mr-5" size="sm" iconName="list-bulleted" /> <div class="tag mr-5">{{ t("duration") }}</div>
{{ t("list") }} <span class="mr-15 sm"
</el-button> >{{ traceStore.currentTrace.duration }} ms</span
<el-button >
class="grey" <div class="tag mr-5">{{ t("spans") }}</div>
:class="{ ghost: displayMode !== 'tree' }" <span class="sm">{{ traceStore.traceSpans.length }}</span>
@click="displayMode = 'tree'" </div>
> <div>
<Icon class="mr-5" size="sm" iconName="issue-child" /> <el-button
{{ t("tree") }} class="grey"
</el-button> :class="{ ghost: displayMode !== 'list' }"
<el-button @click="displayMode = 'list'"
class="grey" >
:class="{ ghost: displayMode !== 'table' }" <Icon class="mr-5" size="sm" iconName="list-bulleted" />
@click="displayMode = 'table'" {{ t("list") }}
> </el-button>
<Icon class="mr-5" size="sm" iconName="table" /> <el-button
{{ t("table") }} class="grey"
</el-button> :class="{ ghost: displayMode !== 'tree' }"
<el-button @click="displayMode = 'tree'"
class="grey" >
:class="{ ghost: displayMode !== 'statistics' }" <Icon class="mr-5" size="sm" iconName="issue-child" />
@click="displayMode = 'statistics'" {{ t("tree") }}
> </el-button>
<Icon class="mr-5" size="sm" iconName="statistics-bulleted" /> <el-button
{{ t("statistics") }} class="grey"
</el-button> :class="{ ghost: displayMode !== 'table' }"
@click="displayMode = 'table'"
>
<Icon class="mr-5" size="sm" iconName="table" />
{{ t("table") }}
</el-button>
<el-button
class="grey"
:class="{ ghost: displayMode !== 'statistics' }"
@click="displayMode = 'statistics'"
>
<Icon class="mr-5" size="sm" iconName="statistics-bulleted" />
{{ t("statistics") }}
</el-button>
</div>
</div> </div>
</div> </div>
<List
v-if="displayMode == 'list' && traceStore.currentTrace.endpointNames"
:data="traceStore.traceSpans"
:traceId="traceStore.currentTrace.traceIds[0].value"
/>
</div> </div>
<List
v-if="displayMode == 'list' && traceStore.currentTrace.endpointNames"
:data="traceStore.traceSpans"
:traceId="traceStore.currentTrace.traceIds[0].value"
/>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import dayjs from "dayjs"; import dayjs from "dayjs";
@ -141,6 +145,11 @@ function changeTraceId(opt: Option[]) {
// } // }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.trace-detail {
height: 100%;
width: 100%;
}
.trace-detail-wrapper { .trace-detail-wrapper {
font-size: 12px; font-size: 12px;
padding: 5px 10px; padding: 5px 10px;

View File

@ -11,24 +11,24 @@ 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="time-charts scroll_hide"> <div class="time-charts">
<div class="trace-t-loading" v-show="loading"> <div class="trace-t-loading" v-show="loading">
<Icon iconName="spinner" size="sm" /> <Icon iconName="spinner" size="sm" />
</div> </div>
<transition-group name="fade" tag="a" class="mb-5"> <div class="service-code">
<span <span
class="time-charts-item mr-10" class="time-charts-item mr-5"
v-for="(i, index) in data" v-for="(i, index) in list"
:key="index" :key="index"
:style="`color:${computedScale(index)}`" :style="`color:${computedScale(index)}`"
> >
<svg class="icon vm mr-5 sm"> <Icon iconName="issue-open-m" class="mr-5" size="sm" />
<use xlink:href="#issue-open-m"></use>
</svg>
<span>{{ i }}</span> <span>{{ i }}</span>
</span> </span>
</transition-group> <el-button class="btn" type="primary" @click="downloadTrace">
<a class="rk-btn r vm tc" @click="downloadTrace">{{ t("exportImage") }}</a> {{ t("exportImage") }}
</el-button>
</div>
<div class="trace-list"> <div class="trace-list">
<div ref="traceList"></div> <div ref="traceList"></div>
</div> </div>
@ -41,9 +41,8 @@ import _ from "lodash";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import * as d3 from "d3"; import * as d3 from "d3";
import ListGraph from "./utils/d3-trace"; import ListGraph from "./utils/d3-trace";
import copy from "@/utils/copy"; import { Span } from "@/types/trace";
import { Span, Trace } from "@/types/trace";
import { Option } from "@/types/app";
/* global defineProps, Nullable*/ /* global defineProps, Nullable*/
const props = defineProps({ const props = defineProps({
data: { type: Array as PropType<Span[]>, default: () => [] }, data: { type: Array as PropType<Span[]>, default: () => [] },
@ -55,7 +54,7 @@ const showDetail = ref<boolean>(false);
const fixSpansSize = ref<number>(0); const fixSpansSize = ref<number>(0);
const segmentId = ref<any>([]); const segmentId = ref<any>([]);
const currentSpan = ref<Array<Span>>([]); const currentSpan = ref<Array<Span>>([]);
const list = ref<any>([]); const list = ref<string[]>([]);
const tree = ref<any>(null); const tree = ref<any>(null);
const traceList = ref<Nullable<HTMLDivElement>>(null); const traceList = ref<Nullable<HTMLDivElement>>(null);
@ -141,7 +140,7 @@ function changeTree() {
if (props.data.length === 0) { if (props.data.length === 0) {
return []; return [];
} }
list.value = Array.from(new Set(props.data.map((i: any) => i.serviceCode))); list.value = Array.from(new Set(props.data.map((i: Span) => i.serviceCode)));
segmentId.value = []; segmentId.value = [];
const segmentGroup: any = {}; const segmentGroup: any = {};
const segmentIdGroup: any = []; const segmentIdGroup: any = [];
@ -335,9 +334,10 @@ watch(
<style lang="scss" scoped> <style lang="scss" scoped>
.time-charts { .time-charts {
overflow: auto; overflow: auto;
padding: 10px 30px; padding: 10px;
position: relative; position: relative;
min-height: 150px; height: calc(100% - 95px);
width: 100%;
} }
.trace-node .group { .trace-node .group {
@ -387,4 +387,8 @@ watch(
overflow: auto; overflow: auto;
font-family: monospace; font-family: monospace;
} }
.btn {
float: right;
}
</style> </style>

View File

@ -18,6 +18,7 @@
import * as d3 from "d3"; import * as d3 from "d3";
import d3tip from "d3-tip"; import d3tip from "d3-tip";
import { Span, Trace } from "@/types/trace"; import { Span, Trace } from "@/types/trace";
import { func } from "vue-types";
const type = { const type = {
MQ: "#bf99f8", MQ: "#bf99f8",
@ -49,7 +50,7 @@ export default class ListGraph {
constructor(el: HTMLDivElement, handleSelectSpan: (i: Trace) => void) { constructor(el: HTMLDivElement, handleSelectSpan: (i: Trace) => void) {
this.handleSelectSpan = handleSelectSpan; this.handleSelectSpan = handleSelectSpan;
this.el = el; this.el = el;
this.width = el.clientWidth; this.width = el.clientWidth - 20;
this.height = el.clientHeight; this.height = el.clientHeight;
this.svg = d3 this.svg = d3
.select(this.el) .select(this.el)
@ -61,23 +62,23 @@ export default class ListGraph {
this.tip = (d3tip as any)() this.tip = (d3tip as any)()
.attr("class", "d3-tip") .attr("class", "d3-tip")
.offset([-8, 0]) .offset([-8, 0])
.html( .html((d: any) => {
(d: any) => ` return `
<div class="mb-5">${d.data.label}</div> <div class="mb-5">${d.data.label}</div>
${ ${
d.data.dur d.data.dur
? '<div class="sm">SelfDuration: ' + d.data.dur + "ms</div>" ? '<div class="sm">SelfDuration: ' + d.data.dur + "ms</div>"
: "" : ""
} }
${ ${
d.data.endTime - d.data.startTime d.data.endTime - d.data.startTime
? '<div class="sm">TotalDuration: ' + ? '<div class="sm">TotalDuration: ' +
(d.data.endTime - d.data.startTime) + (d.data.endTime - d.data.startTime) +
"ms</div>" "ms</div>"
: "" : ""
} }
` `;
); });
this.svg.call(this.tip); this.svg.call(this.tip);
} }
diagonal(d: any) { diagonal(d: any) {
@ -135,6 +136,7 @@ export default class ListGraph {
scope.update(d); scope.update(d);
} }
update(source: any, callback: any) { update(source: any, callback: any) {
const t = this;
const nodes = this.root.descendants(); const nodes = this.root.descendants();
let index = -1; let index = -1;
this.root.eachBefore((n: any) => { this.root.eachBefore((n: any) => {
@ -150,11 +152,11 @@ export default class ListGraph {
.attr("transform", `translate(${source.y0},${source.x0})`) .attr("transform", `translate(${source.y0},${source.x0})`)
.attr("class", "trace-node") .attr("class", "trace-node")
.style("opacity", 0) .style("opacity", 0)
.on("mouseover", (d: Trace) => { .on("mouseover", function (event: any, d: Trace) {
this.tip.show(d, this); t.tip.show(d, this);
}) })
.on("mouseout", (d: Trace) => { .on("mouseout", function (event: any, d: Trace) {
this.tip.hide(d, this); t.tip.hide(d, this);
}) })
.on("click", (d: Trace) => { .on("click", (d: Trace) => {
if (this.handleSelectSpan) { if (this.handleSelectSpan) {