From 782eaee100be8baf7f10d06b2a98dcb383047168 Mon Sep 17 00:00:00 2001 From: Dominik Honnef Date: Fri, 30 Dec 2016 07:31:08 +0100 Subject: [PATCH 1/2] Collect CPU temperatures on FreeBSD --- collector/cpu_freebsd.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/collector/cpu_freebsd.go b/collector/cpu_freebsd.go index 11a9b33e..0ec0a1d1 100644 --- a/collector/cpu_freebsd.go +++ b/collector/cpu_freebsd.go @@ -16,6 +16,7 @@ package collector import ( + "fmt" "strconv" "unsafe" @@ -78,7 +79,8 @@ func getCPUTimes() ([]cputime, error) { } type statCollector struct { - cpu typedDesc + cpu typedDesc + temp typedDesc } func init() { @@ -94,6 +96,11 @@ func NewStatCollector() (Collector, error) { "Seconds the CPU spent in each mode.", []string{"cpu", "mode"}, nil, ), prometheus.CounterValue}, + temp: typedDesc{prometheus.NewDesc( + prometheus.BuildFQName(Namespace, "cpu", "temperature_celsius"), + "CPU temperature", + []string{"cpu"}, nil, + ), prometheus.GaugeValue}, }, nil } @@ -115,11 +122,18 @@ func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) { return err } for cpu, t := range cpuTimes { - ch <- c.cpu.mustNewConstMetric(float64(t.user), strconv.Itoa(cpu), "user") - ch <- c.cpu.mustNewConstMetric(float64(t.nice), strconv.Itoa(cpu), "nice") - ch <- c.cpu.mustNewConstMetric(float64(t.sys), strconv.Itoa(cpu), "system") - ch <- c.cpu.mustNewConstMetric(float64(t.intr), strconv.Itoa(cpu), "interrupt") - ch <- c.cpu.mustNewConstMetric(float64(t.idle), strconv.Itoa(cpu), "idle") + lcpu := strconv.Itoa(cpu) + ch <- c.cpu.mustNewConstMetric(float64(t.user), lcpu, "user") + ch <- c.cpu.mustNewConstMetric(float64(t.nice), lcpu, "nice") + ch <- c.cpu.mustNewConstMetric(float64(t.sys), lcpu, "system") + ch <- c.cpu.mustNewConstMetric(float64(t.intr), lcpu, "interrupt") + ch <- c.cpu.mustNewConstMetric(float64(t.idle), lcpu, "idle") + + temp, err := unix.SysctlUint32(fmt.Sprintf("dev.cpu.%d.temperature", cpu)) + if err == nil { + ftemp := float64(temp-2732) / 10 + ch <- c.temp.mustNewConstMetric(ftemp, lcpu) + } } return err } From d827db8e1728c80ce295bb9a4c25b76c33e77264 Mon Sep 17 00:00:00 2001 From: Dominik Honnef Date: Thu, 5 Jan 2017 06:47:13 +0100 Subject: [PATCH 2/2] Better error handling when collecting CPU temps Log why we couldn't collect the temperature, and set metric to NaN if the CPU should support temperature collection but had an error. --- collector/cpu_freebsd.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/collector/cpu_freebsd.go b/collector/cpu_freebsd.go index 0ec0a1d1..adbdfcf7 100644 --- a/collector/cpu_freebsd.go +++ b/collector/cpu_freebsd.go @@ -17,10 +17,12 @@ package collector import ( "fmt" + "math" "strconv" "unsafe" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/log" "golang.org/x/sys/unix" ) @@ -130,10 +132,18 @@ func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) { ch <- c.cpu.mustNewConstMetric(float64(t.idle), lcpu, "idle") temp, err := unix.SysctlUint32(fmt.Sprintf("dev.cpu.%d.temperature", cpu)) - if err == nil { - ftemp := float64(temp-2732) / 10 - ch <- c.temp.mustNewConstMetric(ftemp, lcpu) + if err != nil { + if err == unix.ENOENT { + // No temperature information for this CPU + log.Debugf("no temperature information for CPU %d", cpu) + } else { + // Unexpected error + ch <- c.temp.mustNewConstMetric(math.NaN(), lcpu) + log.Errorf("failed to query CPU temperature for CPU %d: %s", cpu, err) + } + continue } + ch <- c.temp.mustNewConstMetric(float64(temp-2732)/10, lcpu) } return err }