slitaz-forge annotate pangolin/makegraphs @ rev 711

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