// ParseTrace reads a trace using the standard log format
ParseTrace reads a trace using the standard log format
// ParseTrace reads a trace using the standard log format
func ParseTrace(content string) ([]*pb.TracePayload, error) {
	var tl traceList
	err := json.Unmarshal([]byte(content), &tl)
	traces := []*pb.TracePayload{}
	if err != nil {
		return traces, fmt.Errorf("couldn't parse trace, %v", err)
	}
	removedSpans := map[uint64]*pb.Span{}
	for _, trace := range tl.Traces {
		apiTraces := map[uint64]*pb.APITrace{}
		for _, sp := range trace {
			if sp.Meta == nil {
				sp.Meta = map[string]string{}
			}
			sp.Meta[originMetadataKey] = "lambda"
			sp.Meta[computeStatsKey] = "1"
			pbSpan := convertSpanToPB(sp)
			if IsParentedToXray(pbSpan) {
				removedSpans[pbSpan.SpanID] = pbSpan
				continue
			}
			var apiTrace *pb.APITrace
			var ok bool
			if removedSpans[pbSpan.ParentID] != nil {
				pbSpan.ParentID = removedSpans[pbSpan.ParentID].ParentID
			}
			if apiTrace, ok = apiTraces[pbSpan.TraceID]; !ok {
				apiTrace = &pb.APITrace{
					TraceID:   pbSpan.TraceID,
					Spans:     []*pb.Span{},
					StartTime: 0,
					EndTime:   0,
				}
				apiTraces[apiTrace.TraceID] = apiTrace
			}
			addToAPITrace(apiTrace, pbSpan)
		}
		payload := pb.TracePayload{
			HostName:     "",
			Env:          "none",
			Traces:       []*pb.APITrace{},
			Transactions: []*pb.Span{},
		}
		for _, apiTrace := range apiTraces {
			top := GetAnalyzedSpans(apiTrace.Spans)
			computeSublayerMetrics(apiTrace.Spans)
			payload.Transactions = append(payload.Transactions, top...)
			payload.Traces = append(payload.Traces, apiTrace)
		}
		if len(payload.Traces) == 0 {
			continue
		}
		traces = append(traces, &payload)
	}
	return traces, nil
}
func ParseTrace ( content string ) ( [ ] * pb . TracePayload , error ) { var tl traceList err := json . Unmarshal ( [ ] byte ( content ) , & tl ) traces := [ ] * pb . TracePayload { } if err != nil { return traces , fmt . Errorf ( " " , err ) } removedSpans := map [ uint64 ] * pb . Span { } for _ , trace := range tl . Traces { apiTraces := map [ uint64 ] * pb . APITrace { } for _ , sp := range trace { if sp . Meta == nil { sp . Meta = map [ string ] string { } } sp . Meta [ originMetadataKey ] = " " sp . Meta [ computeStatsKey ] = " " pbSpan := convertSpanToPB ( sp ) if IsParentedToXray ( pbSpan ) { removedSpans [ pbSpan . SpanID ] = pbSpan continue } var apiTrace * pb . APITrace var ok bool if removedSpans [ pbSpan . ParentID ] != nil { pbSpan . ParentID = removedSpans [ pbSpan . ParentID ] . ParentID } if apiTrace , ok = apiTraces [ pbSpan . TraceID ] ; ! ok { apiTrace = & pb . APITrace { TraceID : pbSpan . TraceID , Spans : [ ] * pb . Span { } , StartTime : 0 , EndTime : 0 , } apiTraces [ apiTrace . TraceID ] = apiTrace } addToAPITrace ( apiTrace , pbSpan ) } payload := pb . TracePayload { HostName : " " , Env : " " , Traces : [ ] * pb . APITrace { } , Transactions : [ ] * pb . Span { } , } for _ , apiTrace := range apiTraces { top := GetAnalyzedSpans ( apiTrace . Spans ) computeSublayerMetrics ( apiTrace . Spans ) payload . Transactions = append ( payload . Transactions , top ... ) payload . Traces = append ( payload . Traces , apiTrace ) } if len ( payload . Traces ) == 0 { continue } traces = append ( traces , & payload ) } return traces , nil }
ParseTrace reads a trace using the standard log format
ParseTrace reads a trace using the standard log format
// Make sure the span is marked as comming from lambda, // this will help the backend make sampling decisions // Instruct the span intake pipeline to compute stats // in the APM backend. // We skip root dd-trace spans that are parented to X-Ray, // since those root spans are placeholders for the X-Ray // parent span. // Reparent any spans that have been removed // We dont want to include TracePayloads with empty traces