func getUsingPerfCounters()

in metric/cpu/metrics_windows.go [84:129]


func getUsingPerfCounters(query *pdh.Query) (CPUMetrics, error) {
	globalMetrics := CPUMetrics{}

	if err := query.CollectData(); err != nil {
		return globalMetrics, err
	}

	kernelRawData, err := query.GetRawCounterArray(totalKernelTimeCounter, true)
	if err != nil {
		return globalMetrics, fmt.Errorf("error calling GetRawCounterArray for kernel counter: %w", err)
	}
	idleRawData, err := query.GetRawCounterArray(totalIdleTimeCounter, true)
	if err != nil {
		return globalMetrics, fmt.Errorf("error calling GetRawCounterArray for idle counter: %w", err)
	}
	userRawData, err := query.GetRawCounterArray(totalUserTimeCounter, true)
	if err != nil {
		return globalMetrics, fmt.Errorf("error calling GetRawCounterArray for user counter: %w", err)
	}
	var idle, kernel, user time.Duration
	globalMetrics.list = make([]CPU, len(userRawData))
	for i := 0; i < len(globalMetrics.list); i++ {
		// The values returned by GetRawCounterArray are of equal length and are sorted by instance names.
		// For CPU core {i}, idleRawData[i], kernelRawData[i], and userRawData[i] correspond to the idle time, kernel time, and user time, respectively.

		// values returned by counter are in 100-ns intervals. Hence, convert it to millisecond.
		idleTime := time.Duration(idleRawData[i].RawValue.FirstValue*100) / time.Millisecond
		kernelTime := time.Duration(kernelRawData[i].RawValue.FirstValue*100) / time.Millisecond
		userTime := time.Duration(userRawData[i].RawValue.FirstValue*100) / time.Millisecond

		globalMetrics.list[i].Idle = opt.UintWith(uint64(idleTime))
		globalMetrics.list[i].Sys = opt.UintWith(uint64(kernelTime))
		globalMetrics.list[i].User = opt.UintWith(uint64(userTime))

		// add the per-cpu time to track the total time spent by system
		idle += idleTime
		kernel += kernelTime
		user += userTime
	}

	globalMetrics.totals.Idle = opt.UintWith(uint64(idle))
	globalMetrics.totals.Sys = opt.UintWith(uint64(kernel))
	globalMetrics.totals.User = opt.UintWith(uint64(user))

	return globalMetrics, nil
}