func()

in metric/system/cgroup/cgstats.go [117:151]


func (stat *StatsV2) FillPercentages(prev CGStats, curTime, prevTime time.Time) {
	if prev != nil && prev.CGVersion() != CgroupsV2 {
		return
	}
	prevStat, ok := prev.(*StatsV2)

	if !ok || prevStat == nil || stat == nil || stat.CPU == nil || prevStat.CPU == nil {
		return
	}
	timeDelta := curTime.Sub(prevTime)
	timeDeltaNanos := timeDelta / time.Nanosecond
	totalCPUDeltaNanos := int64(stat.CPU.Stats.Usage.NS - prevStat.CPU.Stats.Usage.NS)

	pct := float64(totalCPUDeltaNanos) / float64(timeDeltaNanos)

	cpuCount := numcpu.NumCPU()

	// if you look at the raw cgroup stats, the following normalized value is literally an average of per-cpu numbers.
	normalizedPct := pct / float64(cpuCount)
	userCPUDeltaMillis := int64(stat.CPU.Stats.User.NS - prevStat.CPU.Stats.User.NS)
	systemCPUDeltaMillis := int64(stat.CPU.Stats.System.NS - prevStat.CPU.Stats.System.NS)

	userPct := float64(userCPUDeltaMillis) / float64(timeDeltaNanos)
	systemPct := float64(systemCPUDeltaMillis) / float64(timeDeltaNanos)

	normalizedUser := userPct / float64(cpuCount)
	normalizedSystem := systemPct / float64(cpuCount)

	stat.CPU.Stats.Usage.Pct = opt.FloatWith(metric.Round(pct))
	stat.CPU.Stats.Usage.Norm.Pct = opt.FloatWith(metric.Round(normalizedPct))
	stat.CPU.Stats.User.Pct = opt.FloatWith(metric.Round(userPct))
	stat.CPU.Stats.User.Norm.Pct = opt.FloatWith(metric.Round(normalizedUser))
	stat.CPU.Stats.System.Pct = opt.FloatWith(metric.Round(systemPct))
	stat.CPU.Stats.System.Norm.Pct = opt.FloatWith(metric.Round(normalizedSystem))
}