From 1fde7188f2c4916133b421bfe69fb5553ecaa2ea Mon Sep 17 00:00:00 2001 From: Fine Date: Mon, 29 Jan 2024 18:27:32 +0800 Subject: [PATCH] fix: trace --- src/hooks/useDashboardsSession.ts | 7 +- src/store/modules/trace.ts | 139 +++++++++++++++++- .../related/log/LogTable/LogService.vue | 1 + .../dashboard/related/trace/TraceList.vue | 3 +- .../trace/components/D3Graph/Index.vue | 98 ++++++------ .../trace/components/D3Graph/SpanDetail.vue | 38 ++++- 6 files changed, 239 insertions(+), 47 deletions(-) diff --git a/src/hooks/useDashboardsSession.ts b/src/hooks/useDashboardsSession.ts index a97d7c33..f3e26bf3 100644 --- a/src/hooks/useDashboardsSession.ts +++ b/src/hooks/useDashboardsSession.ts @@ -16,7 +16,7 @@ */ import { ElMessage } from "element-plus"; import { useDashboardStore } from "@/store/modules/dashboard"; -import type { LayoutConfig } from "@/types/dashboard"; +import type { LayoutConfig, DashboardItem } from "@/types/dashboard"; import { ConfigFieldTypes } from "@/views/dashboard/data"; export default function getDashboard(param?: { name?: string; layer: string; entity: string }, t?: string) { @@ -24,7 +24,7 @@ export default function getDashboard(param?: { name?: string; layer: string; ent const dashboardStore = useDashboardStore(); const opt = param || dashboardStore.currentDashboard; const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]"); - let dashboard; + let dashboard: Nullable; if (type === ConfigFieldTypes.NAME) { dashboard = list.find( (d: { name: string; layer: string; entity: string }) => @@ -62,6 +62,9 @@ export default function getDashboard(param?: { name?: string; layer: string; ent filters, }; dashboardStore.setWidget(item); + if (widget.id === sourceId) { + return; + } const targetTabIndex = (widget.id || "").split("-"); const sourceTabindex = (sourceId || "").split("-") || []; let container: Nullable; diff --git a/src/store/modules/trace.ts b/src/store/modules/trace.ts index 0b860130..b4b5f0cb 100644 --- a/src/store/modules/trace.ts +++ b/src/store/modules/trace.ts @@ -167,7 +167,144 @@ export const traceStore = defineStore({ if (res.data.errors) { return res.data; } - const data = res.data.data.trace.spans; + const resp = { + data: { + trace: { + spans: [ + { + traceId: "d013fdb11b56417a9997db9d56722ce2.57.17056716790540001", + segmentId: "d013fdb11b56417a9997db9d56722ce2.57.17056716790540000", + spanId: 0, + parentSpanId: -1, + refs: [], + serviceCode: "rmq5-grpc-A-scenario", + serviceInstanceName: "3d4a5d93c2af47838948691e07c502e6@198.18.0.1", + startTime: 1705671679055, + endTime: 1705671679135, + endpointName: "GET:/case/rocketmq-5-grpc-scenario", + type: "Entry", + peer: "", + component: "SpringMVC", + isError: false, + layer: "Http", + tags: [ + { + key: "url", + value: "http://127.0.0.1:8080/rocketmq-5-grpc-scenario/case/rocketmq-5-grpc-scenario", + }, + { + key: "http.method", + value: "GET", + }, + { + key: "http.status_code", + value: "200", + }, + ], + logs: [], + attachedEvents: [], + }, + { + traceId: "d013fdb11b56417a9997db9d56722ce2.57.17056716790540001", + segmentId: "d013fdb11b56417a9997db9d56722ce2.57.17056716790540000", + spanId: 1, + parentSpanId: 0, + refs: [], + serviceCode: "rmq5-grpc-A-scenario", + serviceInstanceName: "3d4a5d93c2af47838948691e07c502e6@198.18.0.1", + startTime: 1705671679057, + endTime: 1705671679133, + endpointName: "RocketMQ/ConsumerAsyncTopicTest/Producer", + type: "Exit", + peer: "123.56.194.74:8081", + component: "rocketMQ-producer", + isError: false, + layer: "MQ", + tags: [ + { + key: "mq.broker", + value: "123.56.194.74:8081", + }, + { + key: "mq.topic", + value: "ConsumerAsyncTopicTest", + }, + { + key: "mq.message.keys", + value: "e8029111-fa26-4738-a59f-2d4dab0b2ffe", + }, + { + key: "mq.message.tags", + value: "Tag:async:consumer", + }, + { + key: "mq.message.id", + value: "01ACDE480011221E0005BC15FF00000003", + }, + ], + logs: [], + attachedEvents: [], + }, + { + traceId: "d013fdb11b56417a9997db9d56722ce2.57.17056716790540001", + segmentId: "1c116740e8dd41f9af3577a03c969a4b.53.17056716950020000", + spanId: 0, + parentSpanId: -1, + refs: [ + { + traceId: "d013fdb11b56417a9997db9d56722ce2.57.17056716790540001", + parentSegmentId: "d013fdb11b56417a9997db9d56722ce2.57.17056716790540000", + parentSpanId: 1, + type: "CROSS_PROCESS", + }, + { + traceId: "d013fdb11b56417a9997db9d56722ce2.55.17056716721260001", + parentSegmentId: "d013fdb11b56417a9997db9d56722ce2.55.17056716721250000", + parentSpanId: 1, + type: "CROSS_PROCESS", + }, + ], + serviceCode: "rmq5-grpc-B-scenario", + serviceInstanceName: "88429d7fb3434b928dc39f41c0b7c4c6@198.18.0.1", + startTime: 1705671695004, + endTime: 1705671696483, + endpointName: "RocketMQ/ConsumerAsyncTopicTest/Consumer", + type: "Entry", + peer: "123.56.194.74:8081", + component: "rocketMQ-consumer", + isError: false, + layer: "MQ", + tags: [ + { + key: "mq.topic", + value: "ConsumerAsyncTopicTest", + }, + { + key: "mq.broker", + value: "123.56.194.74:8081", + }, + { + key: "transmission.latency", + value: "17345", + }, + { + key: "transmission.latency", + value: "24263", + }, + { + key: "http.status_code", + value: "200", + }, + ], + logs: [], + attachedEvents: [], + }, + ], + }, + }, + }; + // const data = res.data.data.trace.spans; + const data = resp.data.trace.spans; this.setTraceSpans(data || []); return res.data; }, diff --git a/src/views/dashboard/related/log/LogTable/LogService.vue b/src/views/dashboard/related/log/LogTable/LogService.vue index 137d9f19..256ced31 100644 --- a/src/views/dashboard/related/log/LogTable/LogService.vue +++ b/src/views/dashboard/related/log/LogTable/LogService.vue @@ -71,6 +71,7 @@ limitations under the License. --> emit("select", props.data); } function linkTrace(id: string) { + console.log(options); const { associationWidget } = getDashboard(dashboardStore.currentDashboard); associationWidget( (options.id as any) || "", diff --git a/src/views/dashboard/related/trace/TraceList.vue b/src/views/dashboard/related/trace/TraceList.vue index 6b2ca76a..ba2991a8 100644 --- a/src/views/dashboard/related/trace/TraceList.vue +++ b/src/views/dashboard/related/trace/TraceList.vue @@ -227,7 +227,8 @@ limitations under the License. --> .no-data { padding-top: 50px; - width: 100%; + width: 280px; text-align: center; + height: 100px; } diff --git a/src/views/dashboard/related/trace/components/D3Graph/Index.vue b/src/views/dashboard/related/trace/components/D3Graph/Index.vue index c96c04b7..7886d57d 100644 --- a/src/views/dashboard/related/trace/components/D3Graph/Index.vue +++ b/src/views/dashboard/related/trace/components/D3Graph/Index.vue @@ -139,28 +139,61 @@ limitations under the License. --> } segmentHeaders.forEach((span: Span) => { if (span.refs.length) { + let exit = 0; span.refs.forEach((ref) => { - const index = props.data.findIndex( + const i = props.data.findIndex( (i: Recordable) => ref.parentSegmentId === i.segmentId && ref.parentSpanId === i.spanId, ); - if (index === -1) { - // create a known broken node. - const i = ref.parentSpanId; - const fixSpanKeyContent = { + if (i > -1) { + exit = 1; + } + }); + + if (!exit) { + const ref = span.refs[0]; + // create a known broken node. + const i = ref.parentSpanId; + const fixSpanKeyContent = { + traceId: ref.traceId, + segmentId: ref.parentSegmentId, + spanId: i, + parentSpanId: i > -1 ? 0 : -1, + }; + if (!_.find(fixSpans, fixSpanKeyContent)) { + fixSpans.push({ + ...fixSpanKeyContent, + refs: [], + endpointName: `VNode: ${ref.parentSegmentId}`, + serviceCode: "VirtualNode", + type: `[Broken] ${ref.type}`, + peer: "", + component: `VirtualNode: #${i}`, + isError: true, + isBroken: true, + layer: "Broken", + tags: [], + logs: [], + startTime: 0, + endTime: 0, + }); + } + // if root broken node is not exist, create a root broken node. + if (fixSpanKeyContent.parentSpanId > -1) { + const fixRootSpanKeyContent = { traceId: ref.traceId, segmentId: ref.parentSegmentId, - spanId: i, - parentSpanId: i > -1 ? 0 : -1, + spanId: 0, + parentSpanId: -1, }; - if (!_.find(fixSpans, fixSpanKeyContent)) { + if (!_.find(fixSpans, fixRootSpanKeyContent)) { fixSpans.push({ - ...fixSpanKeyContent, + ...fixRootSpanKeyContent, refs: [], endpointName: `VNode: ${ref.parentSegmentId}`, serviceCode: "VirtualNode", type: `[Broken] ${ref.type}`, peer: "", - component: `VirtualNode: #${i}`, + component: `VirtualNode: #0`, isError: true, isBroken: true, layer: "Broken", @@ -170,44 +203,27 @@ limitations under the License. --> endTime: 0, }); } - // if root broken node is not exist, create a root broken node. - if (fixSpanKeyContent.parentSpanId > -1) { - const fixRootSpanKeyContent = { - traceId: ref.traceId, - segmentId: ref.parentSegmentId, - spanId: 0, - parentSpanId: -1, - }; - if (!_.find(fixSpans, fixRootSpanKeyContent)) { - fixSpans.push({ - ...fixRootSpanKeyContent, - refs: [], - endpointName: `VNode: ${ref.parentSegmentId}`, - serviceCode: "VirtualNode", - type: `[Broken] ${ref.type}`, - peer: "", - component: `VirtualNode: #0`, - isError: true, - isBroken: true, - layer: "Broken", - tags: [], - logs: [], - startTime: 0, - endTime: 0, - }); - } - } } - }); + } } }); [...fixSpans, ...props.data].forEach((i) => { + if (i.refs.length) { + const item = i.refs.find((d) => d.traceId === i.traceId); + if (item) { + i = { + ...i, + ...item, + segmentId: item.parentSegmentId, + spanId: -2, + }; + } + } i.label = i.endpointName || "no operation name"; i.children = []; - if (segmentGroup[i.segmentId] === undefined) { + if (!segmentGroup[i.segmentId]) { segmentIdGroup.push(i.segmentId); - segmentGroup[i.segmentId] = []; - segmentGroup[i.segmentId].push(i); + segmentGroup[i.segmentId] = [i]; } else { segmentGroup[i.segmentId].push(i); } diff --git a/src/views/dashboard/related/trace/components/D3Graph/SpanDetail.vue b/src/views/dashboard/related/trace/components/D3Graph/SpanDetail.vue index a9d54711..3d66bc0c 100644 --- a/src/views/dashboard/related/trace/components/D3Graph/SpanDetail.vue +++ b/src/views/dashboard/related/trace/components/D3Graph/SpanDetail.vue @@ -42,6 +42,13 @@ limitations under the License. --> {{ t("isError") }}: {{ currentSpan.isError }} +
{{ t("traceID") }}.
+
+ No.{{ index + 1 }} + + {{ item.traceId }} + +
{{ t("tags") }}.
{{ i.key }}: @@ -127,7 +134,7 @@ limitations under the License. -->