func remapCPUMetrics()

in remappers/hostmetrics/cpu.go [27:233]


func remapCPUMetrics(
	src, out pmetric.MetricSlice,
	_ pcommon.Resource,
	mutator func(pmetric.NumberDataPoint),
) error {
	var timestamp pcommon.Timestamp
	var numCores int64
	var totalPercent, idlePercent, systemPercent, userPercent, stealPercent,
		iowaitPercent, nicePercent, irqPercent, softirqPercent float64

	// iterate all metrics in the current scope and generate the additional Elastic
	// system integration metrics.
	for i := 0; i < src.Len(); i++ {
		metric := src.At(i)
		switch metric.Name() {
		case "system.cpu.logical.count":
			dp := metric.Sum().DataPoints().At(0)
			if timestamp == 0 {
				timestamp = dp.Timestamp()
			}
			numCores = dp.IntValue()
		case "system.cpu.utilization":
			dataPoints := metric.Gauge().DataPoints()
			for j := 0; j < dataPoints.Len(); j++ {
				dp := dataPoints.At(j)
				if timestamp == 0 {
					timestamp = dp.Timestamp()
				}

				value := dp.DoubleValue()
				if state, ok := dp.Attributes().Get("state"); ok {
					switch state.Str() {
					case "idle":
						idlePercent += value
					case "system":
						systemPercent += value
						totalPercent += value
					case "user":
						userPercent += value
						totalPercent += value
					case "steal":
						stealPercent += value
						totalPercent += value
					case "wait":
						iowaitPercent += value
						totalPercent += value
					case "nice":
						nicePercent += value
						totalPercent += value
					case "interrupt":
						irqPercent += value
						totalPercent += value
					case "softirq":
						softirqPercent += value
						totalPercent += value
					}
				}
			}
		}
	}

	// Add all metrics that are independent of cpu logical count.
	remappedmetric.Add(out, mutator,
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.total.pct",
			Timestamp:   timestamp,
			DoubleValue: &totalPercent,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.idle.pct",
			Timestamp:   timestamp,
			DoubleValue: &idlePercent,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.system.pct",
			Timestamp:   timestamp,
			DoubleValue: &systemPercent,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.user.pct",
			Timestamp:   timestamp,
			DoubleValue: &userPercent,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.steal.pct",
			Timestamp:   timestamp,
			DoubleValue: &stealPercent,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.iowait.pct",
			Timestamp:   timestamp,
			DoubleValue: &iowaitPercent,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.nice.pct",
			Timestamp:   timestamp,
			DoubleValue: &nicePercent,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.irq.pct",
			Timestamp:   timestamp,
			DoubleValue: &irqPercent,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.softirq.pct",
			Timestamp:   timestamp,
			DoubleValue: &softirqPercent,
		},
	)

	if numCores == 0 {
		// system.cpu.logical.count is optional, and if it's not
		// present we can't calculate the normalized values.
		// This is not an error, so we just return early.
		return nil
	}

	totalNorm := totalPercent / float64(numCores)
	idleNorm := idlePercent / float64(numCores)
	systemNorm := systemPercent / float64(numCores)
	userNorm := userPercent / float64(numCores)
	stealNorm := stealPercent / float64(numCores)
	iowaitNorm := iowaitPercent / float64(numCores)
	niceNorm := nicePercent / float64(numCores)
	irqNorm := irqPercent / float64(numCores)
	softirqNorm := softirqPercent / float64(numCores)

	remappedmetric.Add(out, mutator,
		remappedmetric.Metric{
			DataType:  pmetric.MetricTypeSum,
			Name:      "system.cpu.cores",
			Timestamp: timestamp,
			IntValue:  &numCores,
		},
		remappedmetric.Metric{
			DataType:  pmetric.MetricTypeSum,
			Name:      "system.load.cores",
			Timestamp: timestamp,
			IntValue:  &numCores,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.total.norm.pct",
			Timestamp:   timestamp,
			DoubleValue: &totalNorm,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.idle.norm.pct",
			Timestamp:   timestamp,
			DoubleValue: &idleNorm,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.system.norm.pct",
			Timestamp:   timestamp,
			DoubleValue: &systemNorm,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.user.norm.pct",
			Timestamp:   timestamp,
			DoubleValue: &userNorm,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.steal.norm.pct",
			Timestamp:   timestamp,
			DoubleValue: &stealNorm,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.iowait.norm.pct",
			Timestamp:   timestamp,
			DoubleValue: &iowaitNorm,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.nice.norm.pct",
			Timestamp:   timestamp,
			DoubleValue: &niceNorm,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.irq.norm.pct",
			Timestamp:   timestamp,
			DoubleValue: &irqNorm,
		},
		remappedmetric.Metric{
			DataType:    pmetric.MetricTypeGauge,
			Name:        "system.cpu.softirq.norm.pct",
			Timestamp:   timestamp,
			DoubleValue: &softirqNorm,
		},
	)

	return nil
}