Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hwmon /sensors support #278

Merged
merged 6 commits into from
Oct 6, 2016
Merged

Conversation

rtreffer
Copy link
Contributor

@rtreffer rtreffer commented Aug 9, 2016

This commit adds initial support for linux hardware sensors, exported through sysfs.
This data is commonly read via lm-sensors sensors command

Details of the interface can be found at https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface

Sensor data is exported as
node_hwmon_<sensor_type><sensor_element>
e.g. node_hwmon_temp_celsius
All extra information, like the original sensor, the input within the sensor and the possible input name are exported as labels.

Reading the data does not require any special permissions (I'm running this as my linux normal user).

On my home machine this exports (full paste at http://pastebin.com/7TR6KKVM )

node_hwmon_in_volt{hwmon="nct6776",label="in0",sensor="in0"} 0.888
node_hwmon_in_volt{hwmon="nct6776",label="in1",sensor="in1"} 1.864
node_hwmon_in_volt{hwmon="nct6776",label="in2",sensor="in2"} 3.408
node_hwmon_in_volt{hwmon="nct6776",label="in3",sensor="in3"} 3.408
node_hwmon_in_volt{hwmon="nct6776",label="in4",sensor="in4"} 0.136
node_hwmon_in_volt{hwmon="nct6776",label="in5",sensor="in5"} 1.688
node_hwmon_in_volt{hwmon="nct6776",label="in6",sensor="in6"} 0.736
node_hwmon_in_volt{hwmon="nct6776",label="in7",sensor="in7"} 3.44
node_hwmon_in_volt{hwmon="nct6776",label="in8",sensor="in8"} 3.2640000000000002

On my laptop I get e.g.

node_hwmon_fan_rpm{hwmon="applesmc_768",label="left_side",sensor="fan1"} 2156
node_hwmon_fan_rpm{hwmon="applesmc_768",label="right_side",sensor="fan2"} 1993

The workflow to generate the data is

  1. Determine all sensors (via reading the directory /sys/class/hwmon/)
  2. Determine a name, either via /sys/class/hwmon/name or by resolving /sys/class/hwmon/device
  3. For each sensors (data is always grouped by input, e.g. fan3)
    3.a) read the hwmon ./ folder
    3.b) read the hwmon device/ folder
    3.c) Dump as prometheus metrics, adding types if known (most of the updateHwmon method)

This patch will most likely need a cleanup (it is too large & could need some tests etc), but I'm opening the PR for discussion as this starts to look interesting and #211 mentions temperature data.


func init() {
Factories["hwmon"] = NewhwMonCollector
invalidMetricChars, _ = regexp.Compile("[^a-z0-9:_]")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use MustCompile instead.

@rtreffer
Copy link
Contributor Author

@brian-brazil @grobie I've worked through all the small bugs so can I have another 👀 plz?

hwMonSubsystem = "hwmon"
)

type hwMonCollector struct{}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can we keep that directly over NewHwMonCollector? I usually keep that order in go: imports, global const, global var, init, type, NewType, functions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

meta-nit: Can you add that to the contributing docs? It doesn't look like the order is documented anywhere. Maybe even try to get this into https://github.com/golang/go/wiki/CodeReviewComments

@grobie
Copy link
Member

grobie commented Aug 23, 2016

Can you please add end-to-end tests.

if err != nil {
return err
}
_ = collectSensorData(path.Join(dir, "device"), data)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't ignore this error

@discordianfish
Copy link
Member

@rtreffer This is really cool! Any chance you might find time soon to address the comments here? Would love to have this in the node-exporter!

@rtreffer
Copy link
Contributor Author

@discordianfish yes, looked into it yesterday and thought "I should fix this". Will try to get the next round going soon.

@discordianfish
Copy link
Member

@rtreffer Awesome, looking forward to it!

@rtreffer rtreffer force-pushed the hwmon_sensors branch 2 times, most recently from 67f84a3 to 79ca7f4 Compare September 17, 2016 14:21
@rtreffer
Copy link
Contributor Author

Got interrupted yesterday, but managed to go with a split-by-regex approach and fixing all those silly tyops. Still have to build the end-to-end test, though.

@juliusv
Copy link
Member

juliusv commented Sep 17, 2016

@rtreffer Not sure if you've already looked at it, but the mentioned end-to-end tests are super easy. See https://github.com/prometheus/node_exporter/blob/master/end-to-end-test.sh

Just add the relevant sysfs files to https://github.com/prometheus/node_exporter/tree/master/collector/fixtures and update the expected output in https://github.com/prometheus/node_exporter/blob/master/collector/fixtures/e2e-output.txt.

@juliusv
Copy link
Member

juliusv commented Sep 17, 2016

(and enable that collector in the end-to-end-test.sh)

@rtreffer
Copy link
Contributor Author

rtreffer commented Sep 25, 2016

Ok, I need at least 2 sensors as 2 layouts are possible:

  • Old driver have their data under the device folder
  • Newer drivers use the hwmon/hwmonX folder

Besides that it's a mix of some of the reading I got on a few machines.

@rtreffer rtreffer changed the title [WIP] Add hwmon /sensors support Add hwmon /sensors support Sep 26, 2016
@rtreffer
Copy link
Contributor Author

@juliusv / @brian-brazil anything else?

continue
}

// fallback, just dump
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments should be full sentences.

label = sensor
}
}
labels := []string{hwmonName, sensor, label}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we should expose both the sensor and label, just the label should do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll give it a try on a few machines, if it works with just label I'd change to that. In theory it could fail with "bad" drivers, but I'm not sure if such drivers exist (sensor is guaranteed to be unique, label not).

@rtreffer
Copy link
Contributor Author

@brian-brazil updated. Couldn't see issue when dropping sensor, but I have only a limited sample size.

var (
hwmonInvalidMetricChars = regexp.MustCompile("[^a-z0-9:_]")
hwmonFilenameFormat = regexp.MustCompile(`^(?P<type>[^0-9]+)(?P<id>[0-9]*)?(_(?P<property>.+))?$`)
hwmonLabelDesc = []string{"chip", "sensorName"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it can just be sensor now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure thing.

@@ -31,7 +31,7 @@ import (
)

const (
defaultCollectors = "conntrack,cpu,diskstats,entropy,filefd,filesystem,loadavg,mdadm,meminfo,netdev,netstat,sockstat,stat,textfile,time,uname,vmstat"
defaultCollectors = "conntrack,cpu,diskstats,entropy,filefd,filesystem,hwmon,loadavg,mdadm,meminfo,netdev,netstat,sockstat,stat,textfile,time,uname,vmstat"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README needs updating too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's just the one-line I've added, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

@rtreffer
Copy link
Contributor Author

rtreffer commented Oct 6, 2016

So anything else?

@brian-brazil brian-brazil merged commit 081ecc5 into prometheus:master Oct 6, 2016
@brian-brazil
Copy link
Contributor

Thanks!

@SuperQ SuperQ mentioned this pull request Nov 6, 2016
mcdan pushed a commit to mcdan/node_exporter that referenced this pull request Nov 15, 2016
* Add hwmon support (mainly known from lm-sensors)

This commit adds initial support for linux hardware sensors, exported
through sysfs.

Details of the interface can be found at
https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface

* Add end-to-end test with some real life data

* Cleanup comments on hwmon collector

* Drop raw sensor name from hwmon output

* Let the sensor label be "sensor"

* Add hwmon short description to README.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants