func marshalEventGlobalLabels()

in aggregators/converter.go [985:1047]


func marshalEventGlobalLabels(e *modelpb.APMEvent) ([]byte, error) {
	var labelsCnt, numericLabelsCnt int
	for _, v := range e.Labels {
		if !v.Global {
			continue
		}
		labelsCnt++
	}
	for _, v := range e.NumericLabels {
		if !v.Global {
			continue
		}
		numericLabelsCnt++
	}

	if labelsCnt == 0 && numericLabelsCnt == 0 {
		return nil, nil
	}

	pb := &aggregationpb.GlobalLabels{}
	pb.Labels = slices.Grow(pb.Labels, labelsCnt)[:labelsCnt]
	pb.NumericLabels = slices.Grow(pb.NumericLabels, numericLabelsCnt)[:numericLabelsCnt]

	var i int
	// Keys must be sorted to ensure wire formats are deterministically generated and strings are directly comparable
	// i.e. Protobuf formats are equal if and only if the structs are equal
	for k, v := range e.Labels {
		if !v.Global {
			continue
		}
		if pb.Labels[i] == nil {
			pb.Labels[i] = &aggregationpb.Label{}
		}
		pb.Labels[i].Key = k
		pb.Labels[i].Value = v.Value
		pb.Labels[i].Values = slices.Grow(pb.Labels[i].Values, len(v.Values))[:len(v.Values)]
		copy(pb.Labels[i].Values, v.Values)
		i++
	}
	sort.Slice(pb.Labels, func(i, j int) bool {
		return pb.Labels[i].Key < pb.Labels[j].Key
	})

	i = 0
	for k, v := range e.NumericLabels {
		if !v.Global {
			continue
		}
		if pb.NumericLabels[i] == nil {
			pb.NumericLabels[i] = &aggregationpb.NumericLabel{}
		}
		pb.NumericLabels[i].Key = k
		pb.NumericLabels[i].Value = v.Value
		pb.NumericLabels[i].Values = slices.Grow(pb.NumericLabels[i].Values, len(v.Values))[:len(v.Values)]
		copy(pb.NumericLabels[i].Values, v.Values)
		i++
	}
	sort.Slice(pb.NumericLabels, func(i, j int) bool {
		return pb.NumericLabels[i].Key < pb.NumericLabels[j].Key
	})

	return pb.MarshalVT()
}