Add hwmon /sensors support (#278)

* 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.
This commit is contained in:
Rene Treffer 2016-10-06 17:33:24 +02:00 committed by Brian Brazil
parent cf3710191a
commit 081ecc5db0
99 changed files with 753 additions and 79 deletions

View File

@ -24,6 +24,7 @@ diskstats | Exposes disk I/O statistics from `/proc/diskstats`. | Linux
entropy | Exposes available entropy. | Linux
filefd | Exposes file descriptor statistics from `/proc/sys/fs/file-nr`. | Linux
filesystem | Exposes filesystem statistics, such as disk space used. | FreeBSD, Dragonfly, Linux, OpenBSD
hwmon | Expose hardware monitoring and sensor data from `/sys/class/hwmon/`. | Linux
loadavg | Exposes load average. | Darwin, Dragonfly, FreeBSD, Linux, NetBSD, OpenBSD, Solaris
mdadm | Exposes statistics about devices in `/proc/mdstat` (does nothing if no `/proc/mdstat` present). | Linux
meminfo | Exposes memory statistics. | Dragonfly, FreeBSD, Linux

View File

@ -12,73 +12,73 @@ go_gc_duration_seconds_count 0
go_goroutines 13
# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.
# TYPE go_memstats_alloc_bytes gauge
go_memstats_alloc_bytes 1.077136e+06
go_memstats_alloc_bytes 1.236968e+06
# HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed.
# TYPE go_memstats_alloc_bytes_total counter
go_memstats_alloc_bytes_total 1.077136e+06
go_memstats_alloc_bytes_total 1.236968e+06
# HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table.
# TYPE go_memstats_buck_hash_sys_bytes gauge
go_memstats_buck_hash_sys_bytes 1.443406e+06
go_memstats_buck_hash_sys_bytes 2717
# HELP go_memstats_frees_total Total number of frees.
# TYPE go_memstats_frees_total counter
go_memstats_frees_total 0
go_memstats_frees_total 265
# HELP go_memstats_gc_sys_bytes Number of bytes used for garbage collection system metadata.
# TYPE go_memstats_gc_sys_bytes gauge
go_memstats_gc_sys_bytes 98304
go_memstats_gc_sys_bytes 65536
# HELP go_memstats_heap_alloc_bytes Number of heap bytes allocated and still in use.
# TYPE go_memstats_heap_alloc_bytes gauge
go_memstats_heap_alloc_bytes 1.077136e+06
go_memstats_heap_alloc_bytes 1.236968e+06
# HELP go_memstats_heap_idle_bytes Number of heap bytes waiting to be used.
# TYPE go_memstats_heap_idle_bytes gauge
go_memstats_heap_idle_bytes 737280
go_memstats_heap_idle_bytes 139264
# HELP go_memstats_heap_inuse_bytes Number of heap bytes that are in use.
# TYPE go_memstats_heap_inuse_bytes gauge
go_memstats_heap_inuse_bytes 1.916928e+06
go_memstats_heap_inuse_bytes 1.630208e+06
# HELP go_memstats_heap_objects Number of allocated objects.
# TYPE go_memstats_heap_objects gauge
go_memstats_heap_objects 4245
go_memstats_heap_objects 8119
# HELP go_memstats_heap_released_bytes_total Total number of heap bytes released to OS.
# TYPE go_memstats_heap_released_bytes_total counter
go_memstats_heap_released_bytes_total 0
# HELP go_memstats_heap_sys_bytes Number of heap bytes obtained from system.
# TYPE go_memstats_heap_sys_bytes gauge
go_memstats_heap_sys_bytes 2.654208e+06
go_memstats_heap_sys_bytes 1.769472e+06
# HELP go_memstats_last_gc_time_seconds Number of seconds since 1970 of last garbage collection.
# TYPE go_memstats_last_gc_time_seconds gauge
go_memstats_last_gc_time_seconds 9
# HELP go_memstats_lookups_total Total number of pointer lookups.
# TYPE go_memstats_lookups_total counter
go_memstats_lookups_total 16
go_memstats_lookups_total 9
# HELP go_memstats_mallocs_total Total number of mallocs.
# TYPE go_memstats_mallocs_total counter
go_memstats_mallocs_total 4245
go_memstats_mallocs_total 8384
# HELP go_memstats_mcache_inuse_bytes Number of bytes in use by mcache structures.
# TYPE go_memstats_mcache_inuse_bytes gauge
go_memstats_mcache_inuse_bytes 9664
go_memstats_mcache_inuse_bytes 9600
# HELP go_memstats_mcache_sys_bytes Number of bytes used for mcache structures obtained from system.
# TYPE go_memstats_mcache_sys_bytes gauge
go_memstats_mcache_sys_bytes 16384
# HELP go_memstats_mspan_inuse_bytes Number of bytes in use by mspan structures.
# TYPE go_memstats_mspan_inuse_bytes gauge
go_memstats_mspan_inuse_bytes 18144
go_memstats_mspan_inuse_bytes 16080
# HELP go_memstats_mspan_sys_bytes Number of bytes used for mspan structures obtained from system.
# TYPE go_memstats_mspan_sys_bytes gauge
go_memstats_mspan_sys_bytes 32768
go_memstats_mspan_sys_bytes 16384
# HELP go_memstats_next_gc_bytes Number of heap bytes when next garbage collection will take place.
# TYPE go_memstats_next_gc_bytes gauge
go_memstats_next_gc_bytes 4.194304e+06
# HELP go_memstats_other_sys_bytes Number of bytes used for other system allocations.
# TYPE go_memstats_other_sys_bytes gauge
go_memstats_other_sys_bytes 1.065642e+06
go_memstats_other_sys_bytes 558435
# HELP go_memstats_stack_inuse_bytes Number of bytes in use by the stack allocator.
# TYPE go_memstats_stack_inuse_bytes gauge
go_memstats_stack_inuse_bytes 491520
go_memstats_stack_inuse_bytes 327680
# HELP go_memstats_stack_sys_bytes Number of bytes obtained from system for stack allocator.
# TYPE go_memstats_stack_sys_bytes gauge
go_memstats_stack_sys_bytes 491520
go_memstats_stack_sys_bytes 327680
# HELP go_memstats_sys_bytes Number of bytes obtained by system. Sum of all system allocations.
# TYPE go_memstats_sys_bytes gauge
go_memstats_sys_bytes 5.802232e+06
go_memstats_sys_bytes 2.756608e+06
# HELP http_request_duration_microseconds The HTTP request latencies in microseconds.
# TYPE http_request_duration_microseconds summary
http_request_duration_microseconds{handler="prometheus",quantile="0.5"} NaN
@ -380,73 +380,93 @@ node_disk_writes_merged{device="vda"} 2.0711856e+07
node_entropy_available_bits 1337
# HELP node_exporter_build_info A metric with a constant '1' value labeled by version, revision, branch, and goversion from which node_exporter was built.
# TYPE node_exporter_build_info gauge
node_exporter_build_info{branch="master",goversion="go1.5.4",revision="252feb6",version="0.12.0rc3"} 1
node_exporter_build_info{branch="",goversion="go1.6.2",revision="",version=""} 1
# HELP node_exporter_scrape_duration_seconds node_exporter: Duration of a scrape job.
# TYPE node_exporter_scrape_duration_seconds summary
node_exporter_scrape_duration_seconds{collector="bonding",result="success",quantile="0.5"} 7.481600000000001e-05
node_exporter_scrape_duration_seconds{collector="bonding",result="success",quantile="0.9"} 7.481600000000001e-05
node_exporter_scrape_duration_seconds{collector="bonding",result="success",quantile="0.99"} 7.481600000000001e-05
node_exporter_scrape_duration_seconds_sum{collector="bonding",result="success"} 7.481600000000001e-05
node_exporter_scrape_duration_seconds{collector="bonding",result="success",quantile="0.5"} 0.00019123300000000002
node_exporter_scrape_duration_seconds{collector="bonding",result="success",quantile="0.9"} 0.00019123300000000002
node_exporter_scrape_duration_seconds{collector="bonding",result="success",quantile="0.99"} 0.00019123300000000002
node_exporter_scrape_duration_seconds_sum{collector="bonding",result="success"} 0.00019123300000000002
node_exporter_scrape_duration_seconds_count{collector="bonding",result="success"} 1
node_exporter_scrape_duration_seconds{collector="conntrack",result="success",quantile="0.5"} 0.00027974200000000003
node_exporter_scrape_duration_seconds{collector="conntrack",result="success",quantile="0.9"} 0.00027974200000000003
node_exporter_scrape_duration_seconds{collector="conntrack",result="success",quantile="0.99"} 0.00027974200000000003
node_exporter_scrape_duration_seconds_sum{collector="conntrack",result="success"} 0.00027974200000000003
node_exporter_scrape_duration_seconds{collector="conntrack",result="success",quantile="0.5"} 3.1222e-05
node_exporter_scrape_duration_seconds{collector="conntrack",result="success",quantile="0.9"} 3.1222e-05
node_exporter_scrape_duration_seconds{collector="conntrack",result="success",quantile="0.99"} 3.1222e-05
node_exporter_scrape_duration_seconds_sum{collector="conntrack",result="success"} 3.1222e-05
node_exporter_scrape_duration_seconds_count{collector="conntrack",result="success"} 1
node_exporter_scrape_duration_seconds{collector="diskstats",result="success",quantile="0.5"} 0.001661895
node_exporter_scrape_duration_seconds{collector="diskstats",result="success",quantile="0.9"} 0.001661895
node_exporter_scrape_duration_seconds{collector="diskstats",result="success",quantile="0.99"} 0.001661895
node_exporter_scrape_duration_seconds_sum{collector="diskstats",result="success"} 0.001661895
node_exporter_scrape_duration_seconds{collector="diskstats",result="success",quantile="0.5"} 0.001207839
node_exporter_scrape_duration_seconds{collector="diskstats",result="success",quantile="0.9"} 0.001207839
node_exporter_scrape_duration_seconds{collector="diskstats",result="success",quantile="0.99"} 0.001207839
node_exporter_scrape_duration_seconds_sum{collector="diskstats",result="success"} 0.001207839
node_exporter_scrape_duration_seconds_count{collector="diskstats",result="success"} 1
node_exporter_scrape_duration_seconds{collector="filefd",result="success",quantile="0.5"} 0.000146396
node_exporter_scrape_duration_seconds{collector="filefd",result="success",quantile="0.9"} 0.000146396
node_exporter_scrape_duration_seconds{collector="filefd",result="success",quantile="0.99"} 0.000146396
node_exporter_scrape_duration_seconds_sum{collector="filefd",result="success"} 0.000146396
node_exporter_scrape_duration_seconds{collector="entropy",result="success",quantile="0.5"} 2.1329000000000002e-05
node_exporter_scrape_duration_seconds{collector="entropy",result="success",quantile="0.9"} 2.1329000000000002e-05
node_exporter_scrape_duration_seconds{collector="entropy",result="success",quantile="0.99"} 2.1329000000000002e-05
node_exporter_scrape_duration_seconds_sum{collector="entropy",result="success"} 2.1329000000000002e-05
node_exporter_scrape_duration_seconds_count{collector="entropy",result="success"} 1
node_exporter_scrape_duration_seconds{collector="filefd",result="success",quantile="0.5"} 3.7313e-05
node_exporter_scrape_duration_seconds{collector="filefd",result="success",quantile="0.9"} 3.7313e-05
node_exporter_scrape_duration_seconds{collector="filefd",result="success",quantile="0.99"} 3.7313e-05
node_exporter_scrape_duration_seconds_sum{collector="filefd",result="success"} 3.7313e-05
node_exporter_scrape_duration_seconds_count{collector="filefd",result="success"} 1
node_exporter_scrape_duration_seconds{collector="loadavg",result="success",quantile="0.5"} 6.1362e-05
node_exporter_scrape_duration_seconds{collector="loadavg",result="success",quantile="0.9"} 6.1362e-05
node_exporter_scrape_duration_seconds{collector="loadavg",result="success",quantile="0.99"} 6.1362e-05
node_exporter_scrape_duration_seconds_sum{collector="loadavg",result="success"} 6.1362e-05
node_exporter_scrape_duration_seconds{collector="hwmon",result="success",quantile="0.5"} 0.002039698
node_exporter_scrape_duration_seconds{collector="hwmon",result="success",quantile="0.9"} 0.002039698
node_exporter_scrape_duration_seconds{collector="hwmon",result="success",quantile="0.99"} 0.002039698
node_exporter_scrape_duration_seconds_sum{collector="hwmon",result="success"} 0.002039698
node_exporter_scrape_duration_seconds_count{collector="hwmon",result="success"} 1
node_exporter_scrape_duration_seconds{collector="ksmd",result="success",quantile="0.5"} 9.497000000000001e-05
node_exporter_scrape_duration_seconds{collector="ksmd",result="success",quantile="0.9"} 9.497000000000001e-05
node_exporter_scrape_duration_seconds{collector="ksmd",result="success",quantile="0.99"} 9.497000000000001e-05
node_exporter_scrape_duration_seconds_sum{collector="ksmd",result="success"} 9.497000000000001e-05
node_exporter_scrape_duration_seconds_count{collector="ksmd",result="success"} 1
node_exporter_scrape_duration_seconds{collector="loadavg",result="success",quantile="0.5"} 0.00030610500000000004
node_exporter_scrape_duration_seconds{collector="loadavg",result="success",quantile="0.9"} 0.00030610500000000004
node_exporter_scrape_duration_seconds{collector="loadavg",result="success",quantile="0.99"} 0.00030610500000000004
node_exporter_scrape_duration_seconds_sum{collector="loadavg",result="success"} 0.00030610500000000004
node_exporter_scrape_duration_seconds_count{collector="loadavg",result="success"} 1
node_exporter_scrape_duration_seconds{collector="mdadm",result="success",quantile="0.5"} 0.000199423
node_exporter_scrape_duration_seconds{collector="mdadm",result="success",quantile="0.9"} 0.000199423
node_exporter_scrape_duration_seconds{collector="mdadm",result="success",quantile="0.99"} 0.000199423
node_exporter_scrape_duration_seconds_sum{collector="mdadm",result="success"} 0.000199423
node_exporter_scrape_duration_seconds{collector="mdadm",result="success",quantile="0.5"} 0.001285081
node_exporter_scrape_duration_seconds{collector="mdadm",result="success",quantile="0.9"} 0.001285081
node_exporter_scrape_duration_seconds{collector="mdadm",result="success",quantile="0.99"} 0.001285081
node_exporter_scrape_duration_seconds_sum{collector="mdadm",result="success"} 0.001285081
node_exporter_scrape_duration_seconds_count{collector="mdadm",result="success"} 1
node_exporter_scrape_duration_seconds{collector="megacli",result="success",quantile="0.5"} 0.005821468000000001
node_exporter_scrape_duration_seconds{collector="megacli",result="success",quantile="0.9"} 0.005821468000000001
node_exporter_scrape_duration_seconds{collector="megacli",result="success",quantile="0.99"} 0.005821468000000001
node_exporter_scrape_duration_seconds_sum{collector="megacli",result="success"} 0.005821468000000001
node_exporter_scrape_duration_seconds{collector="megacli",result="success",quantile="0.5"} 0.006589346
node_exporter_scrape_duration_seconds{collector="megacli",result="success",quantile="0.9"} 0.006589346
node_exporter_scrape_duration_seconds{collector="megacli",result="success",quantile="0.99"} 0.006589346
node_exporter_scrape_duration_seconds_sum{collector="megacli",result="success"} 0.006589346
node_exporter_scrape_duration_seconds_count{collector="megacli",result="success"} 1
node_exporter_scrape_duration_seconds{collector="meminfo",result="success",quantile="0.5"} 0.001771465
node_exporter_scrape_duration_seconds{collector="meminfo",result="success",quantile="0.9"} 0.001771465
node_exporter_scrape_duration_seconds{collector="meminfo",result="success",quantile="0.99"} 0.001771465
node_exporter_scrape_duration_seconds_sum{collector="meminfo",result="success"} 0.001771465
node_exporter_scrape_duration_seconds{collector="meminfo",result="success",quantile="0.5"} 0.0025752360000000003
node_exporter_scrape_duration_seconds{collector="meminfo",result="success",quantile="0.9"} 0.0025752360000000003
node_exporter_scrape_duration_seconds{collector="meminfo",result="success",quantile="0.99"} 0.0025752360000000003
node_exporter_scrape_duration_seconds_sum{collector="meminfo",result="success"} 0.0025752360000000003
node_exporter_scrape_duration_seconds_count{collector="meminfo",result="success"} 1
node_exporter_scrape_duration_seconds{collector="netdev",result="success",quantile="0.5"} 0.000959257
node_exporter_scrape_duration_seconds{collector="netdev",result="success",quantile="0.9"} 0.000959257
node_exporter_scrape_duration_seconds{collector="netdev",result="success",quantile="0.99"} 0.000959257
node_exporter_scrape_duration_seconds_sum{collector="netdev",result="success"} 0.000959257
node_exporter_scrape_duration_seconds{collector="meminfo_numa",result="success",quantile="0.5"} 0.000494111
node_exporter_scrape_duration_seconds{collector="meminfo_numa",result="success",quantile="0.9"} 0.000494111
node_exporter_scrape_duration_seconds{collector="meminfo_numa",result="success",quantile="0.99"} 0.000494111
node_exporter_scrape_duration_seconds_sum{collector="meminfo_numa",result="success"} 0.000494111
node_exporter_scrape_duration_seconds_count{collector="meminfo_numa",result="success"} 1
node_exporter_scrape_duration_seconds{collector="netdev",result="success",quantile="0.5"} 0.00038711700000000003
node_exporter_scrape_duration_seconds{collector="netdev",result="success",quantile="0.9"} 0.00038711700000000003
node_exporter_scrape_duration_seconds{collector="netdev",result="success",quantile="0.99"} 0.00038711700000000003
node_exporter_scrape_duration_seconds_sum{collector="netdev",result="success"} 0.00038711700000000003
node_exporter_scrape_duration_seconds_count{collector="netdev",result="success"} 1
node_exporter_scrape_duration_seconds{collector="netstat",result="success",quantile="0.5"} 0.0017044130000000001
node_exporter_scrape_duration_seconds{collector="netstat",result="success",quantile="0.9"} 0.0017044130000000001
node_exporter_scrape_duration_seconds{collector="netstat",result="success",quantile="0.99"} 0.0017044130000000001
node_exporter_scrape_duration_seconds_sum{collector="netstat",result="success"} 0.0017044130000000001
node_exporter_scrape_duration_seconds{collector="netstat",result="success",quantile="0.5"} 0.0009007370000000001
node_exporter_scrape_duration_seconds{collector="netstat",result="success",quantile="0.9"} 0.0009007370000000001
node_exporter_scrape_duration_seconds{collector="netstat",result="success",quantile="0.99"} 0.0009007370000000001
node_exporter_scrape_duration_seconds_sum{collector="netstat",result="success"} 0.0009007370000000001
node_exporter_scrape_duration_seconds_count{collector="netstat",result="success"} 1
node_exporter_scrape_duration_seconds{collector="sockstat",result="success",quantile="0.5"} 0.000153337
node_exporter_scrape_duration_seconds{collector="sockstat",result="success",quantile="0.9"} 0.000153337
node_exporter_scrape_duration_seconds{collector="sockstat",result="success",quantile="0.99"} 0.000153337
node_exporter_scrape_duration_seconds_sum{collector="sockstat",result="success"} 0.000153337
node_exporter_scrape_duration_seconds{collector="sockstat",result="success",quantile="0.5"} 0.000119957
node_exporter_scrape_duration_seconds{collector="sockstat",result="success",quantile="0.9"} 0.000119957
node_exporter_scrape_duration_seconds{collector="sockstat",result="success",quantile="0.99"} 0.000119957
node_exporter_scrape_duration_seconds_sum{collector="sockstat",result="success"} 0.000119957
node_exporter_scrape_duration_seconds_count{collector="sockstat",result="success"} 1
node_exporter_scrape_duration_seconds{collector="stat",result="success",quantile="0.5"} 0.00011309800000000001
node_exporter_scrape_duration_seconds{collector="stat",result="success",quantile="0.9"} 0.00011309800000000001
node_exporter_scrape_duration_seconds{collector="stat",result="success",quantile="0.99"} 0.00011309800000000001
node_exporter_scrape_duration_seconds_sum{collector="stat",result="success"} 0.00011309800000000001
node_exporter_scrape_duration_seconds{collector="stat",result="success",quantile="0.5"} 0.00014981800000000002
node_exporter_scrape_duration_seconds{collector="stat",result="success",quantile="0.9"} 0.00014981800000000002
node_exporter_scrape_duration_seconds{collector="stat",result="success",quantile="0.99"} 0.00014981800000000002
node_exporter_scrape_duration_seconds_sum{collector="stat",result="success"} 0.00014981800000000002
node_exporter_scrape_duration_seconds_count{collector="stat",result="success"} 1
node_exporter_scrape_duration_seconds{collector="textfile",result="success",quantile="0.5"} 3.29e-07
node_exporter_scrape_duration_seconds{collector="textfile",result="success",quantile="0.9"} 3.29e-07
node_exporter_scrape_duration_seconds{collector="textfile",result="success",quantile="0.99"} 3.29e-07
node_exporter_scrape_duration_seconds_sum{collector="textfile",result="success"} 3.29e-07
node_exporter_scrape_duration_seconds{collector="textfile",result="success",quantile="0.5"} 3.0500000000000004e-07
node_exporter_scrape_duration_seconds{collector="textfile",result="success",quantile="0.9"} 3.0500000000000004e-07
node_exporter_scrape_duration_seconds{collector="textfile",result="success",quantile="0.99"} 3.0500000000000004e-07
node_exporter_scrape_duration_seconds_sum{collector="textfile",result="success"} 3.0500000000000004e-07
node_exporter_scrape_duration_seconds_count{collector="textfile",result="success"} 1
# HELP node_filefd_allocated File descriptor statistics: allocated.
# TYPE node_filefd_allocated gauge
@ -457,6 +477,180 @@ node_filefd_maximum 1.631329e+06
# HELP node_forks Total number of forks.
# TYPE node_forks counter
node_forks 26442
# HELP node_hwmon_fan_alarm Hardware sensor alarm status (fan)
# TYPE node_hwmon_fan_alarm gauge
node_hwmon_fan_alarm{chip="nct6779",sensor="fan2"} 0
# HELP node_hwmon_fan_beep_enabled Hardware monitor sensor has beeping enabled
# TYPE node_hwmon_fan_beep_enabled gauge
node_hwmon_fan_beep_enabled{chip="nct6779",sensor="fan2"} 0
# HELP node_hwmon_fan_manual Hardware monitor fan element manual
# TYPE node_hwmon_fan_manual gauge
node_hwmon_fan_manual{chip="applesmc_768",sensor="left_side"} 0
node_hwmon_fan_manual{chip="applesmc_768",sensor="right_side"} 0
# HELP node_hwmon_fan_max_rpm Hardware monitor for fan revolutions per minute (max)
# TYPE node_hwmon_fan_max_rpm gauge
node_hwmon_fan_max_rpm{chip="applesmc_768",sensor="left_side"} 6156
node_hwmon_fan_max_rpm{chip="applesmc_768",sensor="right_side"} 5700
# HELP node_hwmon_fan_min_rpm Hardware monitor for fan revolutions per minute (min)
# TYPE node_hwmon_fan_min_rpm gauge
node_hwmon_fan_min_rpm{chip="applesmc_768",sensor="left_side"} 2160
node_hwmon_fan_min_rpm{chip="applesmc_768",sensor="right_side"} 2000
node_hwmon_fan_min_rpm{chip="nct6779",sensor="fan2"} 0
# HELP node_hwmon_fan_output Hardware monitor fan element output
# TYPE node_hwmon_fan_output gauge
node_hwmon_fan_output{chip="applesmc_768",sensor="left_side"} 2160
node_hwmon_fan_output{chip="applesmc_768",sensor="right_side"} 2000
# HELP node_hwmon_fan_pulses Hardware monitor fan element pulses
# TYPE node_hwmon_fan_pulses gauge
node_hwmon_fan_pulses{chip="nct6779",sensor="fan2"} 2
# HELP node_hwmon_fan_rpm Hardware monitor for fan revolutions per minute (input)
# TYPE node_hwmon_fan_rpm gauge
node_hwmon_fan_rpm{chip="applesmc_768",sensor="left_side"} 0
node_hwmon_fan_rpm{chip="applesmc_768",sensor="right_side"} 1998
node_hwmon_fan_rpm{chip="nct6779",sensor="fan2"} 1098
# HELP node_hwmon_fan_target_rpm Hardware monitor for fan revolutions per minute (target)
# TYPE node_hwmon_fan_target_rpm gauge
node_hwmon_fan_target_rpm{chip="nct6779",sensor="fan2"} 27000
# HELP node_hwmon_fan_tolerance Hardware monitor fan element tolerance
# TYPE node_hwmon_fan_tolerance gauge
node_hwmon_fan_tolerance{chip="nct6779",sensor="fan2"} 0
# HELP node_hwmon_in_alarm Hardware sensor alarm status (in)
# TYPE node_hwmon_in_alarm gauge
node_hwmon_in_alarm{chip="nct6779",sensor="in0"} 0
node_hwmon_in_alarm{chip="nct6779",sensor="in1"} 1
# HELP node_hwmon_in_beep_enabled Hardware monitor sensor has beeping enabled
# TYPE node_hwmon_in_beep_enabled gauge
node_hwmon_in_beep_enabled{chip="nct6779",sensor="in0"} 0
node_hwmon_in_beep_enabled{chip="nct6779",sensor="in1"} 0
# HELP node_hwmon_in_max_volts Hardware monitor for voltage (max)
# TYPE node_hwmon_in_max_volts gauge
node_hwmon_in_max_volts{chip="nct6779",sensor="in0"} 1.744
node_hwmon_in_max_volts{chip="nct6779",sensor="in1"} 0
# HELP node_hwmon_in_min_volts Hardware monitor for voltage (min)
# TYPE node_hwmon_in_min_volts gauge
node_hwmon_in_min_volts{chip="nct6779",sensor="in0"} 0
node_hwmon_in_min_volts{chip="nct6779",sensor="in1"} 0
# HELP node_hwmon_in_volts Hardware monitor for voltage (input)
# TYPE node_hwmon_in_volts gauge
node_hwmon_in_volts{chip="nct6779",sensor="in0"} 0.792
node_hwmon_in_volts{chip="nct6779",sensor="in1"} 1.024
# HELP node_hwmon_intrusion_alarm Hardware sensor alarm status (intrusion)
# TYPE node_hwmon_intrusion_alarm gauge
node_hwmon_intrusion_alarm{chip="nct6779",sensor="intrusion0"} 1
node_hwmon_intrusion_alarm{chip="nct6779",sensor="intrusion1"} 1
# HELP node_hwmon_intrusion_beep_enabled Hardware monitor sensor has beeping enabled
# TYPE node_hwmon_intrusion_beep_enabled gauge
node_hwmon_intrusion_beep_enabled{chip="nct6779",sensor="intrusion0"} 0
node_hwmon_intrusion_beep_enabled{chip="nct6779",sensor="intrusion1"} 0
# HELP node_hwmon_pwm_auto_point1_pwm Hardware monitor pwm element auto_point1_pwm
# TYPE node_hwmon_pwm_auto_point1_pwm gauge
node_hwmon_pwm_auto_point1_pwm{chip="nct6779",sensor="pwm1"} 153
# HELP node_hwmon_pwm_auto_point1_temp Hardware monitor pwm element auto_point1_temp
# TYPE node_hwmon_pwm_auto_point1_temp gauge
node_hwmon_pwm_auto_point1_temp{chip="nct6779",sensor="pwm1"} 30000
# HELP node_hwmon_pwm_auto_point2_pwm Hardware monitor pwm element auto_point2_pwm
# TYPE node_hwmon_pwm_auto_point2_pwm gauge
node_hwmon_pwm_auto_point2_pwm{chip="nct6779",sensor="pwm1"} 255
# HELP node_hwmon_pwm_auto_point2_temp Hardware monitor pwm element auto_point2_temp
# TYPE node_hwmon_pwm_auto_point2_temp gauge
node_hwmon_pwm_auto_point2_temp{chip="nct6779",sensor="pwm1"} 70000
# HELP node_hwmon_pwm_auto_point3_pwm Hardware monitor pwm element auto_point3_pwm
# TYPE node_hwmon_pwm_auto_point3_pwm gauge
node_hwmon_pwm_auto_point3_pwm{chip="nct6779",sensor="pwm1"} 255
# HELP node_hwmon_pwm_auto_point3_temp Hardware monitor pwm element auto_point3_temp
# TYPE node_hwmon_pwm_auto_point3_temp gauge
node_hwmon_pwm_auto_point3_temp{chip="nct6779",sensor="pwm1"} 70000
# HELP node_hwmon_pwm_auto_point4_pwm Hardware monitor pwm element auto_point4_pwm
# TYPE node_hwmon_pwm_auto_point4_pwm gauge
node_hwmon_pwm_auto_point4_pwm{chip="nct6779",sensor="pwm1"} 255
# HELP node_hwmon_pwm_auto_point4_temp Hardware monitor pwm element auto_point4_temp
# TYPE node_hwmon_pwm_auto_point4_temp gauge
node_hwmon_pwm_auto_point4_temp{chip="nct6779",sensor="pwm1"} 70000
# HELP node_hwmon_pwm_auto_point5_pwm Hardware monitor pwm element auto_point5_pwm
# TYPE node_hwmon_pwm_auto_point5_pwm gauge
node_hwmon_pwm_auto_point5_pwm{chip="nct6779",sensor="pwm1"} 255
# HELP node_hwmon_pwm_auto_point5_temp Hardware monitor pwm element auto_point5_temp
# TYPE node_hwmon_pwm_auto_point5_temp gauge
node_hwmon_pwm_auto_point5_temp{chip="nct6779",sensor="pwm1"} 75000
# HELP node_hwmon_pwm_crit_temp_tolerance Hardware monitor pwm element crit_temp_tolerance
# TYPE node_hwmon_pwm_crit_temp_tolerance gauge
node_hwmon_pwm_crit_temp_tolerance{chip="nct6779",sensor="pwm1"} 2000
# HELP node_hwmon_pwm_enable Hardware monitor pwm element enable
# TYPE node_hwmon_pwm_enable gauge
node_hwmon_pwm_enable{chip="nct6779",sensor="pwm1"} 5
# HELP node_hwmon_pwm_floor Hardware monitor pwm element floor
# TYPE node_hwmon_pwm_floor gauge
node_hwmon_pwm_floor{chip="nct6779",sensor="pwm1"} 1
# HELP node_hwmon_pwm_mode Hardware monitor pwm element mode
# TYPE node_hwmon_pwm_mode gauge
node_hwmon_pwm_mode{chip="nct6779",sensor="pwm1"} 1
# HELP node_hwmon_pwm_start Hardware monitor pwm element start
# TYPE node_hwmon_pwm_start gauge
node_hwmon_pwm_start{chip="nct6779",sensor="pwm1"} 1
# HELP node_hwmon_pwm_step_down_time Hardware monitor pwm element step_down_time
# TYPE node_hwmon_pwm_step_down_time gauge
node_hwmon_pwm_step_down_time{chip="nct6779",sensor="pwm1"} 100
# HELP node_hwmon_pwm_step_up_time Hardware monitor pwm element step_up_time
# TYPE node_hwmon_pwm_step_up_time gauge
node_hwmon_pwm_step_up_time{chip="nct6779",sensor="pwm1"} 100
# HELP node_hwmon_pwm_stop_time Hardware monitor pwm element stop_time
# TYPE node_hwmon_pwm_stop_time gauge
node_hwmon_pwm_stop_time{chip="nct6779",sensor="pwm1"} 6000
# HELP node_hwmon_pwm_target_temp Hardware monitor pwm element target_temp
# TYPE node_hwmon_pwm_target_temp gauge
node_hwmon_pwm_target_temp{chip="nct6779",sensor="pwm1"} 0
# HELP node_hwmon_pwm_temp_sel Hardware monitor pwm element temp_sel
# TYPE node_hwmon_pwm_temp_sel gauge
node_hwmon_pwm_temp_sel{chip="nct6779",sensor="pwm1"} 7
# HELP node_hwmon_pwm_temp_tolerance Hardware monitor pwm element temp_tolerance
# TYPE node_hwmon_pwm_temp_tolerance gauge
node_hwmon_pwm_temp_tolerance{chip="nct6779",sensor="pwm1"} 0
# HELP node_hwmon_pwm_weight_duty_base Hardware monitor pwm element weight_duty_base
# TYPE node_hwmon_pwm_weight_duty_base gauge
node_hwmon_pwm_weight_duty_base{chip="nct6779",sensor="pwm1"} 0
# HELP node_hwmon_pwm_weight_duty_step Hardware monitor pwm element weight_duty_step
# TYPE node_hwmon_pwm_weight_duty_step gauge
node_hwmon_pwm_weight_duty_step{chip="nct6779",sensor="pwm1"} 0
# HELP node_hwmon_pwm_weight_temp_sel Hardware monitor pwm element weight_temp_sel
# TYPE node_hwmon_pwm_weight_temp_sel gauge
node_hwmon_pwm_weight_temp_sel{chip="nct6779",sensor="pwm1"} 1
# HELP node_hwmon_pwm_weight_temp_step Hardware monitor pwm element weight_temp_step
# TYPE node_hwmon_pwm_weight_temp_step gauge
node_hwmon_pwm_weight_temp_step{chip="nct6779",sensor="pwm1"} 0
# HELP node_hwmon_pwm_weight_temp_step_base Hardware monitor pwm element weight_temp_step_base
# TYPE node_hwmon_pwm_weight_temp_step_base gauge
node_hwmon_pwm_weight_temp_step_base{chip="nct6779",sensor="pwm1"} 0
# HELP node_hwmon_pwm_weight_temp_step_tol Hardware monitor pwm element weight_temp_step_tol
# TYPE node_hwmon_pwm_weight_temp_step_tol gauge
node_hwmon_pwm_weight_temp_step_tol{chip="nct6779",sensor="pwm1"} 0
# HELP node_hwmon_temp_celsius Hardware monitor for temperature (input)
# TYPE node_hwmon_temp_celsius gauge
node_hwmon_temp_celsius{chip="coretemp",sensor="core_0"} 54
node_hwmon_temp_celsius{chip="coretemp",sensor="core_1"} 52
node_hwmon_temp_celsius{chip="coretemp",sensor="core_2"} 53
node_hwmon_temp_celsius{chip="coretemp",sensor="core_3"} 50
node_hwmon_temp_celsius{chip="coretemp",sensor="physical_id_0"} 55
# HELP node_hwmon_temp_crit_alarm_celsius Hardware monitor for temperature (crit_alarm)
# TYPE node_hwmon_temp_crit_alarm_celsius gauge
node_hwmon_temp_crit_alarm_celsius{chip="coretemp",sensor="core_0"} 0
node_hwmon_temp_crit_alarm_celsius{chip="coretemp",sensor="core_1"} 0
node_hwmon_temp_crit_alarm_celsius{chip="coretemp",sensor="core_2"} 0
node_hwmon_temp_crit_alarm_celsius{chip="coretemp",sensor="core_3"} 0
node_hwmon_temp_crit_alarm_celsius{chip="coretemp",sensor="physical_id_0"} 0
# HELP node_hwmon_temp_crit_celsius Hardware monitor for temperature (crit)
# TYPE node_hwmon_temp_crit_celsius gauge
node_hwmon_temp_crit_celsius{chip="coretemp",sensor="core_0"} 100
node_hwmon_temp_crit_celsius{chip="coretemp",sensor="core_1"} 100
node_hwmon_temp_crit_celsius{chip="coretemp",sensor="core_2"} 100
node_hwmon_temp_crit_celsius{chip="coretemp",sensor="core_3"} 100
node_hwmon_temp_crit_celsius{chip="coretemp",sensor="physical_id_0"} 100
# HELP node_hwmon_temp_max_celsius Hardware monitor for temperature (max)
# TYPE node_hwmon_temp_max_celsius gauge
node_hwmon_temp_max_celsius{chip="coretemp",sensor="core_0"} 84
node_hwmon_temp_max_celsius{chip="coretemp",sensor="core_1"} 84
node_hwmon_temp_max_celsius{chip="coretemp",sensor="core_2"} 84
node_hwmon_temp_max_celsius{chip="coretemp",sensor="core_3"} 84
node_hwmon_temp_max_celsius{chip="coretemp",sensor="physical_id_0"} 84
# HELP node_intr Total number of interrupts serviced.
# TYPE node_intr counter
node_intr 8.885917e+06
@ -1540,8 +1734,8 @@ node_sockstat_UDP_mem_bytes 0
node_sockstat_sockets_used 229
# HELP node_textfile_mtime Unixtime mtime of textfiles successfully read.
# TYPE node_textfile_mtime gauge
node_textfile_mtime{file="metrics1.prom"} 1.451167666820433e+09
node_textfile_mtime{file="metrics2.prom"} 1.451167666820433e+09
node_textfile_mtime{file="metrics1.prom"} 1.463773694e+09
node_textfile_mtime{file="metrics2.prom"} 1.463773694e+09
# HELP node_textfile_scrape_error 1 if there was an error opening or reading a file, 0 otherwise
# TYPE node_textfile_scrape_error gauge
node_textfile_scrape_error 0
@ -1553,16 +1747,16 @@ process_cpu_seconds_total 0
process_max_fds 1024
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 7
process_open_fds 8
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 1.23904e+07
process_resident_memory_bytes 1.1108352e+07
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.45121398864e+09
process_start_time_seconds 1.47509459587e+09
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 1.30809856e+08
process_virtual_memory_bytes 2.0549632e+08
# HELP testmetric1_1 Metric read from collector/fixtures/textfile/two_metric_files/metrics1.prom
# TYPE testmetric1_1 untyped
testmetric1_1{foo="bar"} 10

View File

@ -0,0 +1 @@
../../devices/platform/coretemp.0/hwmon/hwmon0

View File

@ -0,0 +1 @@
../../devices/platform/nct6775.656/hwmon/hwmon1

View File

@ -0,0 +1 @@
../../devices/platform/applesmc.768/hwmon/hwmon2

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
Left side

View File

@ -0,0 +1 @@
6156

View File

@ -0,0 +1 @@
2160

View File

@ -0,0 +1 @@
2160

View File

@ -0,0 +1 @@
1998

View File

@ -0,0 +1 @@
Right side

View File

@ -0,0 +1 @@
5700

View File

@ -0,0 +1 @@
2000

View File

@ -0,0 +1 @@
2000

View File

@ -0,0 +1 @@
../../../applesmc.768

View File

@ -0,0 +1 @@
applesmc

View File

@ -0,0 +1 @@
coretemp

View File

@ -0,0 +1 @@
Physical id 0

View File

@ -0,0 +1 @@
nct6779

386
collector/hwmon_linux.go Normal file
View File

@ -0,0 +1,386 @@
// Copyright 2016 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !nohwmon
package collector
import (
"errors"
"io/ioutil"
"os"
"path"
"path/filepath"
"regexp"
"strconv"
"strings"
"github.com/prometheus/client_golang/prometheus"
)
const (
hwMonSubsystem = "hwmon"
)
var (
hwmonInvalidMetricChars = regexp.MustCompile("[^a-z0-9:_]")
hwmonFilenameFormat = regexp.MustCompile(`^(?P<type>[^0-9]+)(?P<id>[0-9]*)?(_(?P<property>.+))?$`)
hwmonLabelDesc = []string{"chip", "sensor"}
hwmonSensorTypes = []string{
"vrm", "beep_enable", "update_interval", "in", "cpu", "fan",
"pwm", "temp", "curr", "power", "energy", "humidity",
"intrusion",
}
)
func init() {
Factories["hwmon"] = NewHwMonCollector
}
type hwMonCollector struct{}
// Takes a prometheus registry and returns a new Collector exposing
// /sys/class/hwmon stats (similar to lm-sensors).
func NewHwMonCollector() (Collector, error) {
return &hwMonCollector{}, nil
}
func cleanMetricName(name string) string {
lower := strings.ToLower(name)
replaced := hwmonInvalidMetricChars.ReplaceAllLiteralString(lower, "_")
cleaned := strings.Trim(replaced, "_")
return cleaned
}
func addValueFile(data map[string]map[string]string, sensor string, prop string, file string) {
raw, e := ioutil.ReadFile(file)
if e != nil {
return
}
value := strings.Trim(string(raw), "\n")
if _, ok := data[sensor]; !ok {
data[sensor] = make(map[string]string)
}
data[sensor][prop] = value
}
// Split a sensor name into <type><num>_<property>
func explodeSensorFilename(filename string) (ok bool, sensorType string, sensorNum int, sensorProperty string) {
matches := hwmonFilenameFormat.FindStringSubmatch(filename)
if len(matches) == 0 {
return false, sensorType, sensorNum, sensorProperty
}
for i, match := range hwmonFilenameFormat.SubexpNames() {
if i >= len(matches) {
return true, sensorType, sensorNum, sensorProperty
}
if match == "type" {
sensorType = matches[i]
}
if match == "property" {
sensorProperty = matches[i]
}
if match == "id" && len(matches[i]) > 0 {
if num, err := strconv.Atoi(matches[i]); err == nil {
sensorNum = num
} else {
return false, sensorType, sensorNum, sensorProperty
}
}
}
return true, sensorType, sensorNum, sensorProperty
}
func collectSensorData(dir string, data map[string]map[string]string) (err error) {
sensorFiles, dirError := ioutil.ReadDir(dir)
if dirError != nil {
return dirError
}
for _, file := range sensorFiles {
filename := file.Name()
ok, sensorType, sensorNum, sensorProperty := explodeSensorFilename(filename)
if !ok {
continue
}
for _, t := range hwmonSensorTypes {
if t == sensorType {
addValueFile(data, sensorType+strconv.Itoa(sensorNum), sensorProperty, path.Join(dir, file.Name()))
break
}
}
}
return nil
}
func (c *hwMonCollector) updateHwmon(ch chan<- prometheus.Metric, dir string) (err error) {
hwmonName, err := c.hwmonName(dir)
if err != nil {
return err
}
data := make(map[string]map[string]string)
err = collectSensorData(dir, data)
if err != nil {
return err
}
if _, err := os.Stat(path.Join(dir, "device")); err == nil {
err := collectSensorData(path.Join(dir, "device"), data)
if err != nil {
return err
}
}
// format all sensors
for sensor, sensorData := range data {
_, sensorType, _, _ := explodeSensorFilename(sensor)
if labelText, ok := sensorData["label"]; ok {
label := cleanMetricName(labelText)
if label != "" {
sensor = label
}
}
labels := []string{hwmonName, sensor}
if sensorType == "beep_enable" {
value := 0.0
if sensorData[""] == "1" {
value = 1.0
}
metricName := "node_hwmon_beep_enabled"
desc := prometheus.NewDesc(metricName, "Hardware beep enabled", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(
desc, prometheus.GaugeValue, value, labels...)
continue
}
if sensorType == "vrm" {
parsedValue, err := strconv.ParseFloat(sensorData[""], 64)
if err != nil {
continue
}
metricName := "node_hwmon_voltage_regulator_version"
desc := prometheus.NewDesc(metricName, "Hardware voltage regulator", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(
desc, prometheus.GaugeValue, parsedValue, labels...)
continue
}
if sensorType == "update_interval" {
parsedValue, err := strconv.ParseFloat(sensorData[""], 64)
if err != nil {
continue
}
metricName := "node_hwmon_update_interval_seconds"
desc := prometheus.NewDesc(metricName, "Hardware monitor update interval", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(
desc, prometheus.GaugeValue, parsedValue*0.001, labels...)
continue
}
prefix := "node_hwmon_" + sensorType
for element, value := range sensorData {
if element == "label" {
continue
}
name := prefix
if element == "input" {
// input is actually the value
if _, ok := sensorData[""]; ok {
name = name + "_input"
}
} else if element != "" {
name = name + "_" + cleanMetricName(element)
}
parsedValue, err := strconv.ParseFloat(value, 64)
if err != nil {
continue
}
// special elements, fault, alarm & beep should be handed out without units
if element == "fault" || element == "alarm" {
desc := prometheus.NewDesc(name, "Hardware sensor "+element+" status ("+sensorType+")", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, parsedValue, labels...)
continue
}
if element == "beep" {
desc := prometheus.NewDesc(name+"_enabled", "Hardware monitor sensor has beeping enabled", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, parsedValue, labels...)
continue
}
// everything else should get a unit
if sensorType == "in" || sensorType == "cpu" {
desc := prometheus.NewDesc(name+"_volts", "Hardware monitor for voltage ("+element+")", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(
desc, prometheus.GaugeValue, parsedValue*0.001, labels...)
continue
}
if sensorType == "temp" && element != "type" {
desc := prometheus.NewDesc(name+"_celsius", "Hardware monitor for temperature ("+element+")", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(
desc, prometheus.GaugeValue, parsedValue*0.001, labels...)
continue
}
if sensorType == "curr" {
desc := prometheus.NewDesc(name+"_amps", "Hardware monitor for current ("+element+")", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(
desc, prometheus.GaugeValue, parsedValue*0.001, labels...)
continue
}
if sensorType == "energy" {
desc := prometheus.NewDesc(name+"_joule_total", "Hardware monitor for joules used so far ("+element+")", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(
desc, prometheus.CounterValue, parsedValue/1000000.0, labels...)
continue
}
if sensorType == "power" && element == "accuracy" {
desc := prometheus.NewDesc(name, "Hardware monitor power meter accuracy, as a ratio", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(
desc, prometheus.GaugeValue, parsedValue/1000000.0, labels...)
continue
}
if sensorType == "power" && (element == "average_interval" || element == "average_interval_min" || element == "average_interval_max") {
desc := prometheus.NewDesc(name+"_seconds", "Hardware monitor power usage update interval ("+element+")", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(
desc, prometheus.GaugeValue, parsedValue*0.001, labels...)
continue
}
if sensorType == "power" {
desc := prometheus.NewDesc(name+"_watt", "Hardware monitor for power usage in watts ("+element+")", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(
desc, prometheus.GaugeValue, parsedValue/1000000.0, labels...)
continue
}
if sensorType == "humidity" {
desc := prometheus.NewDesc(name, "Hardware monitor for humidity, as a ratio (multiply with 100.0 to get the humidity as a percentage) ("+element+")", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(
desc, prometheus.GaugeValue, parsedValue/1000000.0, labels...)
continue
}
if sensorType == "fan" && (element == "input" || element == "min" || element == "max" || element == "target") {
desc := prometheus.NewDesc(name+"_rpm", "Hardware monitor for fan revolutions per minute ("+element+")", hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(
desc, prometheus.GaugeValue, parsedValue, labels...)
continue
}
// fallback, just dump the metric as is
desc := prometheus.NewDesc(name, "Hardware monitor "+sensorType+" element "+element, hwmonLabelDesc, nil)
ch <- prometheus.MustNewConstMetric(
desc, prometheus.GaugeValue, parsedValue, labels...)
}
}
return nil
}
func (c *hwMonCollector) hwmonName(dir string) (string, error) {
// generate a name for a sensor path
// sensor numbering depends on the order of linux module loading and
// is thus unstable.
// However the path of the device has to be stable:
// - /sys/devices/<bus>/<device>
// Some hardware monitors have a "name" file that exports a human
// readbale name that can be used.
// human readable names would be bat0 or coretemp, while a path string
// could be platform_applesmc.768
// preference 1: is there a name file
sysnameRaw, nameErr := ioutil.ReadFile(path.Join(dir, "name"))
if nameErr == nil && string(sysnameRaw) != "" {
cleanName := cleanMetricName(string(sysnameRaw))
if cleanName != "" {
return cleanName, nil
}
}
// preference 2: construct a name based on device
devicePath, devErr := filepath.EvalSymlinks(path.Join(dir, "device"))
if devErr == nil {
devPathPrefix, devName := path.Split(devicePath)
_, devType := path.Split(devPathPrefix)
cleanDevName := cleanMetricName(devName)
cleanDevType := cleanMetricName(devType)
if cleanDevType != "" && cleanDevName != "" {
return cleanDevType + "_" + cleanDevName, nil
}
if cleanDevName != "" {
return cleanDevName, nil
}
}
// it looks bad, name and device don't provide enough information
// return a hwmon[0-9]* name
realDir, err := filepath.EvalSymlinks(dir)
if err != nil {
return "", err
}
// take the last path element, this will be hwmonX
_, name := path.Split(realDir)
cleanName := cleanMetricName(name)
if cleanName != "" {
return cleanName, nil
}
return "", errors.New("Could not derive a monitoring name for " + dir)
}
func (c *hwMonCollector) Update(ch chan<- prometheus.Metric) (err error) {
// Step 1: scan /sys/class/hwmon, resolve all symlinks and call
// updatesHwmon for each folder
hwmonPathName := path.Join(sysFilePath("class"), "hwmon")
hwmonFiles, err := ioutil.ReadDir(hwmonPathName)
if err != nil {
return err
}
for _, hwDir := range hwmonFiles {
hwmonXPathName := path.Join(hwmonPathName, hwDir.Name())
if hwDir.Mode()&os.ModeSymlink > 0 {
hwDir, err = os.Stat(hwmonXPathName)
if err != nil {
continue
}
}
if !hwDir.IsDir() {
continue
}
if lastErr := c.updateHwmon(ch, hwmonXPathName); lastErr != nil {
err = lastErr
}
}
return err
}

View File

@ -7,6 +7,7 @@ collectors=$(cat << COLLECTORS
diskstats
entropy
filefd
hwmon
ksmd
loadavg
mdadm

View File

@ -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"
)
var (