func calculateUtilizationFromNumberDataPoints()

in components/otelopscol/processor/agentmetricsprocessor/utils_calculate_utilizations.go [153:210]


func calculateUtilizationFromNumberDataPoints(metric, utilizationMetric pmetric.Metric) error {
	var ndps pmetric.NumberDataPointSlice
	switch t := metric.Type(); t {
	case pmetric.MetricTypeSum:
		ndps = metric.Sum().DataPoints()
	case pmetric.MetricTypeGauge:
		ndps = metric.Gauge().DataPoints()
	}

	pointCount := ndps.Len()
	groupedPoints := make(map[string]*numberPoints, pointCount) // overallocate to ensure no resizes are required
	for i := 0; i < pointCount; i++ {
		ndp := ndps.At(i)

		key, err := otherLabelsAsKey(ndp.Attributes(), stateLabel)
		if err != nil {
			return fmt.Errorf("metric %v: %w", metric.Name(), err)
		}

		points, ok := groupedPoints[key]
		if !ok {
			points = &numberPoints{}
			groupedPoints[key] = points
		}

		switch ndp.ValueType() {
		case pmetric.NumberDataPointValueTypeInt:
			points.sum += float64(ndp.IntValue())
		case pmetric.NumberDataPointValueTypeDouble:
			points.sum += ndp.DoubleValue()
		}
		points.pts = append(points.pts, ndp)
	}

	ndps = pmetric.NewNumberDataPointSlice()
	ndps.EnsureCapacity(pointCount)
	for _, points := range groupedPoints {
		for _, point := range points.pts {
			ndp := ndps.AppendEmpty()

			// copy dp, setting the value based on utilization calculation
			point.Attributes().CopyTo(ndp.Attributes())
			ndp.SetStartTimestamp(point.StartTimestamp())
			ndp.SetTimestamp(point.Timestamp())
			var num float64
			switch point.ValueType() {
			case pmetric.NumberDataPointValueTypeInt:
				num = float64(point.IntValue())
			case pmetric.NumberDataPointValueTypeDouble:
				num = point.DoubleValue()
			}
			ndp.SetDoubleValue(num / points.sum * 100)
		}
	}
	ndps.CopyTo(utilizationMetric.Gauge().DataPoints())

	return nil
}