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  }