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  }