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