From 4c98c927f2af9a6454cf267ccd39bca04bff285e Mon Sep 17 00:00:00 2001 From: Erlend Date: Mon, 1 Aug 2022 16:24:07 +0200 Subject: Trace is now correctly traversed with nested children --- .../app/pages/querybuilder/TransformVespaTrace.jsx | 321 ++++++++++----------- 1 file changed, 149 insertions(+), 172 deletions(-) diff --git a/client/js/app/src/app/pages/querybuilder/TransformVespaTrace.jsx b/client/js/app/src/app/pages/querybuilder/TransformVespaTrace.jsx index a6981b8a521..db37a227181 100644 --- a/client/js/app/src/app/pages/querybuilder/TransformVespaTrace.jsx +++ b/client/js/app/src/app/pages/querybuilder/TransformVespaTrace.jsx @@ -2,8 +2,7 @@ let traceID = ''; let processes = {}; let output = {}; let traceStartTimestamp = 0; -let topSpanId = ''; -let parentID = ''; +//let topSpanId = ''; // Generates a random hex string of size "size" const genRanHex = (size) => @@ -20,54 +19,66 @@ export default function transform(trace) { let temp = trace['trace']['children']; let spans = findChildren(temp); traceStartTimestamp = findTraceStartTime(spans); - topSpanId = genRanHex(16); + //topSpanId = genRanHex(16); let topSpanFirstHalf = createNewSpan(traceStartTimestamp)[0]; data.push(topSpanFirstHalf); const retrieved = findLogsAndChildren(spans, topSpanFirstHalf); const logs = retrieved['logs']; - const children = retrieved['children']; - traverseLogs(logs); - createChildren(children); + const indexes = retrieved['indexes']; + traverseLogs(logs, indexes); return output; } +function traverseChildren(span, logs, children, indexes, parent) { + let data = output['data'][0]['spans']; + let logSpan; + let spanTimestamp = span['timestamp']; + if (span.hasOwnProperty('children')) { + // Create a new parent span so that the timeline for the logs are correct + logSpan = createNewSpan( + traceStartTimestamp + spanTimestamp, + 0, + 'p0', + parent['operationName'], + [{ refType: 'CHILD_OF', traceID: traceID, spanID: parent['spanID'] }] + ); + data.push(logSpan); + let log = []; + for (let x of span['children']) { + if (x.hasOwnProperty('children')) { + traverseChildren(x, logs, children, indexes, logSpan); + } else if (Array.isArray(x['message'])) { + if (log.length > 0) { + // finished moving down the search chain + // create a new array for holding the logs that represent moving up the search chain + logs.push(log); + indexes.push(data.indexOf(parent)); + log = []; + } + console.log(x); + createChildren(x['message'], parent['spanID']); + } else { + // only add logs with a timestamp + if (x.hasOwnProperty('timestamp')) { + log.push(x); + } + } + } + indexes.push(data.indexOf(parent)); + logs.push(log); + } +} + function findLogsAndChildren(spans, topSpanFirstHalf) { let logs = []; let children = []; + let indexes = []; let data = output['data'][0]['spans']; - //let hitQuery = false; - //let topSpanSecondHalf = createNewSpan(); - //let secondHalfDuration = 0; - //output['data'][0]['spans'].push(topSpanSecondHalf); - //let firstHitSecondHalf = true; - for (let i = 0; i < spans.length - 1; i++) { + for (let i = 0; i < spans.length; i++) { if (spans[i].hasOwnProperty('children')) { - let a = spans[i]['timestamp']; - topSpanFirstHalf = createNewSpan(traceStartTimestamp + a); - //firstHitSecondHalf = true; - //topSpanSecondHalf = createNewSpan(); - //output['data'][0]['spans'].push(topSpanSecondHalf); - let log = []; - for (let x of spans[i]['children']) { - if (Array.isArray(x['message'])) { - if (log.length > 0) { - // finished moving down the search chain - // create a new array for holding the logs that represent moving up the search chain - logs.push(log); - log = []; - } - //hitQuery = true; - children.push(x['message']); - } else { - // only add logs with a timestamp - if (x.hasOwnProperty('timestamp')) { - log.push(x); - } - } - } - logs.push(log); + traverseChildren(spans[i], logs, children, indexes, topSpanFirstHalf); } else if ( spans[i].hasOwnProperty('message') && spans[i].hasOwnProperty('timestamp') @@ -90,183 +101,149 @@ function findLogsAndChildren(spans, topSpanFirstHalf) { } topSpanFirstHalf['duration'] = topSpanFirstHalf['duration'] + duration; span['duration'] = duration; - // if (hitQuery) { - // if (firstHitSecondHalf) { - // secondHalfDuration = span['timestamp'] * 1000; - // topSpanSecondHalf['startTime'] = - // traceStartTimestamp + secondHalfDuration; - // firstHitSecondHalf = false; - // } - // topSpanSecondHalf['duration'] = - // span['timestamp'] * 1000 - secondHalfDuration; - // topSpanSecondHalf['logs'].push({ - // timestamp: traceStartTimestamp + span['timestamp'] * 1000, - // fields: [{ key: 'message', type: 'string', value: span['message'] }], - // }); - // } else { - // topSpanFirstHalf['duration'] = span['timestamp'] * 1000; - // topSpanFirstHalf['logs'].push({ - // timestamp: traceStartTimestamp + span['timestamp'] * 1000, - // fields: [{ key: 'message', type: 'string', value: span['message'] }], - // }); - // } } } - return { logs: logs, children: children }; + return { logs: logs, indexes: indexes }; } -function traverseLogs(logs) { - let first = true; +function traverseLogs(logs, indexes) { let data = output['data'][0]['spans']; - for (let log of logs) { + let previous; + for (let i = 0; i < logs.length; i++) { + previous = data[indexes[i]]; + let log = logs[i]; let logStartTimestamp = traceStartTimestamp + log[0]['timestamp'] * 1000; let logDuration = (log[log.length - 1]['timestamp'] - log[0]['timestamp']) * 1000; if (logDuration === 0) { logDuration = 1; } - let spanID = genRanHex(16); - if (first) { - parentID = spanID; - first = false; - } - let temp = createNewSpan( - logStartTimestamp, - logDuration, - 'p0', - 'test' - //[{ refType: 'CHILD_OF', traceID: traceID, spanID: topSpanId }] - ); + let temp = createNewSpan(logStartTimestamp, logDuration, 'p0', 'test', [ + { refType: 'CHILD_OF', traceID: traceID, spanID: previous['spanID'] }, + ]); let childSpan = temp[0]; let childSpanID = temp[1]; data.push(childSpan); - for (let i = 0; i < log.length - 1; i++) { - if (log[i].hasOwnProperty('message')) { - let logPointStart = traceStartTimestamp + log[i]['timestamp'] * 1000; + for (let k = 0; k < log.length - 1; k++) { + if (log[k].hasOwnProperty('message')) { + let logPointStart = traceStartTimestamp + log[k]['timestamp'] * 1000; let logPointDuration; - if (i > log.length - 1) { + if (k > log.length - 1) { logPointDuration = 1; } else { logPointDuration = - (log[i + 1]['timestamp'] - log[i]['timestamp']) * 1000; + (log[k + 1]['timestamp'] - log[k]['timestamp']) * 1000; logPointDuration = logPointDuration === 0 ? 1 : logPointDuration; } let logSpan = createNewSpan( logPointStart, logPointDuration, 'p0', - log[i]['message'], + log[k]['message'], [{ refType: 'CHILD_OF', traceID: traceID, spanID: childSpanID }] )[0]; data.push(logSpan); - // childSpan['logs'].push({ - // timestamp: traceStartTimestamp + log[i]['timestamp'] * 1000, - // fields: [ - // { key: 'message', type: 'string', value: log[i]['message'] }, - // ], - // }); } } } } -function createChildren(children) { - for (let i = 0; i < children.length; i++) { - let child = children[i][0]; - let processKey = `p${i + 1}`; - processes[processKey] = { serviceName: `Span${i}`, tags: [] }; - let spanID = genRanHex(16); - let data = output['data'][0]['spans']; - let startTimestamp = Date.parse(child['start_time']) * 1000; - let newSpan = { +function createChildren(children, parentID) { + console.log(parentID); + let child = children[0]; + let processKey = genRanHex(5); + processes[processKey] = { serviceName: genRanHex(3), tags: [] }; + let spanID = genRanHex(16); + let data = output['data'][0]['spans']; + let startTimestamp = Date.parse(child['start_time']) * 1000; + let newSpan = { + traceID: traceID, + spanID: spanID, + operationName: 'something', + startTime: startTimestamp, + duration: child['duration_ms'] * 1000, + references: [{ refType: 'CHILD_OF', traceID: traceID, spanID: parentID }], + tags: [], + logs: [], + processID: processKey, + }; + data.push(newSpan); + let traces = child['traces']; + for (let k = 0; k < traces.length; k++) { + let trace = traces[k]; + let traceTimestamp = trace['timestamp_ms']; + let events; + let firstEvent; + let duration; + if (trace['tag'] === 'query_execution') { + events = trace['threads'][0]['traces']; + firstEvent = events[0]; + duration = (traceTimestamp - firstEvent['timestamp_ms']) * 1000; + } else if (trace['tag'] === 'query_execution_plan') { + events = []; + let nextTrace = traces[k + 1]; + firstEvent = trace; + // query execution plan has no events, duration must therefore be found using the next trace + if (nextTrace['tag'] === 'query_execution') { + duration = + (nextTrace['threads'][0]['traces'][0]['timestamp_ms'] - + traceTimestamp) * + 1000; + } else { + duration = (nextTrace['timestamp_ms'] - traceTimestamp) * 1000; + } + } else { + events = trace['traces']; + firstEvent = events[0]; + duration = (traceTimestamp - firstEvent['timestamp_ms']) * 1000; + } + let childSpanID = genRanHex(16); + let childSpan = { traceID: traceID, - spanID: spanID, - operationName: `query${i}`, - startTime: startTimestamp, - duration: child['duration_ms'] * 1000, - references: [{ refType: 'CHILD_OF', traceID: traceID, spanID: parentID }], + spanID: childSpanID, + operationName: trace['tag'], + startTime: startTimestamp + firstEvent['timestamp_ms'] * 1000, + duration: duration, + references: [{ refType: 'CHILD_OF', traceID: traceID, spanID: spanID }], tags: [], logs: [], processID: processKey, }; - data.push(newSpan); - let traces = child['traces']; - for (let k = 0; k < traces.length; k++) { - let trace = traces[k]; - let traceTimestamp = trace['timestamp_ms']; - let events; - let firstEvent; - let duration; - if (trace['tag'] === 'query_execution') { - events = trace['threads'][0]['traces']; - firstEvent = events[0]; - duration = (traceTimestamp - firstEvent['timestamp_ms']) * 1000; - } else if (trace['tag'] === 'query_execution_plan') { - events = []; - let nextTrace = traces[k + 1]; - firstEvent = trace; - // query execution plan has no events, duration must therefore be found using the next trace - if (nextTrace['tag'] === 'query_execution') { - duration = - (nextTrace['threads'][0]['traces'][0]['timestamp_ms'] - - traceTimestamp) * - 1000; - } else { - duration = (nextTrace['timestamp_ms'] - traceTimestamp) * 1000; - } - } else { - events = trace['traces']; - firstEvent = events[0]; - duration = (traceTimestamp - firstEvent['timestamp_ms']) * 1000; - } - let childSpanID = genRanHex(16); - let childSpan = { - traceID: traceID, - spanID: childSpanID, - operationName: trace['tag'], - startTime: startTimestamp + firstEvent['timestamp_ms'] * 1000, - duration: duration, - references: [{ refType: 'CHILD_OF', traceID: traceID, spanID: spanID }], - tags: [], - logs: [], - processID: processKey, - }; - data.push(childSpan); - if (events.length > 0) { - for (let j = 0; j < events.length; j++) { - let event = events[j]; - let eventID = genRanHex(16); - let eventStart = event['timestamp_ms']; - let operationName; - if (event.hasOwnProperty('event')) { - operationName = event['event']; - if ( - operationName === 'Complete query setup' || - operationName === 'MatchThread::run Done' - ) { - duration = (traceTimestamp - eventStart) * 1000; - } else { - duration = (events[j + 1]['timestamp_ms'] - eventStart) * 1000; - } + data.push(childSpan); + if (events.length > 0) { + for (let j = 0; j < events.length; j++) { + let event = events[j]; + let eventID = genRanHex(16); + let eventStart = event['timestamp_ms']; + let operationName; + if (event.hasOwnProperty('event')) { + operationName = event['event']; + if ( + operationName === 'Complete query setup' || + operationName === 'MatchThread::run Done' + ) { + duration = (traceTimestamp - eventStart) * 1000; } else { - operationName = event['tag']; duration = (events[j + 1]['timestamp_ms'] - eventStart) * 1000; } - let eventSpan = { - traceID: traceID, - spanID: eventID, - operationName: operationName, - startTime: startTimestamp + eventStart * 1000, - duration: duration, - references: [ - { refType: 'CHILD_OF', traceID: traceID, spanID: childSpanID }, - ], - tags: [], - logs: [], - processID: processKey, - }; - data.push(eventSpan); + } else { + operationName = event['tag']; + duration = (events[j + 1]['timestamp_ms'] - eventStart) * 1000; } + let eventSpan = { + traceID: traceID, + spanID: eventID, + operationName: operationName, + startTime: startTimestamp + eventStart * 1000, + duration: duration, + references: [ + { refType: 'CHILD_OF', traceID: traceID, spanID: childSpanID }, + ], + tags: [], + logs: [], + processID: processKey, + }; + data.push(eventSpan); } } } -- cgit v1.2.3 From 5268a80073f7218202fd7bbdc5570e686b26c999 Mon Sep 17 00:00:00 2001 From: Erlend Date: Tue, 2 Aug 2022 13:41:16 +0200 Subject: Now has top span and correct duration for spans --- .../app/pages/querybuilder/TransformVespaTrace.jsx | 30 +++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/client/js/app/src/app/pages/querybuilder/TransformVespaTrace.jsx b/client/js/app/src/app/pages/querybuilder/TransformVespaTrace.jsx index db37a227181..5e09a5dec0f 100644 --- a/client/js/app/src/app/pages/querybuilder/TransformVespaTrace.jsx +++ b/client/js/app/src/app/pages/querybuilder/TransformVespaTrace.jsx @@ -2,7 +2,6 @@ let traceID = ''; let processes = {}; let output = {}; let traceStartTimestamp = 0; -//let topSpanId = ''; // Generates a random hex string of size "size" const genRanHex = (size) => @@ -19,7 +18,6 @@ export default function transform(trace) { let temp = trace['trace']['children']; let spans = findChildren(temp); traceStartTimestamp = findTraceStartTime(spans); - //topSpanId = genRanHex(16); let topSpanFirstHalf = createNewSpan(traceStartTimestamp)[0]; data.push(topSpanFirstHalf); @@ -37,9 +35,14 @@ function traverseChildren(span, logs, children, indexes, parent) { let spanTimestamp = span['timestamp']; if (span.hasOwnProperty('children')) { // Create a new parent span so that the timeline for the logs are correct + let duration = + (span['children'][span['children'].length - 1]['timestamp'] - + span['children'][0]['timestamp']) * + 1000; + parent['duration'] = duration; logSpan = createNewSpan( traceStartTimestamp + spanTimestamp, - 0, + duration, 'p0', parent['operationName'], [{ refType: 'CHILD_OF', traceID: traceID, spanID: parent['spanID'] }] @@ -57,7 +60,6 @@ function traverseChildren(span, logs, children, indexes, parent) { indexes.push(data.indexOf(parent)); log = []; } - console.log(x); createChildren(x['message'], parent['spanID']); } else { // only add logs with a timestamp @@ -76,9 +78,17 @@ function findLogsAndChildren(spans, topSpanFirstHalf) { let children = []; let indexes = []; let data = output['data'][0]['spans']; + let totalDuration = findDuration(spans); + topSpanFirstHalf['duration'] = totalDuration; for (let i = 0; i < spans.length; i++) { if (spans[i].hasOwnProperty('children')) { - traverseChildren(spans[i], logs, children, indexes, topSpanFirstHalf); + traverseChildren( + spans[i], + logs, + children, + indexes, + data[data.length - 1] + ); } else if ( spans[i].hasOwnProperty('message') && spans[i].hasOwnProperty('timestamp') @@ -99,7 +109,6 @@ function findLogsAndChildren(spans, topSpanFirstHalf) { duration = (spans[i + 1]['timestamp'] - spans[i]['timestamp']) * 1000; duration = duration === 0 ? 1 : duration; } - topSpanFirstHalf['duration'] = topSpanFirstHalf['duration'] + duration; span['duration'] = duration; } } @@ -149,7 +158,6 @@ function traverseLogs(logs, indexes) { } function createChildren(children, parentID) { - console.log(parentID); let child = children[0]; let processKey = genRanHex(5); processes[processKey] = { serviceName: genRanHex(3), tags: [] }; @@ -283,7 +291,6 @@ function findTraceStartTime(spans) { return startTime; } -//TODO: remove if not needed later function findDuration(spans) { let notFound = true; let duration = 0; @@ -292,16 +299,15 @@ function findDuration(spans) { if (spans[i].hasOwnProperty('timestamp')) { duration = spans[i]['timestamp']; notFound = false; - } else { - i--; } + i--; } - return duration; + return duration * 1000; } function createNewSpan( startTime = 0, - duration = 0, + duration = 1, processID = 'p0', operationName = 'Complete', references = [] -- cgit v1.2.3