signoz/frontend/src/utils/spanToTree.ts
Prashant Shahi eb63b6da2a
Release/v0.7.0 (#814)
* feat(FE): dynamic step size of metrics page

* chore(tests): migrate to dayjs for generating timestamp

* bug: sorting of date is fixed

* feat: soring filter is added

* chore: typo is fixed

* feat(backend): support custom events in span

* fix: encode event string to fix parsing at frontend

* chore: styles is updated for the not found button

* chore: update otel-collector to 0.43.0

* fix: remove encoding

* fix: set userId as distinctId if failed to fetch IP

* Fe: Feat/trace detail (#764)

* feat: new trace detail page flame graph

* feat: new trace detail page layout

* test: trace detail is wip

* chore: trace details in wip

* feat: trace detail page timeline component

* chore: spantoTree is updated

* chore: gantchart is updated

* chore: onClick is added

* chore: isSpanPresentInSearchString util is added

* chore: trace graph is updated

* chore: added the hack to work

* feat: is span present util is added

* chore: in span ms is added

* chore: tooltip is updated

* WIP: chore: trace details changes are updated

* feat: getTraceItem is added

* feat: trace detail page is updated

* feat: trace detail styling changes

* feat: trace detail page is updated

* feat: implement span hover, select, focus and reset

* feat: reset focus

* feat: spanId as query table and unfurling

* feat: trace details is updated

* chore: remove lodash

* chore: remove lodash

* feat: trace details is updated

* feat: new trace detail page styling changes

* feat: new trace detail page styling changes

* feat: improved styling

* feat: remove horizontal scrolling

* feat: new trace detail page modify caret icon

* chore styles are updated

* Revert "chore: Trace styles"

* chore styles are updated

* feat: timeline normalisation

* chore: remove mock data

* chore: sort tree data util is added and selected span component is updated

* chore: trace changes are updated

* chore: trace changes are updated

* chore: trace changes are updated

* feat: refactored time units for new trace detail page

* chore: remove mockdata

* feat: new trace detail page themeing and interval loop fix

* chore: error tag is updated

* chore: error tag is updated

* chore: error tag is updated

* chore: error tag is updated

* chore: console is removed

* fix: error tag expand button

* chore: expanded panel is updated

* feat: scroll span from gantt chart intoview

* chore: trace detail is removed

Co-authored-by: Pranshu Chittora <pranshu@signoz.io>

* bug: Trace search bug is resolved (#741)

* bug: Trace search bug is resolved

* bug: Trace search bug is resolved

* chore: parseTagsToQuery is updated

* chore: parseTagsToQuery is updated

* chore: parseTagsToQuery is updated

* chore: parseTagsToQuery is updated

* chore: ️ add hotrod template and install/delete scripts (#801)

* chore: ️ add hotrod template and scripts

Signed-off-by: Prashant Shahi <prashant@signoz.io>

* refactor:  conditionally compute image

Signed-off-by: Prashant Shahi <prashant@signoz.io>

* fix: 🩹 add signoz namespace

Signed-off-by: Prashant Shahi <prashant@signoz.io>

* chore: 🔨  fix namespace template in scripts

Signed-off-by: Prashant Shahi <prashant@signoz.io>

* docs(hotrod): 📝 Add README for hotrod k8s

Signed-off-by: Prashant Shahi <prashant@signoz.io>

Co-authored-by: Ankit Nayan <ankit@signoz.io>

* chore(release): 📌 pin SigNoz and OtelCollector versions

Signed-off-by: Prashant Shahi <prashant@signoz.io>

Co-authored-by: Pranshu Chittora <pranshu@signoz.io>
Co-authored-by: Palash gupta <palash@signoz.io>
Co-authored-by: makeavish <makeavish786@gmail.com>
Co-authored-by: Ankit Nayan <ankit@signoz.io>
2022-03-04 01:41:49 +05:30

136 lines
4.1 KiB
TypeScript

import { cloneDeep } from 'lodash-es';
import { ITraceTree, Span } from 'types/api/trace/getTraceItem';
// PNOTE - should the data be taken from redux or only through props? - Directly as arguments
export const spanToTreeUtil = (originalList: Span[]): ITraceTree => {
// Initializing tree. What should be returned is trace is empty? We should have better error handling
let tree: ITraceTree = {
id: 'empty',
name: 'default',
value: 0,
time: 0,
startTime: 0,
tags: [],
children: [],
serviceColour: '',
serviceName: '',
};
let spanlist = cloneDeep(originalList);
// let spans :spanItem[]= trace.spans;
if (spanlist) {
// Create a dict with spanIDs as keys
// PNOTE
// Can we now assign different strings as id - Yes
// https://stackoverflow.com/questions/15877362/declare-and-initialize-a-dictionary-in-typescript
//May1
//https://stackoverflow.com/questions/13315131/enforcing-the-type-of-the-indexed-members-of-a-typescript-object
const mapped_array: { [id: string]: Span } = {};
const originalListArray: { [id: string]: Span } = {};
for (let i = 0; i < spanlist.length; i++) {
originalListArray[spanlist[i][1]] = originalList[i];
mapped_array[spanlist[i][1]] = spanlist[i];
mapped_array[spanlist[i][1]][10] = []; //initialising the 10th element in the Span data structure which is array
// of type ITraceTree
// console.log('IDs while creating mapped array')
// console.log(`SpanID is ${spanlist[i][1]}\n`);
}
// console.log(`In SpanTreeUtil: mapped_arrayis ${mapped_array}`);
for (const id in mapped_array) {
const child_span = mapped_array[id];
//mapping tags to new structure
const tags_temp = [];
if (child_span[7] !== null && child_span[8] !== null) {
if (
typeof child_span[7] === 'string' &&
typeof child_span[8] === 'string'
) {
tags_temp.push({ key: child_span[7], value: child_span[8] });
} else if (child_span[7].length > 0 && child_span[8].length > 0) {
for (let j = 0; j < child_span[7].length; j++) {
tags_temp.push({ key: child_span[7][j], value: child_span[8][j] });
}
}
}
const push_object: ITraceTree = {
id: child_span[1],
name: child_span[4],
value: parseInt(child_span[6]),
time: parseInt(child_span[6]),
startTime: child_span[0],
tags: tags_temp,
children: mapped_array[id][10],
serviceName: child_span[3],
hasError: !!child_span[11],
serviceColour: '',
event: originalListArray[id][10].map((e) => {
return JSON.parse(decodeURIComponent(e || '{}')) || {};
}),
};
const referencesArr = mapped_array[id][9];
let refArray = [];
if (typeof referencesArr === 'string') {
refArray.push(referencesArr);
} else {
refArray = referencesArr;
}
const references = [];
refArray.forEach((element) => {
element = element
.replaceAll('{', '')
.replaceAll('}', '')
.replaceAll(' ', '');
const arr = element.split(',');
const refItem = { traceID: '', spanID: '', refType: '' };
arr.forEach((obj) => {
const arr2 = obj.split('=');
if (arr2[0] === 'TraceId') {
refItem['traceID'] = arr2[1];
} else if (arr2[0] === 'SpanId') {
refItem['spanID'] = arr2[1];
} else if (arr2[0] === 'RefType') {
refItem['refType'] = arr2[1];
}
});
references.push(refItem);
});
if (references.length !== 0 && references[0].spanID.length !== 0) {
if (references[0].refType === 'CHILD_OF') {
const parentID = references[0].spanID;
// console.log(`In SpanTreeUtil: mapped_array[parentID] is ${mapped_array[parentID]}`);
if (typeof mapped_array[parentID] !== 'undefined') {
//checking for undefined [10] issue
mapped_array[parentID][10].push(push_object);
} else {
// console.log(
// `In SpanTreeUtil: mapped_array[parentID] is undefined, parentID is ${parentID}`,
// );
// console.log(
// `In SpanTreeUtil: mapped_array[parentID] is undefined, mapped_array[parentID] is ${mapped_array[parentID]}`,
// );
}
}
} else {
tree = push_object;
}
} // end of for loop
} // end of if(spans)
return { ...tree };
};