func()

in metric/system/cgroup/cgstats.go [57:96]


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

	if !ok || prevStat == nil || stat == nil || stat.CPUAccounting == nil || prevStat.CPUAccounting == nil {
		return
	}

	timeDelta := curTime.Sub(prevTime)
	timeDeltaNanos := timeDelta / time.Nanosecond
	totalCPUDeltaNanos := int64(stat.CPUAccounting.Total.NS - prevStat.CPUAccounting.Total.NS)

	pct := float64(totalCPUDeltaNanos) / float64(timeDeltaNanos)
	var cpuCount int
	if len(stat.CPUAccounting.UsagePerCPU) > 0 {
		cpuCount = len(stat.CPUAccounting.UsagePerCPU)
	} else {
		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.CPUAccounting.Stats.User.NS - prevStat.CPUAccounting.Stats.User.NS)
	systemCPUDeltaMillis := int64(stat.CPUAccounting.Stats.System.NS - prevStat.CPUAccounting.Stats.System.NS)

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

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

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