// Expose CPU stats using KVM. func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) { if os.Geteuid() != 0 && os.Getegid() != 2 { return errors.New("caller should be either root user or kmem group to access /dev/mem") } var errbuf *C.char kd := C.kvm_open(nil, nil, nil, C.O_RDONLY, errbuf) if errbuf != nil { return errors.New("failed to call kvm_open()") } defer C.kvm_close(kd) // The cp_time variable is an array of CPUSTATES long integers -- in // the same format as the kern.cp_time sysctl. According to the // comments in sys/kern/kern_clock.c, the frequency of this timer will // be stathz (or hz, if stathz is zero). clockrate, err := getClockRate() if err != nil { return err } ncpus := C.kvm_getncpus(kd) for i := 0; i < int(ncpus); i++ { pcpu := C.kvm_getpcpu(kd, C.int(i)) cp_time := ((*C.struct_pcpu)(unsafe.Pointer(pcpu))).pc_cp_time c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "user"}).Set(float64(cp_time[C.CP_USER]) / clockrate) c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "nice"}).Set(float64(cp_time[C.CP_NICE]) / clockrate) c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "system"}).Set(float64(cp_time[C.CP_SYS]) / clockrate) c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "interrupt"}).Set(float64(cp_time[C.CP_INTR]) / clockrate) c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "idle"}).Set(float64(cp_time[C.CP_IDLE]) / clockrate) } c.cpu.Collect(ch) return err }
// Expose CPU stats using KVM. func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) { if os.Geteuid() != 0 && os.Getegid() != 2 { return errors.New("caller should be either root user or kmem group to access /dev/mem") } var errbuf *C.char kd := C.kvm_open(nil, nil, nil, C.O_RDONLY, errbuf) if errbuf != nil { return errors.New("failed to call kvm_open()") } defer C.kvm_close(kd) ncpus := C.kvm_getncpus(kd) for i := 0; i < int(ncpus); i++ { pcpu := C.kvm_getpcpu(kd, C.int(i)) cp_time := ((*C.struct_pcpu)(unsafe.Pointer(pcpu))).pc_cp_time c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "user"}).Set(float64(cp_time[C.CP_USER])) c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "nice"}).Set(float64(cp_time[C.CP_NICE])) c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "system"}).Set(float64(cp_time[C.CP_SYS])) c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "interrupt"}).Set(float64(cp_time[C.CP_INTR])) c.cpu.With(prometheus.Labels{"cpu": strconv.Itoa(i), "mode": "idle"}).Set(float64(cp_time[C.CP_IDLE])) } c.cpu.Collect(ch) return err }