github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/pkg/segment/tracing/utils/buildspantree.go (about) 1 package utils 2 3 import ( 4 "fmt" 5 6 "github.com/siglens/siglens/pkg/segment/tracing/structs" 7 log "github.com/sirupsen/logrus" 8 ) 9 10 func BuildSpanTree(spanMap map[string]*structs.GanttChartSpan, idToParentId map[string]string) (*structs.GanttChartSpan, error) { 11 res := &structs.GanttChartSpan{} 12 13 // Find root span 14 for spanID, span := range spanMap { 15 parentSpanID, exists := idToParentId[spanID] 16 if !exists { 17 log.Errorf("BuildSpanTree: can not find parent span:%v for span:%v", parentSpanID, spanID) 18 continue 19 } 20 21 if parentSpanID == "" { 22 res = span 23 } 24 } 25 26 if res.SpanID == "" { 27 return nil, fmt.Errorf("BuildSpanTree: can not find a root span") 28 } 29 30 rootSpanStartTime := res.StartTime 31 32 for spanID, span := range spanMap { 33 // Calculate the relative start time and end time for each span 34 span.ActualStartTime = span.StartTime 35 span.StartTime -= rootSpanStartTime 36 span.EndTime -= rootSpanStartTime 37 38 parentSpanID, exists := idToParentId[spanID] 39 if !exists { 40 log.Errorf("BuildSpanTree: can not find parent span:%v for span:%v", parentSpanID, spanID) 41 continue 42 } 43 44 if parentSpanID != "" { 45 parentSpan, exists := spanMap[parentSpanID] 46 if !exists { 47 log.Errorf("BuildSpanTree: can not find parent span:%v for span:%v", parentSpanID, spanID) 48 continue 49 } 50 51 // If a span start before its parent, it is anomalous 52 parentSpanStartTime := parentSpan.StartTime 53 if parentSpan.ActualStartTime != uint64(0) { 54 parentSpanStartTime = parentSpan.ActualStartTime 55 } 56 57 if span.ActualStartTime < parentSpanStartTime || span.ActualStartTime < rootSpanStartTime { 58 span.IsAnomalous = true 59 } 60 61 parentSpan.Children = append(parentSpan.Children, span) 62 } 63 } 64 65 return res, nil 66 }