bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/scollector/collectors/cpu_windows.go (about) 1 package collectors 2 3 import ( 4 "strings" 5 6 "bosun.org/metadata" 7 "bosun.org/opentsdb" 8 "github.com/StackExchange/wmi" 9 ) 10 11 func init() { 12 collectors = append(collectors, &IntervalCollector{F: c_cpu_windows}) 13 collectors = append(collectors, &IntervalCollector{F: c_cpu_info_windows}) 14 } 15 16 func c_cpu_windows() (opentsdb.MultiDataPoint, error) { 17 var dst []Win32_PerfRawData_PerfOS_Processor 18 var q = wmi.CreateQuery(&dst, "") 19 err := queryWmi(q, &dst) 20 if err != nil { 21 return nil, err 22 } 23 var md opentsdb.MultiDataPoint 24 var used, num uint64 25 var winCPUTotalPerfOS *Win32_PerfRawData_PerfOS_Processor 26 for _, v := range dst { 27 if v.Name == "_Total" { 28 winCPUTotalPerfOS = &v 29 continue 30 } 31 ts := TSys100NStoEpoch(v.Timestamp_Sys100NS) 32 tags := opentsdb.TagSet{"cpu": v.Name} 33 num++ 34 //Divide by 1e5 because: 1 seconds / 100 Nanoseconds = 1e7. This is the percent time as a decimal, so divide by two less zeros to make it the same as the result * 100. 35 used += (v.PercentUserTime + v.PercentPrivilegedTime + v.PercentInterruptTime) / 1e5 36 AddTS(&md, winCPU, ts, v.PercentPrivilegedTime/1e5, opentsdb.TagSet{"type": "privileged"}.Merge(tags), metadata.Counter, metadata.Pct, descWinCPUPrivileged) 37 AddTS(&md, winCPU, ts, v.PercentInterruptTime/1e5, opentsdb.TagSet{"type": "interrupt"}.Merge(tags), metadata.Counter, metadata.Pct, descWinCPUInterrupt) 38 AddTS(&md, winCPU, ts, v.PercentUserTime/1e5, opentsdb.TagSet{"type": "user"}.Merge(tags), metadata.Counter, metadata.Pct, descWinCPUUser) 39 AddTS(&md, winCPU, ts, v.PercentIdleTime/1e5, opentsdb.TagSet{"type": "idle"}.Merge(tags), metadata.Counter, metadata.Pct, descWinCPUIdle) 40 AddTS(&md, "win.cpu.interrupts", ts, v.InterruptsPersec, tags, metadata.Counter, metadata.Event, descWinCPUInterrupts) 41 Add(&md, "win.cpu.dpcs", v.DPCRate, tags, metadata.Gauge, metadata.Event, descWinCPUDPC) 42 } 43 if num > 0 { 44 cpu := used / num 45 Add(&md, osCPU, cpu, nil, metadata.Counter, metadata.Pct, "") 46 } 47 if winCPUTotalPerfOS != nil { 48 v := winCPUTotalPerfOS 49 ts := TSys100NStoEpoch(v.Timestamp_Sys100NS) 50 AddTS(&md, winCPUTotal, ts, v.PercentPrivilegedTime/1e5, opentsdb.TagSet{"type": "privileged"}, metadata.Counter, metadata.Pct, descWinCPUPrivileged) 51 AddTS(&md, winCPUTotal, ts, v.PercentInterruptTime/1e5, opentsdb.TagSet{"type": "interrupt"}, metadata.Counter, metadata.Pct, descWinCPUInterrupt) 52 AddTS(&md, winCPUTotal, ts, v.PercentUserTime/1e5, opentsdb.TagSet{"type": "user"}, metadata.Counter, metadata.Pct, descWinCPUUser) 53 AddTS(&md, winCPUTotal, ts, v.PercentIdleTime/1e5, opentsdb.TagSet{"type": "idle"}, metadata.Counter, metadata.Pct, descWinCPUIdle) 54 AddTS(&md, "win.cpu_total.interrupts", ts, v.InterruptsPersec, nil, metadata.Counter, metadata.Event, descWinCPUInterrupts) 55 Add(&md, "win.cpu_total.dpcs", v.DPCRate, nil, metadata.Gauge, metadata.Event, descWinCPUDPC) 56 AddTS(&md, winCPUCStates, ts, v.PercentC1Time/1e5, opentsdb.TagSet{"cpu": "total", "type": "c1"}, metadata.Counter, metadata.Pct, descWinCPUC1) 57 AddTS(&md, winCPUCStates, ts, v.PercentC2Time/1e5, opentsdb.TagSet{"cpu": "total", "type": "c2"}, metadata.Counter, metadata.Pct, descWinCPUC2) 58 AddTS(&md, winCPUCStates, ts, v.PercentC3Time/1e5, opentsdb.TagSet{"cpu": "total", "type": "c3"}, metadata.Counter, metadata.Pct, descWinCPUC3) 59 } 60 return md, nil 61 } 62 63 const ( 64 winCPU = "win.cpu" 65 winCPUTotal = "win.cpu_total" 66 winCPUCStates = "win.cpu.time_cstate" 67 descWinCPUPrivileged = "Percentage of non-idle processor time spent in privileged mode." 68 descWinCPUInterrupt = "Percentage of time that the processor spent receiving and servicing hardware interrupts during the sample interval." 69 descWinCPUUser = "Percentage of non-idle processor time spent in user mode." 70 descWinCPUIdle = "Percentage of time during the sample interval that the processor was idle." 71 descWinCPUInterrupts = "Average number of hardware interrupts that the processor is receiving and servicing in each second." 72 descWinCPUDPC = "Rate at which deferred procedure calls (DPCs) are added to the processor DPC queue between the timer tics of the processor clock." 73 descWinCPUC1 = "Percentage of time that the processor spends in the C1 low-power idle state, which is a subset of the total processor idle time." 74 descWinCPUC2 = "Percentage of time that the processor spends in the C-2 low-power idle state, which is a subset of the total processor idle time." 75 descWinCPUC3 = "Percentage of time that the processor spends in the C3 low-power idle state, which is a subset of the total processor idle time." 76 ) 77 78 type Win32_PerfRawData_PerfOS_Processor struct { 79 DPCRate uint32 80 InterruptsPersec uint32 81 Name string 82 PercentC1Time uint64 83 Timestamp_Sys100NS uint64 84 PercentC2Time uint64 85 PercentC3Time uint64 86 PercentIdleTime uint64 87 PercentInterruptTime uint64 88 PercentPrivilegedTime uint64 89 PercentProcessorTime uint64 90 PercentUserTime uint64 91 } 92 93 func c_cpu_info_windows() (opentsdb.MultiDataPoint, error) { 94 var dst []Win32_Processor 95 var q = wmi.CreateQuery(&dst, `WHERE Name <> '_Total'`) 96 err := queryWmi(q, &dst) 97 if err != nil { 98 return nil, err 99 } 100 var md opentsdb.MultiDataPoint 101 for _, v := range dst { 102 tags := opentsdb.TagSet{"cpu": strings.Replace(v.DeviceID, "CPU", "", 1)} 103 Add(&md, osCPUClock, v.CurrentClockSpeed, tags, metadata.Gauge, metadata.MHz, osCPUClockDesc) 104 Add(&md, "win.cpu.clock", v.CurrentClockSpeed, tags, metadata.Gauge, metadata.MHz, descWinCPUClock) 105 Add(&md, "win.cpu.clock_max", v.MaxClockSpeed, tags, metadata.Gauge, metadata.MHz, descWinCPUClockMax) 106 Add(&md, "win.cpu.voltage", v.CurrentVoltage, tags, metadata.Gauge, metadata.V10, descWinCPUVoltage) 107 Add(&md, "win.cpu.cores_physical", v.NumberOfCores, tags, metadata.Gauge, metadata.Count, descWinCPUCores) 108 Add(&md, "win.cpu.cores_logical", v.NumberOfLogicalProcessors, tags, metadata.Gauge, metadata.Count, descWinCPUCoresLogical) 109 if v.LoadPercentage != nil { 110 Add(&md, "win.cpu.load", *v.LoadPercentage, tags, metadata.Gauge, metadata.Pct, descWinCPULoad) 111 } 112 } 113 return md, nil 114 } 115 116 const ( 117 descWinCPUClock = "Current speed of the processor, in MHz." 118 descWinCPUClockMax = "Maximum speed of the processor, in MHz." 119 descWinCPUVoltage = "Voltage of the processor." 120 descWinCPUCores = "Number of cores for the current instance of the processor." 121 descWinCPUCoresLogical = "Number of logical processors for the current instance of the processor." 122 descWinCPULoad = "Load capacity of each processor, averaged to the last second." 123 ) 124 125 type Win32_Processor struct { 126 CurrentClockSpeed uint32 127 CurrentVoltage *uint16 128 LoadPercentage *uint16 129 MaxClockSpeed uint32 130 DeviceID string 131 NumberOfCores uint32 132 NumberOfLogicalProcessors uint32 133 }