slitaz-forge view mirror/info/bin/makegraphs @ rev 361

mirror/info: vm lguest -> UML
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sat Apr 13 18:15:41 2013 +0200 (2013-04-13)
parents d2d8931bb183
children 3d98f09d077b
line source
1 #!/bin/sh
2 #*/5 * * * * /var/www/mirror-info/bin/makegraphs >/dev/null
4 # RRD database directory
5 rrdlog="/var/spool/rrd"
7 # Images directory
8 rrdgraph="/var/www/mirror-info/images/rrd"
10 # Colors
11 #rrdcolors="--color SHADEA#EAE9EE --color SHADEB#EAE9EE --color BACK#EAE9EE"
12 rrdcolors="--color SHADEA#FFFFFF --color SHADEB#FFFFFF --color BACK#FFFFFF"
13 rrdgraphargs="-aPNG -i -z --alt-y-grid -w 600 -h 100 -r $rrdcolors"
15 [ -d $rrdlog ] || mkdir -p $rrdlog
16 [ -d $rrdgraph ] || mkdir -p $rrdgraph
18 updatecpudata() {
19 [ -e "$rrdlog/cpu.rrd" ] || rrdtool create $rrdlog/cpu.rrd --step=300 \
20 DS:user:COUNTER:600:0:500000000 \
21 DS:system:COUNTER:600:0:500000000 \
22 DS:idle:COUNTER:600:0:500000000 \
23 RRA:AVERAGE:0.5:1:576 RRA:AVERAGE:0.5:6:672 \
24 RRA:AVERAGE:0.5:24:732 RRA:AVERAGE:0.5:144:1460
25 grep '^cpu' /proc/stat | while read cpu user nice system idle misc; do
26 rrdtool update $rrdlog/cpu.rrd -t user:system:idle \
27 N:$(( $user + $nice )):$system:$idle
28 break
29 done
31 [ -e "$rrdlog/cpu2.rrd" ] &&
32 grep '^cpu' /proc/stat | while read cpu user nice system idle misc; do
33 rrdtool update $rrdlog/cpu2.rrd -t nice:user:system:idle \
34 N:$nice:$user:$system:$idle
35 break
36 done
37 }
39 updatecpugraph() {
40 period=$1
41 info="$(sed '/cpuinfo=/!d;s/.*cpuinfo=\([^ ]*\).*/: \1/;s/_/ /g' /proc/cmdline)"
42 [ -n "$info" ] || info="$(grep '^model name' /proc/cpuinfo)"
43 info="$(echo "$info" | cut -d: -f2 | sed 's/ * / /g' | head -1)"
44 rrdtool graph "$rrdgraph/cpu-$period.png" --start -1$period \
45 $rrdgraphargs -l 0 -u 100 -t "cpu usage per $period [$info ]" \
46 DEF:user=$rrdlog/cpu.rrd:user:AVERAGE \
47 DEF:system=$rrdlog/cpu.rrd:system:AVERAGE \
48 DEF:idle=$rrdlog/cpu.rrd:idle:AVERAGE \
49 'CDEF:total=user,system,idle,+,+' \
50 'CDEF:userpct=100,user,total,/,*' \
51 'CDEF:systempct=100,system,total,/,*' \
52 'CDEF:idlepct=100,idle,total,/,*' \
53 'AREA:userpct#0000FF:user cpu usage' \
54 'STACK:systempct#FF0000:system cpu usage' \
55 'STACK:idlepct#00FF00:idle cpu usage\j'
56 }
59 updatememgraph() {
60 period=$1
61 info="$(free | awk '\
62 { \
63 if (/Mem:/) { \
64 if ($2 < 10000) printf "%d KB",$2; \
65 else if ($2 < 10000000) printf "%d MB",$2/1024; \
66 else printf "%d GB",$2/1024/1024; \
67 } \
68 }')"
69 info2="$(free | awk '\
70 { \
71 if (/Swap:/) { \
72 if ($2 < 10000) printf "%d KB",$2; \
73 else if ($2 < 10000000) printf "%d MB",$2/1024; \
74 else printf "%d GB",$2/1024/1024; \
75 } \
76 }')"
77 rrdtool graph "$rrdgraph/memory-$period.png" --start -1$period \
78 $rrdgraphargs -l 0 -u 100 \
79 -t "memory usage per $period [ $info + $info2 swap ]" \
80 DEF:used=$rrdlog/mem.rrd:memused:AVERAGE \
81 DEF:free=$rrdlog/mem.rrd:memfree:AVERAGE \
82 DEF:shared=$rrdlog/mem.rrd:memshared:AVERAGE \
83 DEF:buffer=$rrdlog/mem.rrd:membuffers:AVERAGE \
84 DEF:cache=$rrdlog/mem.rrd:memcache:AVERAGE \
85 DEF:swused=$rrdlog/mem.rrd:swapused:AVERAGE \
86 DEF:swfree=$rrdlog/mem.rrd:swapfree:AVERAGE \
87 'CDEF:total=used,free,+' \
88 'CDEF:used2=used,buffer,cache,shared,+,+,-' \
89 'CDEF:usedpct=100,used2,total,/,*' \
90 'CDEF:sharedpct=100,shared,total,/,*' \
91 'CDEF:bufferpct=100,buffer,total,/,*' \
92 'CDEF:cachepct=100,cache,total,/,*' \
93 'CDEF:freepct=100,free,total,/,*' \
94 'CDEF:swtotal=swused,swfree,+' \
95 'CDEF:swusedpct=100,swused,swtotal,/,*' \
96 'AREA:usedpct#0000FF:used memory' \
97 'STACK:sharedpct#FF7F00:shared memory' \
98 'STACK:bufferpct#FF00FF:buffered memory' \
99 'STACK:cachepct#FFFF00:cached memory' \
100 'STACK:freepct#00FF00:free memory' \
101 'LINE2:swusedpct#FF0000:used swap\j'
102 }
104 updatememdata () {
105 [ -e "$rrdlog/mem.rrd" ] ||
106 rrdtool create "$rrdlog/mem.rrd" --step=300 \
107 DS:memused:ABSOLUTE:600:0:5000000000 \
108 DS:memfree:ABSOLUTE:600:0:5000000000 \
109 DS:memshared:ABSOLUTE:600:0:5000000000 \
110 DS:membuffers:ABSOLUTE:600:0:5000000000 \
111 DS:memcache:ABSOLUTE:600:0:5000000000 \
112 DS:swapused:ABSOLUTE:600:0:5000000000 \
113 DS:swapfree:ABSOLUTE:600:0:5000000000 \
114 RRA:AVERAGE:0.5:1:576 RRA:AVERAGE:0.5:6:672 \
115 RRA:AVERAGE:0.5:24:732 RRA:AVERAGE:0.5:144:1460
117 while read tag count unit; do
118 case "$tag" in
119 MemTotal:) memtotal=$(($count * 1024));;
120 MemFree:) memfree=$(($count * 1024))
121 memused=$(($memtotal - $memfree))
122 memshared=0;;
123 MemShared:) memshared=$(($count * 1024));;
124 Buffers:) membuffers=$(($count * 1024));;
125 Cached:) memcache=$(($count * 1024));;
126 SwapTotal:) swaptotal=$(($count * 1024));;
127 SwapFree:) swapfree=$(($count * 1024))
128 swapused=$(( $swaptotal - $swapfree));;
129 esac
130 done < /proc/meminfo
132 rrdtool update "$rrdlog/mem.rrd" \
133 -t memused:memfree:memshared:membuffers:memcache:swapused:swapfree \
134 "N:$memused:$memfree:$memshared:$membuffers:$memcache:$swapused:$swapfree"
135 }
137 getmax() {
138 rrdtool fetch $rrdlog/$1.rrd AVERAGE | awk '\
139 BEGIN {max=0} \
140 /^[0-9]/ { \
141 if ($2 != "nan" && $2 > max) max=$2; \
142 if ($3 != "nan" && $3 > max) max=$3; \
143 } \
144 END { print max }' | sed 's/,/./'
145 }
147 updatediskgraph() {
148 period=$1
149 extra="--logarithmic --lower-limit 1"
150 [ "$period" == "day" ] && maxdisk="$(getmax disk)" && extra=""
151 info=""
152 [ -r $2 ] &&
153 info="[ $(fdisk -l 2> /dev/null | grep "^Disk $2:" | \
154 sed "s|Disk $2: \(.*\), .*|\1|") ]"
155 if [ -e /sys/block/${2#/dev/}/device/iodone_cnt ]; then
156 # --right-axis-label "I/O state %"
157 rrdtool graph "$rrdgraph/disk-$period.png" --start -1$period \
158 $rrdgraphargs -t "disk access per $period $info" \
159 $extra -v "Sectors/second" --units=si \
160 DEF:read=$rrdlog/disk.rrd:readsect:AVERAGE \
161 DEF:write=$rrdlog/disk.rrd:writesect:AVERAGE \
162 DEF:req=$rrdlog/iodisk.rrd:req:AVERAGE \
163 DEF:done=$rrdlog/iodisk.rrd:done:AVERAGE \
164 DEF:err=$rrdlog/iodisk.rrd:err:AVERAGE \
165 "CDEF:readpct=100,read,$maxdisk,/,*" \
166 "CDEF:writepct=100,write,$maxdisk,/,*" \
167 "CDEF:errpct=100,err,req,/,*" \
168 "CDEF:donepct=100,done,req,/,*" \
169 'AREA:readpct#0000FF:sectors written from disk' \
170 'STACK:writepct#00FF00:sectors read to disk' \
171 'LINE2:donepct#FFFF00:I/O complete' \
172 'LINE2:errpct#FF0000:I/O error\j'
173 else
174 rrdtool graph "$rrdgraph/disk-$period.png" --start -1$period \
175 $rrdgraphargs -t "disk access per $period $info" \
176 $extra -v "Sectors/second" --units=si \
177 DEF:read=$rrdlog/disk.rrd:readsect:AVERAGE \
178 DEF:write=$rrdlog/disk.rrd:writesect:AVERAGE \
179 DEF:blk=$rrdlog/usagedisk.rrd:broot:AVERAGE \
180 DEF:ino=$rrdlog/usagedisk.rrd:iroot:AVERAGE \
181 "CDEF:readpct=100,read,$maxdisk,/,*" \
182 "CDEF:writepct=100,write,$maxdisk,/,*" \
183 'AREA:readpct#0000FF:sectors written from disk' \
184 'STACK:writepct#00FF00:sectors read to disk' \
185 'LINE1:ino#FF00FF:% inodes used' \
186 'LINE1:blk#FF0000:% blocks used\j'
187 fi
188 }
190 updatediskdata() {
191 dev=$1
192 [ -e "$rrdlog/disk.rrd" ] ||
193 rrdtool create "$rrdlog/disk.rrd" --step=300 \
194 DS:readsect:COUNTER:600:0:5000000000 \
195 DS:writesect:COUNTER:600:0:5000000000 \
196 RRA:AVERAGE:0.5:1:576 RRA:AVERAGE:0.5:6:672 \
197 RRA:AVERAGE:0.5:24:732 RRA:AVERAGE:0.5:144:1460
198 [ -e "$rrdlog/iodisk.rrd" ] ||
199 rrdtool create "$rrdlog/iodisk.rrd" --step=300 \
200 DS:done:GAUGE:600:0:U DS:err:GAUGE:600:0:U \
201 DS:req:GAUGE:600:0:U \
202 RRA:AVERAGE:0.5:1:576 RRA:AVERAGE:0.5:6:672 \
203 RRA:AVERAGE:0.5:24:732 RRA:AVERAGE:0.5:144:1460
204 [ -e "$rrdlog/usagedisk.rrd" ] ||
205 rrdtool create "$rrdlog/usagedisk.rrd" --step=300 \
206 DS:broot:GAUGE:600:0:U DS:iroot:GAUGE:600:0:U \
207 RRA:AVERAGE:0.5:1:576 RRA:AVERAGE:0.5:6:672 \
208 RRA:AVERAGE:0.5:24:732 RRA:AVERAGE:0.5:144:1460
210 while read major minor name readreq readsect writereq writesect misc; do
211 [ $major = $(( 0x$(stat -c %t $dev) )) ] || continue
212 [ $minor = $(( 0x$(stat -c %T $dev) )) ] || continue
213 rrdtool update "$rrdlog/disk.rrd" -t readsect:writesect \
214 N:$readsect:$writesect
215 done < /proc/diskstats
216 disk=${dev:0:8}
217 dir=/sys/block/${disk#/dev/}/device
218 iroot=$(df -i / | sed '$!d;s/.* \([0-9]*\)% \/.*/\1/')
219 broot=$(df / | sed '$!d;s/.* \([0-9]*\)% \/.*/\1/')
220 rrdtool update "$rrdlog/usagedisk.rrd" -t broot:iroot N:$broot:$iroot
221 [ -e $dir/iorequest_cnt ] || return
222 done=$(printf "%d\n" $(cat $dir/iodone_cnt 2> /dev/null) )
223 err=$(printf "%d\n" $(cat $dir/ioerr_cnt 2> /dev/null) )
224 req=$(printf "%d\n" $(cat $dir/iorequest_cnt 2> /dev/null) )
225 rrdtool update "$rrdlog/iodisk.rrd" -t done:err:req N:$done:$err:$req
226 }
228 updateifgraph() {
229 interface=$1
230 period=$2
231 rrdtool graph "$rrdgraph/$interface-$period.png" --start -1$period \
232 $rrdgraphargs -t "traffic on $interface graph per $period" \
233 --logarithmic -A -v "Bytes/second" --units=si \
234 DEF:incoming=$rrdlog/$interface.rrd:incoming:AVERAGE \
235 DEF:outgoing=$rrdlog/$interface.rrd:outgoing:AVERAGE \
236 DEF:tcp=$rrdlog/proto-$interface.rrd:tcp:AVERAGE \
237 'AREA:incoming#00FF00:incoming traffic' \
238 'GPRINT:outgoing:MAX:max output%8.3lf %sBps' \
239 'LINE1:outgoing#0000FF:outgoing traffic' \
240 'LINE1:tcp#000000:connections\j'
241 }
243 netframes() {
244 ifconfig $1 | grep "$2 packets" | sed -re "s/.*$3:([0-9]+).*/\1/g"
245 }
247 netstats() {
248 ifconfig $1 | grep bytes | sed -re "s/.*$2 bytes:([0-9]+).*/\1/g"
249 }
251 netproto()
252 {
253 proto=${1:-tcp}
254 if [ -n "$2" ]; then
255 netstat -an 2> /dev/null | grep -v '0.0.0.0:*' | grep "^$proto" | grep ":$2 " | wc -l
256 else
257 netstat -an 2> /dev/null | grep -v '0.0.0.0:*' | grep "^$proto" | wc -l
258 fi
259 }
261 updateifdata() {
262 interface=$1
263 [ -e "$rrdlog/$interface.rrd" ] ||
264 rrdtool create "$rrdlog/$interface.rrd" --step=300 \
265 DS:incoming:COUNTER:600:0:U \
266 DS:outgoing:COUNTER:600:0:U \
267 RRA:AVERAGE:0.5:1:576 RRA:AVERAGE:0.5:6:672 \
268 RRA:AVERAGE:0.5:24:732 RRA:AVERAGE:0.5:144:1460
269 [ -e "$rrdlog/packets-$interface.rrd" ] ||
270 rrdtool create "$rrdlog/packets-$interface.rrd" --step=300 \
271 DS:in:COUNTER:600:0:U DS:out:COUNTER:600:0:U \
272 DS:inerr:COUNTER:600:0:U DS:outerr:COUNTER:600:0:U \
273 DS:indrop:COUNTER:600:0:U DS:outdrop:COUNTER:600:0:U \
274 DS:inov:COUNTER:600:0:U DS:outov:COUNTER:600:0:U \
275 DS:frame:COUNTER:600:0:U DS:carrier:COUNTER:600:0:U \
276 RRA:AVERAGE:0.5:1:576 RRA:AVERAGE:0.5:6:672 \
277 RRA:AVERAGE:0.5:24:732 RRA:AVERAGE:0.5:144:1460
278 [ -e "$rrdlog/proto-$interface.rrd" ] ||
279 rrdtool create "$rrdlog/proto-$interface.rrd" --step=300 \
280 DS:tcp:GAUGE:600:0:U DS:udp:GAUGE:600:0:U \
281 DS:rsync:GAUGE:600:0:U DS:www:GAUGE:600:0:U \
282 DS:ssh:GAUGE:600:0:U \
283 RRA:AVERAGE:0.5:1:576 RRA:AVERAGE:0.5:6:672 \
284 RRA:AVERAGE:0.5:24:732 RRA:AVERAGE:0.5:144:1460
285 rx=$(netstats $interface RX)
286 tx=$(netstats $interface TX)
287 rrdtool update "$rrdlog/$interface.rrd" -t incoming:outgoing \
288 N:${rx:-U}:${tx:-U}
289 rx=$(netframes $interface RX packets)
290 tx=$(netframes $interface TX packets)
291 rxerr=$(netframes $interface RX errors)
292 txerr=$(netframes $interface TX errors)
293 rxdrop=$(netframes $interface RX dropped)
294 txdrop=$(netframes $interface TX dropped)
295 rxov=$(netframes $interface RX overruns)
296 txov=$(netframes $interface TX overruns)
297 frame=$(netframes $interface RX frame)
298 carrier=$(netframes $interface TX carrier)
299 rrdtool update "$rrdlog/packets-$interface.rrd" \
300 -t in:out:inerr:outerr:indrop:outdrop:inov:outov:frame:carrier \
301 N:${rx:-U}:${tx:-U}:${rxerr:-U}:${txerr:-U}:${rxdrop:-U}:${txdrop:-U}:${rxov:-U}:${txov:-U}:${frame:-U}:${carrier:-U}
302 rsync=$(netproto tcp 873)
303 www=$(netproto tcp 80)
304 ssh=$(netproto tcp 22)
305 tcp=$(netproto tcp)
306 udp=$(netproto udp)
307 rrdtool update "$rrdlog/proto-$interface.rrd" \
308 -t tcp:udp:rsync:www:ssh \
309 N:${tcp:-U}:${udp:-U}:${rsync:-U}:${www:-U}:${ssh:-U}
310 }
312 getdisk()
313 {
314 local d
315 local i
316 d=$(stat -c %04D $1)
317 for i in /dev/* ; do
318 [ $(stat -c "%02t%02T" $i) == $d ] || continue
319 echo $i
320 break
321 done
322 }
324 ###
325 ### System graphs
326 ###
328 updatecpudata
329 updatecpugraph day
330 updatecpugraph week
331 updatecpugraph month
332 updatecpugraph year
334 updatememdata
335 updatememgraph day
336 updatememgraph week
337 updatememgraph month
338 updatememgraph year
340 if [ -e /proc/diskstats ]; then
341 disk=$(getdisk $0)
342 updatediskdata $disk
343 updatediskgraph day ${disk:0:8}
344 updatediskgraph week ${disk:0:8}
345 updatediskgraph month ${disk:0:8}
346 updatediskgraph year ${disk:0:8}
347 fi
349 iface=$(/sbin/route -n | awk '{ if (/^0.0.0.0/) print $8 }')
350 updateifdata $iface
351 updateifgraph $iface day
352 updateifgraph $iface week
353 updateifgraph $iface month
354 updateifgraph $iface year
356 [ ! -s $rrdgraph/boot.html -o /var/log/boot.log -nt $rrdgraph/boot.html ] &&
357 cat > $rrdgraph/boot.html <<EOT
358 <html>
359 <body>
360 <pre>
361 $(cat /var/log/dmesg.log /var/log/boot.log | \
362 sed -e 's/</\&lt;/g;s/>/\&gt;/g' -e 's/.*\]R//' -e 's/.*\[?8h//' \
363 -e 's|.\[1m|<b>|' -e 's|.\[0m|</b>|' -e 's|.\[[0-9][0-9Gm;]*||g' \
364 -e ':a;s/^\(.\{1,68\}\)\(\[ [A-Za-z]* \]\)/\1 \2/;ta' \
365 -e 's#\[ OK \]#[ <span style="color: green">OK</span> ]#' \
366 -e 's#\[ Failed \]#[ <span style="color: red">Failed</span> ]#' \
367 -e 's|No such .*|<span style="color: red">&</span>|' \
368 -e 's|ERROR .*|<span style="color: red">&</span>|' \
369 -e 's|command line: \(.*\)|command line: <span style="color: blue">\1</span>|' \
370 )
371 </pre>
372 </body>
373 </html>
374 EOT