From d8be5a0ea21556dfb23d57705867533a1dddc0c1 Mon Sep 17 00:00:00 2001 From: jacovinus Date: Mon, 24 Jul 2023 13:45:17 +0200 Subject: [PATCH] fix: #349 improve traces rendering --- .../components/Traces/mapTracesResponse.ts | 273 ++++++++---------- 1 file changed, 122 insertions(+), 151 deletions(-) diff --git a/packages/main/src/components/DataViews/components/Traces/mapTracesResponse.ts b/packages/main/src/components/DataViews/components/Traces/mapTracesResponse.ts index 336b8144..560e63ed 100644 --- a/packages/main/src/components/DataViews/components/Traces/mapTracesResponse.ts +++ b/packages/main/src/components/DataViews/components/Traces/mapTracesResponse.ts @@ -121,7 +121,8 @@ export function mapSpanFields(spans:any) { export const TREE_ROOT_ID = "__root__"; -export function countSpanDepth(spans:any, count:number = 0) { +export function countSpanDepth(spans:any, count = 0) { + spans.forEach((span:any) => { span.depth = count; if (span.children?.length > 0) { @@ -133,9 +134,11 @@ export function countSpanDepth(spans:any, count:number = 0) { }); } }); + } function getSpans(data:any) { + const mappedSpans = data.resourceSpans?.map((rs:any) => { const resource = rs.resource; return rs.instrumentationLibrarySpans.map((m:any) => @@ -148,171 +151,139 @@ function getSpans(data:any) { export function mapTracesResponse(data:any) { const allSpans = getSpans(data); - - return data?.resourceSpans?.map((trace:any) => { + const mapped = data?.resourceSpans?.map((trace) => { const { instrumentationLibrarySpans } = trace; - - const parent = allSpans.find( - (m:any) => Object.keys(m).indexOf("parentSpanId") === -1 - ); - + const parent = allSpans.find((m) => m.parentSpanId === undefined); const instSpans = [...allSpans]; - const orderedSpans = instSpans?.sort( - (a, b) => - parseInt(a.startTimeUnixNano) - parseInt(b.startTimeUnixNano) + (a, b) => parseInt(a.startTimeUnixNano) - parseInt(b.startTimeUnixNano) ); - + const firstTs = orderedSpans[0]?.startTimeUnixNano / 1000; const lastTimestamps = orderedSpans - .map((m) => m.endTimeUnixNano) - ?.sort() - ?.reverse(); - + .map((m) => m.endTimeUnixNano) + ?.sort() + ?.reverse(); const lastTs = lastTimestamps[0] / 1000; - - let spans = allSpans?.map((m:any, idx:any) => { - const tags = m.attributes?.map((attr:any) => ({ - key: attr?.key, - value: attr?.value?.stringValue, - })); - - const serviceTags = m?.resource?.attributes?.map((attr:any) => ({ - key: attr?.key, - value: attr?.value?.stringValue, - })); - - const duration = - Math.round(m?.endTimeUnixNano / 1000) - - Math.round(m?.startTimeUnixNano / 1000); - const startTime = m?.startTimeUnixNano / 1000; - - const process = { - serviceName: m?.serviceName, - tags: serviceTags, - }; - - return { - traceID: m?.traceID || m?.traceId, - spanID: m?.spanID || m.spanId, - parentSpanID: m?.parentSpanID || m?.parentSpanId || "", - operationName: m?.name, - serviceName: m?.serviceName, - serviceTags, - startTime, - duration, - relativeStartTime: 0, - events:m?.events || [], - logs: m?.logs || [], - references: m?.references || [], - tags, - processID: m?.spanID, - flags: 0, - dataFrameRowIndex: idx, - process, - children: m?.children || [], - }; + const spans:any = instSpans.map((m, idx) => { + const tags = m.attributes?.map((attr) => ({ + key: attr?.key, + value: attr?.value?.stringValue, + })); + + const serviceTags = m?.resource?.attributes?.map((attr) => ({ + key: attr?.key, + value: attr?.value?.stringValue, + })); + + const duration = + Math.round(m?.endTimeUnixNano / 1000) - + Math.round(m?.startTimeUnixNano / 1000); + const startTime = m?.startTimeUnixNano / 1000; + + const process = { + serviceName: m?.serviceName, + tags: serviceTags, + }; + + return { + traceID: m?.traceID || m?.traceId, + spanID: m?.spanID || m.spanId, + parentSpanID: m?.parentSpanID || m?.parentSpanId || "", + operationName: m?.name, + serviceName: m?.serviceName, + serviceTags, + startTime, + duration, + relativeStartTime: 0, + events: m?.events || [], + logs: m?.logs || [], + references: m?.references || [], + tags, + processID: m?.spanID, + flags: 0, + dataFrameRowIndex: idx, + process, + children: m?.children || [], + }; }); - + if (spans?.length > 0) { - try { - spans.forEach((span:any) => { - const hasParent = spans?.some( - (s:any) => s?.spanID === span?.parentSpanID - ); - - if (span?.parentSpanID !== "" && hasParent) { - const parent = spans?.find( - (f:any) => f.spanID === span.parentSpanID - ); - - if (parent) - spans = spans - ?.map((m:any) => { - if (m.spanID === parent.spanID) { - return { - ...m, - children: [ - ...m.children, - span.spanID, - ], - }; - } - - return m; - }) - ?.map((n:any) => { - if (n?.children?.length > 0) { - return { - ...n, - hasChildren: true, - childSpanCount: n.children.length, - relativeStartTime: - n.startTime - - spans[0].startTime, - }; - } - - return { - ...n, - relativeStartTime: - n.startTime - spans[0].startTime, - }; - }); - - span?.references?.push({ - refType: "CHILD_OF", - spanID: parent.spanID, - traceID: parent.traceID, - span: { ...parent }, - }); - } + try { + const spanMap = Object.create(null); // Use Object.create(null) for better performance + const rootSpan = spans[0].startTime; + + for (const span of spans) { + const { spanID, parentSpanID, startTime, references, children } = span; + const hasParent = parentSpanID !== "" && spanMap[parentSpanID]; + + if (hasParent) { + spanMap[parentSpanID].children.push(spanID); + references.push({ + refType: "CHILD_OF", + spanID: parentSpanID, + traceID: spanMap[parentSpanID].traceID, + span: { ...spanMap[parentSpanID] }, }); - } catch (e) { - console.log(e); + } + + if (children.length > 0) { + span.hasChildren = true; + span.childSpanCount = children.length; + span.relativeStartTime = startTime - rootSpan; + } else { + span.relativeStartTime = startTime - rootSpan; + } + + spanMap[spanID] = span; } + } catch (e) { + console.log(e); + } } - + countSpanDepth(spans); - - let traceObj :any = { - services: [], - spans: [], - traceID: "", - traceName: "", - processes: {}, // use processing fn - duration: 0, - startTime: 0, - endTime: 0, + + let traceObj = { + services: [], + spans: [], + traceID: "", + traceName: "", + processes: {}, // use processing fn + duration: 0, + startTime: 0, + endTime: 0, }; - - const firstSpan = spans?.[0]; - + + const firstSpan:any = spans?.[0]; + if (instrumentationLibrarySpans && lastTs && firstTs) { - const { - serviceName: firstServiceName, - name: firstName, - traceID: firstTraceID, - } = firstSpan; - - traceObj = { - services: spans.map((span:any) => { - return { - name: span.serviceName, - numberOfSpans: spans.length, - }; - }), - spans, - traceID: parent ? parent?.traceID : firstTraceID, - traceName: parent - ? `${parent?.serviceName}: ${parent?.name}` - : `${firstServiceName}: ${firstName}`, - processes: {}, // use processing fn - duration: lastTs - firstTs, - startTime: firstTs, - endTime: lastTs, - }; + const { + serviceName: firstServiceName, + name: firstName, + traceID: firstTraceID, + } = firstSpan; + + traceObj = { + services: spans.map((span) => { + return { + name: span.serviceName, + numberOfSpans: spans.length, + }; + }), + spans, + traceID: parent ? parent?.traceID : firstTraceID, + traceName: parent + ? `${parent?.serviceName}: ${parent?.name}` + : `${firstServiceName}: ${firstName}`, + processes: {}, // use processing fn + duration: lastTs - firstTs, + startTime: firstTs, + endTime: lastTs, + }; } return traceObj; - }); + }); + + return mapped }