This is an automated email from the ASF dual-hosted git repository.
qiuxiafan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-rocketbot-ui.git
The following commit(s) were added to refs/heads/master by this push:
new 70ad10c Feat: implement viewing logs on trace page (#420)
70ad10c is described below
commit 70ad10c08e7eb7d877e33e993296775609839de4
Author: Qiuxia Fan <[email protected]>
AuthorDate: Wed Jan 27 15:55:08 2021 +0800
Feat: implement viewing logs on trace page (#420)
* feat: add sidebox
* feat: implement trace logs
* feat: implement turning page
* fix: update span logs
* feat: query trace logs
* fix: type
* fix: logs
* fix: type
* feat: update view logs
* fix: update sidebox
* fix:typo
---
src/assets/lang/en.ts | 2 +
src/assets/lang/zh.ts | 2 +
src/store/modules/trace/index.ts | 25 ++++
src/store/mutation-types.ts | 4 +
.../components/common/trace-detail-chart-table.vue | 59 +-------
src/views/components/log/log-service-detail.vue | 16 +--
.../components/log/log-table/log-service-item.vue | 6 +-
src/views/components/log/log-table/log-table.vue | 5 +-
.../components/trace/trace-detail-chart-list.vue | 89 ++----------
.../components/trace/trace-detail-chart-tree.vue | 58 +-------
src/views/components/trace/trace-detail.vue | 54 +++++++-
src/views/components/trace/trace-search.vue | 27 +++-
src/views/components/trace/trace-span-logs.vue | 152 +++++++++++++++++++++
src/views/components/trace/trace-table.vue | 5 +-
14 files changed, 290 insertions(+), 214 deletions(-)
diff --git a/src/assets/lang/en.ts b/src/assets/lang/en.ts
index c7201e5..b9df4b0 100644
--- a/src/assets/lang/en.ts
+++ b/src/assets/lang/en.ts
@@ -186,6 +186,7 @@ const m = {
errorPage: 'Error Page',
category: 'Category',
grade: 'Grade',
+ relatedTraceLogs: 'Related Logs',
setConditions: 'More Conditions',
metricName: 'Metric Name',
keywordsOfContent: 'Keys Of Content',
@@ -194,6 +195,7 @@ const m = {
isError: 'Error',
contentType: 'Content Type',
content: 'Content',
+ viewLogs: 'View Logs',
};
export default m;
diff --git a/src/assets/lang/zh.ts b/src/assets/lang/zh.ts
index e696d0f..b0b74bd 100644
--- a/src/assets/lang/zh.ts
+++ b/src/assets/lang/zh.ts
@@ -185,6 +185,7 @@ const m = {
errorPage: '错误页面',
category: '类别',
grade: '等级',
+ relatedTraceLogs: '相关的日志',
setConditions: '更多条件',
metricName: '指标名称',
keywordsOfContent: '内容关键词',
@@ -193,6 +194,7 @@ const m = {
isError: '错误',
contentType: '内容类型',
content: '内容',
+ viewLogs: '查看日志',
};
export default m;
diff --git a/src/store/modules/trace/index.ts b/src/store/modules/trace/index.ts
index a3feb8d..3583dc8 100644
--- a/src/store/modules/trace/index.ts
+++ b/src/store/modules/trace/index.ts
@@ -30,6 +30,8 @@ export interface State {
traceTotal: number;
traceSpans: Span[];
currentTrace: Trace;
+ traceSpanLogs: any[];
+ traceSpanLogsTotal: number;
}
const initState: State = {
@@ -50,6 +52,8 @@ const initState: State = {
start: '',
traceIds: [],
},
+ traceSpanLogs: [],
+ traceSpanLogsTotal: 0,
};
// mutations
@@ -104,6 +108,12 @@ const mutations: MutationTree<State> = {
traceIds: [],
};
},
+ [types.SET_TRACE_SPAN_LOGS](state: State, logs: any[]) {
+ state.traceSpanLogs = logs;
+ },
+ [types.SET_TRACE_SPAN_LOGS_TOTAL](state: State, data: number) {
+ state.traceSpanLogsTotal = data;
+ },
};
// actions
@@ -149,6 +159,21 @@ const actions: ActionTree<State, any> = {
context.commit(types.SET_TRACE_SPANS, res.data.data.trace.spans);
});
},
+ GET_TRACE_SPAN_LOGS(context: { commit: Commit }, params: any) {
+ return graph
+ .query('queryServiceLogs')
+ .params(params)
+ .then((res: AxiosResponse<any>) => {
+ if (res.data && res.data.errors) {
+ context.commit('SET_TRACE_SPAN_LOGS', []);
+ context.commit('SET_TRACE_SPAN_LOGS_TOTAL', 0);
+
+ return;
+ }
+ context.commit('SET_TRACE_SPAN_LOGS', res.data.data.queryLogs.logs);
+ context.commit('SET_TRACE_SPAN_LOGS_TOTAL',
res.data.data.queryLogs.total);
+ });
+ },
};
export default {
diff --git a/src/store/mutation-types.ts b/src/store/mutation-types.ts
index 6846c00..3957d83 100644
--- a/src/store/mutation-types.ts
+++ b/src/store/mutation-types.ts
@@ -68,6 +68,10 @@ export const SET_CURRENT_TRACE = 'SET_CURRENT_TRACE';
export const SET_TRACE_FORM = 'SET_TRACE_FORM';
export const SET_TRACE_FORM_ITEM = 'SET_TRACE_FORM_ITEM';
export const SET_DEFAULT_EMPTY_TRACE = 'SET_DEFAULT_EMPTY_TRACE';
+export const SET_TRACE_LOGS = 'SET_TRACE_LOGS';
+export const SET_TRACE_LOGS_TOTAL = 'SET_TRACE_LOGS_TOTAL';
+export const SET_TRACE_SPAN_LOGS_TOTAL = 'SET_TRACE_SPAN_LOGS_TOTAL';
+export const SET_TRACE_SPAN_LOGS = 'SET_TRACE_SPAN_LOGS';
// topo
export const SET_TOPO = 'SET_TOPO';
diff --git a/src/views/components/common/trace-detail-chart-table.vue
b/src/views/components/common/trace-detail-chart-table.vue
index 52c8048..3776c49 100644
--- a/src/views/components/common/trace-detail-chart-table.vue
+++ b/src/views/components/common/trace-detail-chart-table.vue
@@ -23,62 +23,7 @@ limitations under the License. -->
<div class="trace-tips" v-if="!tableData.length">{{ $t('noData') }}</div>
</TraceContainer>
<rk-sidebox :width="'50%'" :show.sync="showDetail" :title="$t('spanInfo')">
- <div class="rk-trace-detail">
- <h5 class="mb-15">{{ $t('tags') }}.</h5>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('service') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.serviceCode }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('endpoint') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.label }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('spanType') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.type }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('component') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.component }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">Peer:</span><span class="g-sm-8 wba">{{
this.currentSpan.peer || 'No Peer' }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('error') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.isError }}</span>
- </div>
- <div class="mb-10 clear" v-for="i in this.currentSpan.tags"
:key="i.key">
- <span class="g-sm-4 grey">{{ i.key }}:</span>
- <span class="g-sm-8 wba">
- {{ i.value }}
- <svg v-if="i.key === 'db.statement'" class="icon vm grey
link-hover cp ml-5" @click="copy(i.value)">
- <use xlink:href="#review-list"></use>
- </svg>
- </span>
- </div>
- <h5 class="mb-10" v-if="this.currentSpan.logs"
v-show="this.currentSpan.logs.length">{{ $t('logs') }}.</h5>
- <div v-for="(i, index) in this.currentSpan.logs" :key="index">
- <div class="mb-10 sm">
- <span class="mr-10">{{ $t('time') }}:</span>
- <span class="grey">{{ i.time | dateformat }}</span>
- </div>
- <div class="mb-15 clear" v-for="(_i, _index) in i.data"
:key="_index">
- <div class="mb-10">
- {{ _i.key }}:<span
- v-if="_i.key === 'stack'"
- class="r rk-sidebox-magnify"
- @click="showCurrentSpanDetail(_i.key, _i.value)"
- >
- <svg class="icon">
- <use xlink:href="#magnify"></use>
- </svg>
- </span>
- </div>
- <pre class="pl-15 mt-0 mb-0 sm oa">{{ _i.value }}</pre>
- </div>
- </div>
- </div>
+ <TraceSpanLogs :currentSpan="currentSpan" />
</rk-sidebox>
</div>
</template>
@@ -97,11 +42,13 @@ limitations under the License. -->
import copy from '@/utils/copy';
import TraceContainer from './trace-chart-table/trace-container';
import _ from 'lodash';
+ import TraceSpanLogs from '../trace/trace-span-logs.vue';
/* eslint-disable */
/* tslint:disable */
export default {
components: {
TraceContainer,
+ TraceSpanLogs,
},
props: ['data', 'traceId', 'showBtnDetail', 'HeaderType'],
watch: {
diff --git a/src/views/components/log/log-service-detail.vue
b/src/views/components/log/log-service-detail.vue
index f16c944..6a6a7b1 100644
--- a/src/views/components/log/log-service-detail.vue
+++ b/src/views/components/log/log-service-detail.vue
@@ -19,7 +19,7 @@ limitations under the License. -->
<use xlink:href="#spinner"></use>
</svg>
</div>
- <LogTable :tableData="data" :type="`service`">
+ <LogTable :tableData="data" :type="`service`" :noLink="noLink">
<div class="log-tips" v-if="!data.length">{{ $t('noData') }}</div>
</LogTable>
<rk-sidebox :width="'800px'" :show.sync="showDetail"
:title="$t('logDetail')">
@@ -51,24 +51,24 @@ limitations under the License. -->
components: { LogTable },
})
export default class LogServiceDetail extends Vue {
- @State('rocketLog') private logState: any;
@Prop() private data: any;
@Prop() private loading!: true;
@Prop() private showBtnDetail: any;
+ @Prop() private noLink!: boolean;
private columns = ServiceLogDetail;
- private showDetail = false;
+ private showDetail: boolean = false;
private list = [];
private currentLog: any = {};
- private logContent: any = '';
- private logTags: any = '';
- private formatJson = formatJson;
+ private logContent: string = '';
+ private logTags: string = '';
+
private created() {
this.$eventBus.$on('HANDLE-SELECT-LOG', this, this.handleSelectLog);
}
- private handleSelectLog(data: any) {
+ private handleSelectLog(data: any[]) {
this.currentLog = data;
- this.logTags = this.currentLog.tags.map((d: any) => {
+ this.logTags = this.currentLog.tags.map((d: { key: string; value: string
}) => {
return `${d.key} = ${d.value}`;
});
if (this.currentLog.contentType === 'JSON') {
diff --git a/src/views/components/log/log-table/log-service-item.vue
b/src/views/components/log/log-table/log-service-item.vue
index a24f63f..278d00d 100644
--- a/src/views/components/log/log-table/log-service-item.vue
+++ b/src/views/components/log/log-table/log-service-item.vue
@@ -19,7 +19,10 @@ limitations under the License. -->
<span v-if="item.label === 'timestamp'">
{{ data.time | dateformat }}
</span>
- <router-link v-if="item.label === 'traceId'" :to="{ name: 'trace',
query: { traceid: data[item.label] } }">
+ <router-link
+ v-if="item.label === 'traceId' && !noLink"
+ :to="{ name: 'trace', query: { traceid: data[item.label] } }"
+ >
<span>{{ data[item.label] }}</span>
</router-link>
<span v-else>{{ data[item.label] }}</span>
@@ -33,6 +36,7 @@ limitations under the License. -->
@Component
export default class ServiceItem extends Vue {
@Prop() private data: any;
+ @Prop() private noLink!: any;
private columns = ServiceLogConstants;
private showSelectSpan() {
this.$eventBus.$emit('HANDLE-SELECT-LOG', this.data);
diff --git a/src/views/components/log/log-table/log-table.vue
b/src/views/components/log/log-table/log-table.vue
index 8795e88..9708650 100644
--- a/src/views/components/log/log-table/log-table.vue
+++ b/src/views/components/log/log-table/log-table.vue
@@ -32,7 +32,8 @@ limitations under the License. -->
<BrowserItem :method="method" v-for="(item, index) in tableData"
:data="item" :key="'key' + index" />
</div>
<div v-else>
- <ServiceItem v-for="(item, index) in tableData" :data="item" :key="'key'
+ index" />
+ "
+ <ServiceItem v-for="(item, index) in tableData" :data="item" :key="'key'
+ index" :noLink="noLink" />
</div>
<slot></slot>
</div>
@@ -45,7 +46,7 @@ limitations under the License. -->
export default {
components: { ServiceItem, BrowserItem },
name: 'LogContainer',
- props: ['type', 'tableData'],
+ props: ['type', 'tableData', 'noLink'],
data() {
return {
method: 380,
diff --git a/src/views/components/trace/trace-detail-chart-list.vue
b/src/views/components/trace/trace-detail-chart-list.vue
index 286f4b3..d540cd3 100644
--- a/src/views/components/trace/trace-detail-chart-list.vue
+++ b/src/views/components/trace/trace-detail-chart-list.vue
@@ -29,61 +29,7 @@ limitations under the License. -->
</transition-group>
<a class="rk-btn r vm tc" @click="downloadTrace">{{ $t('exportImage')
}}</a>
<rk-sidebox :width="'50%'" :show.sync="showDetail" :title="$t('spanInfo')">
- <div class="rk-trace-detail">
- <h5 class="mb-15">{{ $t('tags') }}.</h5>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('service') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.serviceCode }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('endpoint') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.label }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('spanType') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.type }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('component') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.component }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">Peer:</span><span class="g-sm-8 wba">{{
this.currentSpan.peer || 'No Peer' }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('error') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.isError }}</span>
- </div>
- <div class="mb-10 clear" v-for="i in this.currentSpan.tags"
:key="i.key">
- <span class="g-sm-4 grey">{{ i.key }}:</span>
- <span class="g-sm-8 wba">
- {{ i.value }}
- <svg v-if="i.key === 'db.statement'" class="icon vm grey
link-hover cp ml-5" @click="copy(i.value)">
- <use xlink:href="#review-list"></use>
- </svg>
- </span>
- </div>
- <h5 class="mb-10" v-if="this.currentSpan.logs"
v-show="this.currentSpan.logs.length">{{ $t('logs') }}.</h5>
- <div v-for="(i, index) in this.currentSpan.logs" :key="index">
- <div class="mb-10 sm">
- <span class="mr-10">{{ $t('time') }}:</span><span class="grey">{{
i.time | dateformat }}</span>
- </div>
- <div class="mb-15 clear" v-for="(_i, _index) in i.data"
:key="_index">
- <div class="mb-10">
- {{ _i.key }}:<span
- v-if="_i.key === 'stack'"
- class="r rk-sidebox-magnify"
- @click="showCurrentSpanDetail(_i.key, _i.value)"
- >
- <svg class="icon">
- <use xlink:href="#magnify"></use>
- </svg>
- </span>
- </div>
- <pre class="pl-15 mt-0 mb-0 sm oa">{{ _i.value }}</pre>
- </div>
- </div>
- </div>
+ <TraceSpanLogs :currentSpan="currentSpan" />
</rk-sidebox>
<div class="trace-list">
<div ref="traceList"></div>
@@ -95,7 +41,9 @@ limitations under the License. -->
import * as d3 from 'd3';
import Trace from './d3-trace';
import _ from 'lodash';
+ import TraceSpanLogs from './trace-span-logs.vue';
export default {
+ components: {TraceSpanLogs},
props: ['data', 'traceId'],
data() {
return {
@@ -105,6 +53,7 @@ limitations under the License. -->
currentSpan: [],
loading: true,
fixSpansSize: 0,
+ showRelatedLogs: false,
};
},
watch: {
@@ -134,7 +83,6 @@ limitations under the License. -->
// this.computedScale();
},
methods: {
- copy,
handleSelectSpan(i) {
this.currentSpan = i.data;
this.showDetail = true;
@@ -323,27 +271,6 @@ limitations under the License. -->
d.children.forEach((i) => this.collapse(i));
}
},
- showCurrentSpanDetail(title, text) {
- const textLineNumber = text.split('\n').length;
- let textHeight = textLineNumber * 20.2 + 10;
- const tmpHeight = window.innerHeight * 0.9;
- textHeight = textHeight >= tmpHeight ? tmpHeight : textHeight;
- this.$modal.show('dialog', {
- title,
- text: `<div style="height:${textHeight}px">${text}</div>`,
- buttons: [
- {
- title: 'Copy',
- handler: () => {
- this.copy(text);
- },
- },
- {
- title: 'Close',
- },
- ],
- });
- },
downloadTrace() {
const serializer = new XMLSerializer();
const svgNode = d3.select('.trace-list-dowanload').node();
@@ -413,4 +340,12 @@ limitations under the License. -->
overflow: auto;
font-family: monospace;
}
+ .rk-popup-btn {
+ color: #fff;
+ padding: 10px 9px;
+ border-radius: 4px;
+ margin-top: 40px;
+ width: 100%;
+ text-align: center;
+ }
</style>
diff --git a/src/views/components/trace/trace-detail-chart-tree.vue
b/src/views/components/trace/trace-detail-chart-tree.vue
index 8f0601c..0659d7e 100644
--- a/src/views/components/trace/trace-detail-chart-tree.vue
+++ b/src/views/components/trace/trace-detail-chart-tree.vue
@@ -28,61 +28,7 @@ limitations under the License. -->
<a class="trace-tree-btn mr-10" @click="tree.getTopChild()">Top 5 of
children</a>
</div>
<rk-sidebox :width="'50%'" :show.sync="showDetail" :title="$t('spanInfo')">
- <div class="rk-trace-detail">
- <h5 class="mb-15">{{ $t('tags') }}.</h5>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('service') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.serviceCode }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('endpoint') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.label }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('spanType') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.type }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('component') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.component }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">Peer:</span><span class="g-sm-8 wba">{{
this.currentSpan.peer || 'No Peer' }}</span>
- </div>
- <div class="mb-10 clear">
- <span class="g-sm-4 grey">{{ $t('error') }}:</span
- ><span class="g-sm-8 wba">{{ this.currentSpan.isError }}</span>
- </div>
- <div class="mb-10 clear" v-for="i in this.currentSpan.tags"
:key="i.key">
- <span class="g-sm-4 grey">{{ i.key }}:</span>
- <span class="g-sm-8 wba">
- {{ i.value }}
- <svg v-if="i.key === 'db.statement'" class="icon vm grey
link-hover cp ml-5" @click="copy(i.value)">
- <use xlink:href="#review-list"></use>
- </svg>
- </span>
- </div>
- <h5 class="mb-10" v-if="this.currentSpan.logs"
v-show="this.currentSpan.logs.length">{{ $t('logs') }}.</h5>
- <div v-for="(i, index) in this.currentSpan.logs" :key="index">
- <div class="mb-10 sm">
- <span class="mr-10">{{ $t('time') }}:</span><span class="grey">{{
i.time | dateformat }}</span>
- </div>
- <div class="mb-15 clear" v-for="(_i, _index) in i.data"
:key="_index">
- <div class="mb-10">
- {{ _i.key }}:<span
- v-if="_i.key === 'stack'"
- class="r rk-sidebox-magnify"
- @click="showCurrentSpanDetail(_i.key, _i.value)"
- >
- <svg class="icon">
- <use xlink:href="#magnify"></use>
- </svg>
- </span>
- </div>
- <pre class="pl-15 mt-0 mb-0 sm oa">{{ _i.value }}</pre>
- </div>
- </div>
- </div>
+ <TraceSpanLogs :currentSpan="currentSpan" />
</rk-sidebox>
<div class="trace-tree" style="height:100%">
<div class="trace-tree-inner" ref="traceTree"></div>
@@ -94,9 +40,11 @@ limitations under the License. -->
import * as d3 from 'd3';
import Tree from './d3-trace-tree';
import _ from 'lodash';
+ import TraceSpanLogs from './trace-span-logs.vue';
/* eslint-disable */
/* tslint:disable */
export default {
+ components: {TraceSpanLogs},
props: ['data', 'traceId'],
data(){
return {
diff --git a/src/views/components/trace/trace-detail.vue
b/src/views/components/trace/trace-detail.vue
index 496aaff..bda492e 100644
--- a/src/views/components/trace/trace-detail.vue
+++ b/src/views/components/trace/trace-detail.vue
@@ -14,15 +14,25 @@ See the License for the specific language governing
permissions and
limitations under the License. -->
<template>
<div class="rk-trace-detail flex-v">
+ <rk-sidebox class="rk-log-box" :width="'100%'" :show.sync="showTraceLogs"
:title="$t('relatedTraceLogs')">
+ <RkPage
+ :currentSize="pageSize"
+ :currentPage="pageNum"
+ @changePage="turnLogsPage"
+ :total="rocketTrace.traceLogsTotal"
+ />
+ <LogTable :tableData="rocketTrace.traceSpanLogs || []" :type="`service`"
:noLink="true">
+ <div class="log-tips" v-if="!rocketTrace.traceSpanLogs.length">{{
$t('noData') }}</div>
+ </LogTable>
+ </rk-sidebox>
<div class="rk-trace-detail-wrapper clear" v-if="current.endpointNames">
<h5 class="mb-5 mt-0">
- <svg v-if="current.isError" class="icon red vm mr-5 sm">
- <use xlink:href="#clear"></use>
- </svg>
+ <rk-icon icon="clear" v-if="current.isError" class="red mr-5 sm" />
<span class="vm">{{ current.endpointNames[0] }}</span>
+ <div class="rk-trace-log-btn bg-blue r mr-10"
@click="searchTraceLogs">{{ $t('viewLogs') }}</div>
</h5>
<div class="mb-5 blue sm">
- <select class="rk-trace-detail-ids" @change="GET_TRACE_SPANS({
traceId: i })">
+ <select class="rk-trace-detail-ids" @change="changeTraceId(i)">
<option v-for="i in current.traceIds" :value="i" :key="i">{{ i
}}</option>
</select>
<svg class="icon vm grey link-hover cp ml-5"
@click="handleClick(current.traceIds)">
@@ -89,22 +99,31 @@ limitations under the License. -->
import { Trace, Span } from '@/types/trace';
import { Action, State } from 'vuex-class';
import copy from '@/utils/copy';
+ import { State as traceState } from '@/store/modules/trace/index';
+ import LogTable from '../log/log-table/log-table.vue';
@Component({
components: {
TraceDetailChartList,
TraceDetailChartTree,
TraceDetailChartTable,
+ LogTable,
},
})
export default class TraceDetail extends Vue {
- @State('rocketbot') private rocketbot: any;
+ @State('rocketTrace') private rocketTrace!: traceState;
@Action('rocketTrace/GET_TRACE_SPANS') private GET_TRACE_SPANS: any;
+ @Action('rocketTrace/GET_TRACE_SPAN_LOGS') private GET_TRACE_SPAN_LOGS:
any;
@Prop() private spans!: Span[];
@Prop() private current!: Trace;
private mode: boolean = true;
private displayMode: string = 'list';
- private handleClick(ids: any) {
+ private showTraceLogs: boolean = false;
+ private pageSize: number = 10;
+ private pageNum: number = 1;
+ private traceId: string = '';
+
+ private handleClick(ids: string[]) {
let copyValue = null;
if (ids.length === 1) {
copyValue = ids[0];
@@ -113,6 +132,29 @@ limitations under the License. -->
}
copy(copyValue);
}
+
+ private changeTraceId(i: string) {
+ this.traceId = i;
+ this.GET_TRACE_SPANS({ traceId: i });
+ }
+
+ private turnLogsPage(pageNum: number) {
+ this.pageNum = pageNum;
+ this.searchTraceLogs();
+ }
+
+ private searchTraceLogs() {
+ this.showTraceLogs = true;
+ this.GET_TRACE_SPAN_LOGS({
+ condition: {
+ state: 'ALL',
+ relatedTrace: {
+ traceId: this.traceId || this.current.traceIds[0],
+ },
+ paging: { pageNum: this.pageNum, pageSize: this.pageSize, needTotal:
true },
+ },
+ });
+ }
}
</script>
diff --git a/src/views/components/trace/trace-search.vue
b/src/views/components/trace/trace-search.vue
index 709ee7b..0b3354f 100644
--- a/src/views/components/trace/trace-search.vue
+++ b/src/views/components/trace/trace-search.vue
@@ -114,11 +114,14 @@ limitations under the License. -->
import { Component, Vue, Watch } from 'vue-property-decorator';
import { Action, Getter, Mutation, State } from 'vuex-class';
import TraceSelect from '../common/trace-select.vue';
+ import LogTable from '../log/log-table/log-table.vue';
+ import { State as traceState } from '@/store/modules/trace/index';
+ import { State as globalState } from '@/store/modules/global/index';
- @Component({ components: { TraceSelect } })
+ @Component({ components: { TraceSelect, LogTable } })
export default class TraceSearch extends Vue {
- @State('rocketbot') private rocketbotGlobal: any;
- @State('rocketTrace') private rocketTrace: any;
+ @State('rocketbot') private rocketbotGlobal!: globalState;
+ @State('rocketTrace') private rocketTrace!: traceState;
@Getter('durationTime') private durationTime: any;
@Getter('duration') private duration: any;
@Action('RESET_DURATION') private RESET_DURATION: any;
@@ -158,6 +161,7 @@ limitations under the License. -->
});
}
}
+
private dateFormat(date: Date, step: string) {
const year = date.getFullYear();
const monthTemp = date.getMonth() + 1;
@@ -232,11 +236,11 @@ limitations under the License. -->
queryDuration: this.globalTimeFormat([
new Date(
this.time[0].getTime() +
- (parseInt(this.rocketbotGlobal.utc, 10) + new
Date().getTimezoneOffset() / 60) * 3600000,
+ (parseInt(String(this.rocketbotGlobal.utc), 10) + new
Date().getTimezoneOffset() / 60) * 3600000,
),
new Date(
this.time[1].getTime() +
- (parseInt(this.rocketbotGlobal.utc, 10) + new
Date().getTimezoneOffset() / 60) * 3600000,
+ (parseInt(String(this.rocketbotGlobal.utc), 10) + new
Date().getTimezoneOffset() / 60) * 3600000,
),
]),
traceState: this.traceState.key,
@@ -328,6 +332,9 @@ limitations under the License. -->
</script>
<style lang="scss">
+ .rk-log-box {
+ color: #3d444f;
+ }
.rk-trace-search {
flex-shrink: 0;
background-color: #333840;
@@ -388,16 +395,22 @@ limitations under the License. -->
}
}
- .rk-trace-search-btn {
+ .rk-trace-search-btn,
+ .rk-trace-log-btn {
padding: 3px 9px;
background-color: #484b55;
border-radius: 4px;
- margin-top: 12px;
+ color: #eee;
+ font-weight: normal;
+ cursor: pointer;
&.bg-blue {
background-color: #448dfe;
}
}
+ .rk-trace-search-btn {
+ margin-top: 12px;
+ }
.rk-trace-clear-btn {
padding: 3px 9px;
diff --git a/src/views/components/trace/trace-span-logs.vue
b/src/views/components/trace/trace-span-logs.vue
new file mode 100644
index 0000000..0f19df8
--- /dev/null
+++ b/src/views/components/trace/trace-span-logs.vue
@@ -0,0 +1,152 @@
+<!-- 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="rk-trace-detail">
+ <h5 class="mb-15">{{ $t('tags') }}.</h5>
+ <div class="mb-10 clear">
+ <span class="g-sm-4 grey">{{ $t('service') }}:</span>
+ <span class="g-sm-8 wba">{{ this.currentSpan.serviceCode }}</span>
+ </div>
+ <div class="mb-10 clear">
+ <span class="g-sm-4 grey">{{ $t('endpoint') }}:</span>
+ <span class="g-sm-8 wba">{{ this.currentSpan.label }}</span>
+ </div>
+ <div class="mb-10 clear">
+ <span class="g-sm-4 grey">{{ $t('spanType') }}:</span>
+ <span class="g-sm-8 wba">{{ this.currentSpan.type }}</span>
+ </div>
+ <div class="mb-10 clear">
+ <span class="g-sm-4 grey">{{ $t('component') }}:</span>
+ <span class="g-sm-8 wba">{{ this.currentSpan.component }}</span>
+ </div>
+ <div class="mb-10 clear">
+ <span class="g-sm-4 grey">Peer:</span>
+ <span class="g-sm-8 wba">{{ this.currentSpan.peer || 'No Peer'
}}</span>
+ </div>
+ <div class="mb-10 clear">
+ <span class="g-sm-4 grey">{{ $t('error') }}:</span>
+ <span class="g-sm-8 wba">{{ this.currentSpan.isError }}</span>
+ </div>
+ <div class="mb-10 clear" v-for="i in this.currentSpan.tags" :key="i.key">
+ <span class="g-sm-4 grey">{{ i.key }}:</span>
+ <span class="g-sm-8 wba">
+ {{ i.value }}
+ <svg v-if="i.key === 'db.statement'" class="icon vm grey link-hover
cp ml-5" @click="copy(i.value)">
+ <use xlink:href="#review-list"></use>
+ </svg>
+ </span>
+ </div>
+ <h5 class="mb-10" v-if="this.currentSpan.logs"
v-show="this.currentSpan.logs.length">{{ $t('logs') }}.</h5>
+ <div v-for="(i, index) in this.currentSpan.logs" :key="index">
+ <div class="mb-10 sm">
+ <span class="mr-10">{{ $t('time') }}:</span><span class="grey">{{
i.time | dateformat }}</span>
+ </div>
+ <div class="mb-15 clear" v-for="(_i, _index) in i.data" :key="_index">
+ <div class="mb-10">
+ {{ _i.key }}:<span
+ v-if="_i.key === 'stack'"
+ class="r rk-sidebox-magnify"
+ @click="showCurrentSpanDetail(_i.key, _i.value)"
+ >
+ <svg class="icon">
+ <use xlink:href="#magnify"></use>
+ </svg>
+ </span>
+ </div>
+ <pre class="pl-15 mt-0 mb-0 sm oa">{{ _i.value }}</pre>
+ </div>
+ </div>
+ <div @click="getTaceLogs()">
+ <a class="rk-popup-btn bg-blue r">
+ <span class="mr-5 vm">
+ {{ $t('relatedTraceLogs') }}
+ </span>
+ </a>
+ </div>
+ </div>
+ <rk-sidebox :width="'100%'" :show.sync="showRelatedLogs"
:title="$t('relatedTraceLogs')">
+ <div>
+ <RkPage
+ :currentSize="pageSize"
+ :currentPage="pageNum"
+ @changePage="turnPage"
+ :total="rocketTrace.traceSpanLogsTotal"
+ />
+ <LogServiceDetail :data="rocketTrace.traceSpanLogs || []"
:loading="false" :noLink="true" />
+ </div>
+ </rk-sidebox>
+ </div>
+</template>
+<script lang="ts">
+ import { Component, Prop, Vue } from 'vue-property-decorator';
+ import LogServiceDetail from '../log/log-service-detail.vue';
+ import { Action, State } from 'vuex-class';
+ import copy from '@/utils/copy';
+ import { State as traceState } from '@/store/modules/trace/index';
+
+ @Component({
+ components: { LogServiceDetail },
+ })
+ export default class TraceSpanLogs extends Vue {
+ @State('rocketTrace') private rocketTrace!: traceState;
+ @Action('rocketTrace/GET_TRACE_SPAN_LOGS') private GET_TRACE_SPAN_LOGS:
any;
+ @Prop() private currentSpan: any;
+ private showRelatedLogs: boolean = false;
+ private copy = copy;
+ private pageNum: number = 1;
+ private pageSize: number = 10;
+
+ private getTaceLogs() {
+ this.showRelatedLogs = true;
+ this.GET_TRACE_SPAN_LOGS({
+ condition: {
+ state: 'ALL',
+ relatedTrace: {
+ traceId: this.currentSpan.traceId,
+ segmentId: this.currentSpan.segmentId,
+ spanId: this.currentSpan.spanId,
+ },
+ paging: { pageNum: this.pageNum, pageSize: this.pageSize, needTotal:
true },
+ },
+ });
+ }
+ private turnPage(pageNum: number) {
+ this.pageNum = pageNum;
+ this.getTaceLogs();
+ }
+ private showCurrentSpanDetail(title: string, text: string) {
+ const textLineNumber = text.split('\n').length;
+ let textHeight = textLineNumber * 20.2 + 10;
+ const tmpHeight = window.innerHeight * 0.9;
+ textHeight = textHeight >= tmpHeight ? tmpHeight : textHeight;
+ this.$modal.show('dialog', {
+ title,
+ text: `<div style="height:${textHeight}px">${text}</div>`,
+ buttons: [
+ {
+ title: 'Copy',
+ handler: () => {
+ this.copy(text);
+ },
+ },
+ {
+ title: 'Close',
+ },
+ ],
+ });
+ }
+ }
+</script>
diff --git a/src/views/components/trace/trace-table.vue
b/src/views/components/trace/trace-table.vue
index 06af196..e8c1029 100644
--- a/src/views/components/trace/trace-table.vue
+++ b/src/views/components/trace/trace-table.vue
@@ -64,10 +64,11 @@ limitations under the License. -->
<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
import { Action, Getter, Mutation, State } from 'vuex-class';
+ import { State as traceState } from '@/store/modules/trace/index';
+
@Component
export default class TraceTable extends Vue {
- @State('rocketTrace') private rocketTrace: any;
- @State('rocketbot') private rocketbot: any;
+ @State('rocketTrace') private rocketTrace!: traceState;
@Mutation('rocketTrace/SET_TRACE_FORM_ITEM')
private SET_TRACE_FORM_ITEM: any;
@Mutation('rocketTrace/SET_CURRENT_TRACE') private SET_CURRENT_TRACE: any;