Please help me with CPU temp metric collection for FreeBSD

789 views
Skip to first unread message

john.ma...@gmail.com

unread,
May 11, 2018, 12:49:44 PM5/11/18
to Prometheus Users
Hello all,

I have struggled for weeks trying to figure this one out.  I even took a course on learning Go (thank you Todd McLeod!) for this and future endeavors.  I have a working shell script which reports the CPU and drive temperatures using a CRON job but I would like to have that data collected, visualized, and alerting within a more comprehensive/configurable monitoring system.  Looking forward, I chose Prometheus as that tool and as part of the ongoing learning/labbing.  Using steps from https://blog.yo61.com/installing-prometheus-node_exporter-on-freenas/ I was abke to run the node_exporter on FreeNAS, however, it reported the CPU temperature as 400,000,000 degrees Centigrade.  I have gone so far as to write my own collector using the converted functions (os/exec calls) from the shell script, but have come back to you to reconsider the path of least resistance.  Within the collector cpu_freebsd.go we have line 129 (within the method described and defined on 104 and 105):

Line 104: // Expose CPU stats using sysctl.
Line 105: func (c *statCollector) Update(ch chan<- prometheus.Metric) error {
...
Line 129: temp, err := unix.SysctlUint32(fmt.Sprintf("dev.cpu.%d.temperature", cpu))

What is this Sprintf even pulling from?  I get that it is taking the data and converting it to base 10, then to Uint32, but how are we getting 400M C?  Later on line 143 of the same file we have

Line 143: ch <- c.temp.mustNewConstMetric(float64(temp-2732)/10, lcpu)

Again, what in the world is this conversion?  Looking back, "cpu" from line 129, is taken from the cpuTimes array defined below (created and then looped over) in lines 117-121

    cpuTimes, err := getCPUTimes()
    if err != nil {
        return err
    }
    for cpu, t := range cpuTimes {

and this is where I get a bit lost.  I dont see the temperature defind in cpuTimes() of NewStatCollector().  If we look in golang.org\sys\unix\syscall_bsd.go we find the SysctlUint32(name string) function, lines 457-476, below

func SysctlUint32(name string) (uint32, error) {
    return SysctlUint32Args(name)
}

func SysctlUint32Args(name string, args ...int) (uint32, error) {
    mib, err := sysctlmib(name, args...)
    if err != nil {
        return 0, err
    }

    n := uintptr(4)
    buf := make([]byte, 4)
    if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
        return 0, err
    }
    if n != 4 {
        return 0, EIO
    }
    return *(*uint32)(unsafe.Pointer(&buf[0])), nil
}

Getting thick into the weeds here and not sure where to go.  I don't see the call to Sysctl, but it gives me a place to start.  I am booting the machine and will try to just run Sysctl to see what that gives.  That alone may be the issue.  The custom collector I wrote can be found here - https://forums.freenas.org/index.php?threads/custom-metric-collector-for-prometheus-node-exporter.63462/ - and eventually on github.  Realizing that I may split the CPU and Drive temps into two files anyway, I may look at simply using IPMI exporter first to get it working if I cant get the node_exporter fixed.



Still a little lost.  It may be time to make a custom exporter with my one custom collector once I figure out how to get that working.  Any advice or help is greatly appreciated
Auto Generated Inline Image 1
Auto Generated Inline Image 2

john.ma...@gmail.com

unread,
May 11, 2018, 12:55:45 PM5/11/18
to Prometheus Users
Here is the picture of the 400 M metric
Auto Generated Inline Image 1

john.ma...@gmail.com

unread,
May 15, 2018, 1:54:10 PM5/15/18
to Prometheus Users
Alright so I sidestepped this by making my own custom collector that compiles but does not run.  If someone could take a look and see if you can spot anything obvious.  When I run the "go build -v -x main.go freenascollector.go" it does not seem to build nearly as many dependencies as seems needed (all the Prometheus files).


When I run this command on FreeNAS I get 
./main: line 7: syntax error nearnexpected token'newline'
./main: line7:'<DOCTYPE html>'

Note, this does run when I use FreeBSD to fetch the port of node_collector, make the package, and then run the package on FreeNAS
I also went ahead and created https://github.com/prometheus/node_exporter/issues/945 for this.  I know why the 400M is there now, but not sure why sysctl is pulling the -1 on FreeNAS.  I hope to get around this with my custom exporter.

john.ma...@gmail.com

unread,
May 15, 2018, 2:55:09 PM5/15/18
to Prometheus Users
Build using only "go build -x -v" and it built the entire package with dependencies, or at least it looked that way, but I am receiving the same error.

john.ma...@gmail.com

unread,
May 16, 2018, 11:06:53 AM5/16/18
to Prometheus Users
I neglected to mention that FreeNAS is running as a VM on ESXI 6.5.  This is likely the source of the problem.  I am, however, making progress with a custom collector or exporter that will use IPMI for the CPU temp.

John Fox

unread,
Jun 9, 2018, 11:04:48 AM6/9/18
to Prometheus Users

John Fox

unread,
Aug 2, 2018, 4:41:15 PM8/2/18
to Prometheus Users
For what its worth I got the script working.  Thanks to Brian for helping out.  Your emails and book finally helped it "click".  I realize it could or should have happened a while ago, but I have learned a lot thus far and will keep churnin away.  Thank you all.
Reply all
Reply to author
Forward
0 new messages