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
}