mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-24 02:46:27 +00:00
* 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>
136 lines
4.1 KiB
TypeScript
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 };
|
|
};
|