]> arthur.barton.de Git - netdata.git/blob - charts.d/sensors.chart.sh
Merge pull request #515 from paulfantom/master
[netdata.git] / charts.d / sensors.chart.sh
1 #!/bin/sh
2
3 # sensors docs
4 # https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
5
6 # if this chart is called X.chart.sh, then all functions and global variables
7 # must start with X_
8
9 # the directory the kernel keeps sensor data
10 sensors_sys_dir="${NETDATA_HOST_PREFIX}/sys/devices"
11
12 # how deep in the tree to check for sensor data
13 sensors_sys_depth=10
14
15 # if set to 1, the script will overwrite internal
16 # script functions with code generated ones
17 # leave to 1, is faster
18 sensors_source_update=1
19
20 # how frequently to collect sensor data
21 # the default is to collect it at every iteration of charts.d
22 sensors_update_every=
23
24 sensors_priority=90000
25
26 declare -A sensors_excluded=()
27
28 sensors_find_all_files() {
29         find $1 -maxdepth $sensors_sys_depth -name \*_input -o -name temp 2>/dev/null
30 }
31
32 sensors_find_all_dirs() {
33         sensors_find_all_files $1 | while read
34         do
35                 dirname $REPLY
36         done | sort -u
37 }
38
39 # _check is called once, to find out if this chart should be enabled or not
40 sensors_check() {
41
42         # this should return:
43         #  - 0 to enable the chart
44         #  - 1 to disable the chart
45
46         [ -z "$( sensors_find_all_files $sensors_sys_dir )" ] && echo >&2 "$PROGRAM_NAME: sensors: no sensors found in '$sensors_sys_dir'." && return 1
47         return 0
48 }
49
50 sensors_check_files() {
51         # we only need sensors that report a non-zero value
52         # also remove not needed sensors
53
54         local f= v= excluded=
55         for f in $*
56         do
57                 [ ! -f "$f" ] && continue
58                 for ex in ${sensors_excluded[@]}; do
59                         [[ $f =~ .*$ex$ ]] && excluded='1' && break
60                 done
61
62                 [ "$excluded" != "1" ] && v="$( cat $f )" || v=0
63                 v=$(( v + 1 - 1 ))
64                 [ $v -ne 0 ] && echo "$f" && continue
65                 excluded=
66
67                 echo >&2 "$PROGRAM_NAME: sensors: $f gives zero values"
68         done
69 }
70
71 sensors_check_temp_type() {
72         # valid temp types are 1 to 6
73         # disabled sensors have the value 0
74
75         local f= t= v=
76         for f in $*
77         do
78                 t=$( echo $f | sed "s|_input$|_type|g" )
79                 [ "$f" = "$t" ] && echo "$f" && continue
80                 [ ! -f "$t" ] && echo "$f" && continue
81
82                 v="$( cat $t )"
83                 v=$(( v + 1 - 1 ))
84                 [ $v -ne 0 ] && echo "$f" && continue
85
86                 echo >&2 "$PROGRAM_NAME: sensors: $f is disabled"
87         done
88 }
89
90 # _create is called once, to create the charts
91 sensors_create() {
92         local path= dir= name= x= file= lfile= labelname= labelid= device= subsystem= id= type= mode= files= multiplier= divisor=
93
94         # we create a script with the source of the
95         # sensors_update() function
96         # - the highest speed we can achieve -
97         [ $sensors_source_update -eq 1 ] && echo >$TMP_DIR/sensors.sh "sensors_update() {"
98
99         for path in $( sensors_find_all_dirs $sensors_sys_dir | sort -u )
100         do
101                 dir=$( basename $path )
102                 device=
103                 subsystem=
104                 id=
105                 type=
106                 name=
107
108                 [ -h $path/device ] && device=$( readlink -f $path/device )
109                 [ ! -z "$device" ] && device=$( basename $device )
110                 [ -z "$device" ] && device="$dir"
111
112                 [ -h $path/subsystem ] && subsystem=$( readlink -f $path/subsystem )
113                 [ ! -z "$subsystem" ] && subsystem=$( basename $subsystem )
114                 [ -z "$subsystem" ] && subsystem="$dir"
115
116                 [ -f $path/name ] && name=$( cat $path/name )
117                 [ -z "$name" ] && name="$dir"
118
119                 [ -f $path/type ] && type=$( cat $path/type )
120                 [ -z "$type" ] && type="$dir"
121
122                 id="$( fixid "$device.$subsystem.$dir" )"
123
124                 echo >&2 "charts.d: sensors: on path='$path', dir='$dir', device='$device', subsystem='$subsystem', id='$id', name='$name'"
125
126                 for mode in temperature voltage fans power current energy humidity
127                 do
128                         files=
129                         multiplier=1
130                         divisor=1
131                         algorithm="absolute"
132
133                         case $mode in
134                                 temperature)
135                                         files="$( ls $path/temp*_input 2>/dev/null; ls $path/temp 2>/dev/null )"
136                                         files="$( sensors_check_files $files )"
137                                         files="$( sensors_check_temp_type $files )"
138                                         [ -z "$files" ] && continue
139                                         echo "CHART sensors.temp_$id '' '$name Temperature' 'Celsius' 'temperature' 'sensors.temp' line $((sensors_priority + 1)) $sensors_update_every"
140                                         echo >>$TMP_DIR/sensors.sh "echo \"BEGIN sensors.temp_$id \$1\""
141                                         divisor=1000
142                                         ;;
143
144                                 voltage)
145                                         files="$( ls $path/in*_input 2>/dev/null )"
146                                         files="$( sensors_check_files $files )"
147                                         [ -z "$files" ] && continue
148                                         echo "CHART sensors.volt_$id '' '$name Voltage' 'Volts' 'voltage' 'sensors.volt' line $((sensors_priority + 2)) $sensors_update_every"
149                                         echo >>$TMP_DIR/sensors.sh "echo \"BEGIN sensors.volt_$id \$1\""
150                                         divisor=1000
151                                         ;;
152
153                                 current)
154                                         files="$( ls $path/curr*_input 2>/dev/null )"
155                                         files="$( sensors_check_files $files )"
156                                         [ -z "$files" ] && continue
157                                         echo "CHART sensors.curr_$id '' '$name Current' 'Ampere' 'current' 'sensors.curr' line $((sensors_priority + 3)) $sensors_update_every"
158                                         echo >>$TMP_DIR/sensors.sh "echo \"BEGIN sensors.curr_$id \$1\""
159                                         divisor=1000
160                                         ;;
161
162                                 power)
163                                         files="$( ls $path/power*_input 2>/dev/null )"
164                                         files="$( sensors_check_files $files )"
165                                         [ -z "$files" ] && continue
166                                         echo "CHART sensors.power_$id '' '$name Power' 'Watt' 'power' 'sensors.power' line $((sensors_priority + 4)) $sensors_update_every"
167                                         echo >>$TMP_DIR/sensors.sh "echo \"BEGIN sensors.power_$id \$1\""
168                                         divisor=1000000
169                                         ;;
170
171                                 fans)
172                                         files="$( ls $path/fan*_input 2>/dev/null )"
173                                         files="$( sensors_check_files $files )"
174                                         [ -z "$files" ] && continue
175                                         echo "CHART sensors.fan_$id '' '$name Fans Speed' 'Rotations / Minute' 'fans' 'sensors.fans' line $((sensors_priority + 5)) $sensors_update_every"
176                                         echo >>$TMP_DIR/sensors.sh "echo \"BEGIN sensors.fan_$id \$1\""
177                                         ;;
178
179                                 energy)
180                                         files="$( ls $path/energy*_input 2>/dev/null )"
181                                         files="$( sensors_check_files $files )"
182                                         [ -z "$files" ] && continue
183                                         echo "CHART sensors.energy_$id '' '$name Energy' 'Joule' 'energy' 'sensors.energy' areastack $((sensors_priority + 6)) $sensors_update_every"
184                                         echo >>$TMP_DIR/sensors.sh "echo \"BEGIN sensors.energy_$id \$1\""
185                                         algorithm="incremental"
186                                         divisor=1000000
187                                         ;;
188
189                                 humidity)
190                                         files="$( ls $path/humidity*_input 2>/dev/null )"
191                                         files="$( sensors_check_files $files )"
192                                         [ -z "$files" ] && continue
193                                         echo "CHART sensors.humidity_$id '' '$name Humidity' 'Percent' 'humidity' 'sensors.humidity' line $((sensors_priority + 7)) $sensors_update_every"
194                                         echo >>$TMP_DIR/sensors.sh "echo \"BEGIN sensors.humidity_$id \$1\""
195                                         divisor=1000
196                                         ;;
197
198                                 *)
199                                         continue
200                                         ;;
201                         esac
202
203                         for x in $files
204                         do
205                                 file="$x"
206                                 fid="$( fixid "$file" )"
207                                 lfile="$( basename $file | sed "s|_input$|_label|g" )"
208                                 labelname="$( basename $file | sed "s|_input$||g" )"
209
210                                 if [ ! "$path/$lfile" = "$file" -a -f "$path/$lfile" ]
211                                         then
212                                         labelname="$( cat "$path/$lfile" )"
213                                 fi
214
215                                 echo "DIMENSION $fid '$labelname' $algorithm $multiplier $divisor"
216                                 echo >>$TMP_DIR/sensors.sh "printf \"SET $fid = \"; cat $file "
217                         done
218
219                         echo >>$TMP_DIR/sensors.sh "echo END"
220                 done
221         done
222
223         [ $sensors_source_update -eq 1 ] && echo >>$TMP_DIR/sensors.sh "}"
224         # cat >&2 $TMP_DIR/sensors.sh
225
226         # ok, load the function sensors_update() we created
227         [ $sensors_source_update -eq 1 ] && . $TMP_DIR/sensors.sh
228
229         return 0
230 }
231
232 # _update is called continiously, to collect the values
233 sensors_update() {
234         # the first argument to this function is the microseconds since last update
235         # pass this parameter to the BEGIN statement (see bellow).
236
237         # do all the work to collect / calculate the values
238         # for each dimension
239         # remember: KEEP IT SIMPLE AND SHORT
240
241         [ $sensors_source_update -eq 0 ] && . $TMP_DIR/sensors.sh $1
242
243         return 0
244 }
245