| <!-- 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 @click="showSelectSpan" :class="['trace-item', 'level' + (data.level - 1)]" ref="traceItem"> |
| <div :class="['method', 'level' + (data.level - 1)]" :style="{ 'text-indent': (data.level - 1) * 10 + 'px' }"> |
| <svg |
| class="icon vm cp trans" |
| :style="!displayChildren ? 'transform: rotate(-90deg);' : ''" |
| @click.stop="toggle" |
| v-if="data.children && data.children.length" |
| > |
| <use xlink:href="#arrow-down"></use> |
| </svg> |
| <span v-tooltip:bottom="{ content: data.endpointName, popperCls: ['trace-table-tooltip'] }"> |
| {{ data.endpointName }} |
| </span> |
| </div> |
| <div class="start-time"> |
| {{ data.startTime | dateformat }} |
| </div> |
| <div class="exec-ms"> |
| {{ data.endTime - data.startTime ? data.endTime - data.startTime : '0' }} |
| </div> |
| <div class="exec-percent"> |
| <div class="outer-progress_bar" :style="{ width: outterPercent }"> |
| <div class="inner-progress_bar" :style="{ width: innerPercent }"></div> |
| </div> |
| </div> |
| <div class="self"> |
| {{ data.dur ? data.dur + '' : '0' }} |
| </div> |
| <div class="api"> |
| <span v-tooltip:bottom="data.component || '-'">{{ data.component || '-' }}</span> |
| </div> |
| <div class="application"> |
| <span v-tooltip:bottom="data.serviceCode || '-'">{{ data.serviceCode }}</span> |
| </div> |
| <div class="application" v-show="type === 'profile'"> |
| <span @click="viewSpanDetail">{{ this.$t('view') }}</span> |
| </div> |
| </div> |
| <div v-show="data.children && data.children.length > 0 && displayChildren" class="children-trace"> |
| <item v-for="(item, index) in data.children" :key="index" :data="item" :type="type"> </item> |
| </div> |
| </div> |
| </template> |
| <script lang="js"> |
| export default { |
| name: 'item', |
| props: ['data', 'type'], |
| watch: { |
| data() { |
| const items = document.querySelectorAll('.trace-item'); |
| for (const item of items) { |
| item.style.background = '#fff'; |
| } |
| }, |
| }, |
| data() { |
| return { |
| displayChildren: true, |
| selectedSpan: 0, |
| }; |
| }, |
| computed: { |
| selfTime() { |
| const {data} = this; |
| return data.dur ? data.dur : 0; |
| }, |
| execTime() { |
| const {data} = this; |
| return (data.endTime - data.startTime) ? (data.endTime - data.startTime) : 0; |
| }, |
| outterPercent() { |
| if (this.data.level === 1) { |
| return '100%'; |
| } else { |
| const data = this.data; |
| const exec = (data.endTime - data.startTime) ? (data.endTime - data.startTime) : 0; |
| let result = (exec / data.totalExec * 100); |
| result = result > 100 ? 100 : result; |
| result = result.toFixed(4) + '%'; |
| return result === '0.0000%' ? '0.9%' : result; |
| } |
| }, |
| innerPercent() { |
| const result = (this.selfTime / this.execTime) * 100 .toFixed(4) + '%'; |
| return result === '0.0000%' ? '0.9%' : result; |
| }, |
| }, |
| methods: { |
| toggle() { |
| this.displayChildren = !this.displayChildren; |
| }, |
| showSelectSpan() { |
| const items = document.querySelectorAll('.trace-item'); |
| for (const item of items) { |
| item.style.background = '#fff'; |
| } |
| this.$refs.traceItem.style.background = 'rgba(0, 0, 0, 0.1)'; |
| this.$eventBus.$emit('HANDLE-SELECT-SPAN', this.data); |
| }, |
| viewSpanDetail() { |
| this.showSelectSpan(); |
| this.$eventBus.$emit('HANDLE-VIEW-SPAN', this.data); |
| }, |
| }, |
| }; |
| </script> |
| <style lang="scss" scoped> |
| @import './trace.scss'; |
| .trace-item.level0 { |
| color: #448dfe; |
| &:hover { |
| background: rgba(0, 0, 0, 0.04); |
| color: #448dfe; |
| } |
| &::before { |
| position: absolute; |
| content: ''; |
| width: 5px; |
| height: 100%; |
| background: #448dfe; |
| left: 0; |
| } |
| } |
| |
| .trace-item { |
| display: flex; |
| position: relative; |
| cursor: pointer; |
| } |
| .trace-item.selected { |
| background: rgba(0, 0, 0, 0.04); |
| } |
| |
| .trace-item:not(.level0):hover { |
| background: rgba(0, 0, 0, 0.04); |
| } |
| |
| .trace-item > div { |
| padding: 0 5px; |
| border: 1px solid transparent; |
| border-right: 1px dotted silver; |
| overflow: hidden; |
| line-height: 30px; |
| overflow: hidden; |
| text-overflow: ellipsis; |
| white-space: nowrap; |
| } |
| .trace-item > div.method { |
| padding-left: 10px; |
| } |
| .trace-item div.exec-percent { |
| width: 10%; |
| padding-left: 8px; |
| padding-right: 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> |